2017-05-23 15:36:59 +08:00
< ? php
2018-08-04 02:31:33 +08:00
function mailbox ( $_action , $_type , $_data = null , $_extra = null ) {
2018-07-12 04:13:43 +08:00
global $pdo ;
global $redis ;
global $lang ;
2018-10-03 17:28:25 +08:00
global $MAILBOX_DEFAULT_ATTRIBUTES ;
2018-08-04 02:31:33 +08:00
$_data_log = $_data ;
! isset ( $_data_log [ 'password' ]) ? : $_data_log [ 'password' ] = '*' ;
! isset ( $_data_log [ 'password2' ]) ? : $_data_log [ 'password2' ] = '*' ;
2017-05-23 15:36:59 +08:00
switch ( $_action ) {
case 'add' :
switch ( $_type ) {
case 'time_limited_alias' :
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'spam_alias' ]) || $_SESSION [ 'acl' ][ 'spam_alias' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( isset ( $_data [ 'username' ]) && filter_var ( $_data [ 'username' ], FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data [ 'username' ])) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
else {
$username = $_data [ 'username' ];
}
}
else {
$username = $_SESSION [ 'mailcow_cc_username' ];
}
2021-05-21 18:48:19 +08:00
if ( isset ( $_data [ " validity " ]) && ! filter_var ( $_data [ " validity " ], FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 87600 )))) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'validity_missing'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2021-05-21 18:48:19 +08:00
else {
// Default to 1 yr
$_data [ " validity " ] = 8760 ;
}
$domain = $_data [ 'domain' ];
$valid_domains [] = mailbox ( 'get' , 'mailbox_details' , $username )[ 'domain' ];
$valid_alias_domains = user_get_alias_details ( $username )[ 'alias_domains' ];
if ( ! empty ( $valid_alias_domains )) {
$valid_domains = array_merge ( $valid_domains , $valid_alias_domains );
}
if ( ! in_array ( $domain , $valid_domains )) {
2020-04-25 15:44:04 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
);
return false ;
}
2021-05-21 18:48:19 +08:00
$validity = strtotime ( " + " . $_data [ " validity " ] . " hour " );
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `spamalias` (`address`, `goto`, `validity`) VALUES
( : address , : goto , : validity ) " );
$stmt -> execute ( array (
2021-05-21 18:48:19 +08:00
':address' => readable_random_string ( rand ( rand ( 3 , 9 ), rand ( 3 , 9 ))) . '.' . readable_random_string ( rand ( rand ( 3 , 9 ), rand ( 3 , 9 ))) . '@' . $domain ,
2018-08-14 05:20:40 +08:00
':goto' => $username ,
':validity' => $validity
));
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'success' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2020-04-25 15:44:04 +08:00
'msg' => array ( 'mailbox_modified' , $username )
2017-05-23 15:36:59 +08:00
);
break ;
2020-03-19 19:23:48 +08:00
case 'global_filter' :
if ( $_SESSION [ 'mailcow_cc_role' ] != " admin " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
return false ;
}
$sieve = new Sieve\SieveParser ();
$script_data = $_data [ 'script_data' ];
$script_data = str_replace ( " \r \n " , " \n " , $script_data ); // windows -> unix
$script_data = str_replace ( " \r " , " \n " , $script_data ); // remaining -> unix
$filter_type = $_data [ 'filter_type' ];
try {
$sieve -> parse ( $script_data );
}
catch ( Exception $e ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'sieve_error' , $e -> getMessage ())
);
return false ;
}
if ( $filter_type == 'prefilter' ) {
try {
if ( file_exists ( '/global_sieve/before' )) {
$filter_handle = fopen ( '/global_sieve/before' , 'w' );
if ( ! $filter_handle ) {
throw new Exception ( $lang [ 'danger' ][ 'file_open_error' ]);
}
fwrite ( $filter_handle , $script_data );
fclose ( $filter_handle );
}
2020-04-13 01:26:32 +08:00
$restart_response = json_decode ( docker ( 'post' , 'dovecot-mailcow' , 'restart' ), true );
if ( $restart_response [ 'type' ] == " success " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'dovecot_restart_success'
);
}
else {
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'dovecot_restart_failed'
);
}
2020-03-19 19:23:48 +08:00
}
catch ( Exception $e ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_data_log ),
'msg' => array ( 'global_filter_write_error' , htmlspecialchars ( $e -> getMessage ()))
);
return false ;
}
}
elseif ( $filter_type == 'postfilter' ) {
try {
if ( file_exists ( '/global_sieve/after' )) {
$filter_handle = fopen ( '/global_sieve/after' , 'w' );
if ( ! $filter_handle ) {
throw new Exception ( $lang [ 'danger' ][ 'file_open_error' ]);
}
fwrite ( $filter_handle , $script_data );
fclose ( $filter_handle );
}
2020-04-13 01:26:32 +08:00
$restart_response = json_decode ( docker ( 'post' , 'dovecot-mailcow' , 'restart' ), true );
if ( $restart_response [ 'type' ] == " success " ) {
2020-04-12 03:44:53 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'dovecot_restart_success'
);
}
else {
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'dovecot_restart_failed'
);
}
2020-03-19 19:23:48 +08:00
}
catch ( Exception $e ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_data_log ),
'msg' => array ( 'global_filter_write_error' , htmlspecialchars ( $e -> getMessage ()))
);
return false ;
}
}
else {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'invalid_filter_type'
);
return false ;
}
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'global_filter_written'
);
return true ;
2017-11-04 03:37:24 +08:00
case 'filter' :
$sieve = new Sieve\SieveParser ();
if ( ! isset ( $_SESSION [ 'acl' ][ 'filters' ]) || $_SESSION [ 'acl' ][ 'filters' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-11-04 03:37:24 +08:00
);
return false ;
}
if ( isset ( $_data [ 'username' ]) && filter_var ( $_data [ 'username' ], FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data [ 'username' ])) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-11-04 03:37:24 +08:00
);
return false ;
}
else {
$username = $_data [ 'username' ];
}
}
elseif ( $_SESSION [ 'mailcow_cc_role' ] == " user " ) {
$username = $_SESSION [ 'mailcow_cc_username' ];
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'no_user_defined'
2017-11-04 03:37:24 +08:00
);
return false ;
}
$active = intval ( $_data [ 'active' ]);
$script_data = $_data [ 'script_data' ];
$script_desc = $_data [ 'script_desc' ];
$filter_type = $_data [ 'filter_type' ];
if ( empty ( $script_data )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'script_empty'
2017-11-04 03:37:24 +08:00
);
return false ;
}
try {
$sieve -> parse ( $script_data );
}
catch ( Exception $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'sieve_error' , $e -> getMessage ())
2017-11-04 03:37:24 +08:00
);
return false ;
}
if ( empty ( $script_data ) || empty ( $script_desc )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'value_missing'
2017-11-04 03:37:24 +08:00
);
return false ;
}
if ( $filter_type != 'postfilter' && $filter_type != 'prefilter' ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'filter_type'
2017-11-04 03:37:24 +08:00
);
return false ;
}
if ( ! empty ( $active )) {
$script_name = 'active' ;
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `sieve_filters` SET `script_name` = 'inactive' WHERE `username` = :username AND `filter_type` = :filter_type " );
2017-11-04 03:37:24 +08:00
$stmt -> execute ( array (
':username' => $username ,
':filter_type' => $filter_type
));
}
2018-08-14 05:20:40 +08:00
else {
$script_name = 'inactive' ;
2017-11-04 03:37:24 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `sieve_filters` (`username`, `script_data`, `script_desc`, `script_name`, `filter_type`)
VALUES ( : username , : script_data , : script_desc , : script_name , : filter_type ) " );
$stmt -> execute ( array (
':username' => $username ,
':script_data' => $script_data ,
':script_desc' => $script_desc ,
':script_name' => $script_name ,
':filter_type' => $filter_type
));
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'success' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
2017-11-04 03:37:24 +08:00
);
break ;
2017-05-23 15:36:59 +08:00
case 'syncjob' :
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'syncjobs' ]) || $_SESSION [ 'acl' ][ 'syncjobs' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( isset ( $_data [ 'username' ]) && filter_var ( $_data [ 'username' ], FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data [ 'username' ])) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
else {
$username = $_data [ 'username' ];
}
}
2017-07-29 16:32:17 +08:00
elseif ( $_SESSION [ 'mailcow_cc_role' ] == " user " ) {
2017-05-23 15:36:59 +08:00
$username = $_SESSION [ 'mailcow_cc_username' ];
}
2017-07-29 16:32:17 +08:00
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-07-29 16:32:17 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'no_user_defined'
2017-07-29 16:32:17 +08:00
);
return false ;
}
2018-07-28 04:19:59 +08:00
$active = intval ( $_data [ 'active' ]);
$subscribeall = intval ( $_data [ 'subscribeall' ]);
2018-01-24 19:59:04 +08:00
$delete2duplicates = intval ( $_data [ 'delete2duplicates' ]);
$delete1 = intval ( $_data [ 'delete1' ]);
$delete2 = intval ( $_data [ 'delete2' ]);
2018-07-28 04:19:59 +08:00
$timeout1 = intval ( $_data [ 'timeout1' ]);
$timeout2 = intval ( $_data [ 'timeout2' ]);
2018-01-24 19:59:04 +08:00
$skipcrossduplicates = intval ( $_data [ 'skipcrossduplicates' ]);
$automap = intval ( $_data [ 'automap' ]);
$port1 = $_data [ 'port1' ];
$host1 = strtolower ( $_data [ 'host1' ]);
$password1 = $_data [ 'password1' ];
$exclude = $_data [ 'exclude' ];
$maxage = $_data [ 'maxage' ];
$maxbytespersecond = $_data [ 'maxbytespersecond' ];
$subfolder2 = $_data [ 'subfolder2' ];
$user1 = $_data [ 'user1' ];
$mins_interval = $_data [ 'mins_interval' ];
2018-07-28 04:19:59 +08:00
$enc1 = $_data [ 'enc1' ];
$custom_params = ( empty ( trim ( $_data [ 'custom_params' ]))) ? '' : trim ( $_data [ 'custom_params' ]);
2020-11-06 21:26:48 +08:00
// Workaround, fixme
if ( strpos ( $custom_params , 'pipemess' )) {
$custom_params = '' ;
}
2017-05-23 15:36:59 +08:00
if ( empty ( $subfolder2 )) {
$subfolder2 = " " ;
}
2018-07-28 04:19:59 +08:00
if ( ! isset ( $maxage ) || ! filter_var ( $maxage , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 32000 )))) {
2017-05-23 15:36:59 +08:00
$maxage = " 0 " ;
}
2018-07-28 04:19:59 +08:00
if ( ! isset ( $timeout1 ) || ! filter_var ( $timeout1 , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 32000 )))) {
$timeout1 = " 600 " ;
}
if ( ! isset ( $timeout2 ) || ! filter_var ( $timeout2 , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 32000 )))) {
$timeout2 = " 600 " ;
}
2018-01-24 19:59:04 +08:00
if ( ! isset ( $maxbytespersecond ) || ! filter_var ( $maxbytespersecond , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 125000000 )))) {
$maxbytespersecond = " 0 " ;
}
2017-05-23 15:36:59 +08:00
if ( ! filter_var ( $port1 , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 65535 )))) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2020-07-09 01:36:05 +08:00
if ( ! filter_var ( $mins_interval , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 43800 )))) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2019-09-21 16:44:08 +08:00
// if (!is_valid_domain_name($host1)) {
// $_SESSION['return'][] = array(
// 'type' => 'danger',
// 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
// 'msg' => 'access_denied'
// );
// return false;
// }
2017-05-23 15:36:59 +08:00
if ( $enc1 != " TLS " && $enc1 != " SSL " && $enc1 != " PLAIN " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( @ preg_match ( " / " . $exclude . " / " , null ) === false ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT '1' FROM `imapsync`
WHERE `user2` = : user2 AND `user1` = : user1 AND `host1` = : host1 " );
$stmt -> execute ( array ( ':user1' => $user1 , ':user2' => $username , ':host1' => $host1 ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
2017-05-23 15:36:59 +08:00
if ( $num_results != 0 ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'object_exists' , htmlspecialchars ( $host1 . ' / ' . $user1 ))
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `imapsync` (`user2`, `exclude`, `delete1`, `delete2`, `timeout1`, `timeout2`, `automap`, `skipcrossduplicates`, `maxbytespersecond`, `subscribeall`, `maxage`, `subfolder2`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `custom_params`, `active`)
VALUES ( : user2 , : exclude , : delete1 , : delete2 , : timeout1 , : timeout2 , : automap , : skipcrossduplicates , : maxbytespersecond , : subscribeall , : maxage , : subfolder2 , : host1 , : authmech1 , : user1 , : password1 , : mins_interval , : port1 , : enc1 , : delete2duplicates , : custom_params , : active ) " );
$stmt -> execute ( array (
':user2' => $username ,
':custom_params' => $custom_params ,
':exclude' => $exclude ,
':maxage' => $maxage ,
':delete1' => $delete1 ,
':delete2' => $delete2 ,
':timeout1' => $timeout1 ,
':timeout2' => $timeout2 ,
':automap' => $automap ,
':skipcrossduplicates' => $skipcrossduplicates ,
':maxbytespersecond' => $maxbytespersecond ,
':subscribeall' => $subscribeall ,
':subfolder2' => $subfolder2 ,
':host1' => $host1 ,
':authmech1' => 'PLAIN' ,
':user1' => $user1 ,
':password1' => $password1 ,
':mins_interval' => $mins_interval ,
':port1' => $port1 ,
':enc1' => $enc1 ,
':delete2duplicates' => $delete2duplicates ,
':active' => $active ,
));
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'success' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
2017-05-23 15:36:59 +08:00
);
break ;
case 'domain' :
if ( $_SESSION [ 'mailcow_cc_role' ] != " admin " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2019-02-05 07:10:21 +08:00
$domain = idn_to_ascii ( strtolower ( trim ( $_data [ 'domain' ])), 0 , INTL_IDNA_VARIANT_UTS46 );
2017-05-23 15:36:59 +08:00
$description = $_data [ 'description' ];
2021-02-12 17:04:19 +08:00
$xmpp_prefix = preg_replace ( '/[^\da-z-]/i' , '' , $_data [ 'xmpp_prefix' ]);
2020-02-21 15:59:50 +08:00
if ( empty ( $description )) {
$description = $domain ;
}
2021-03-01 17:21:26 +08:00
$aliases = ( int ) $_data [ 'aliases' ];
$mailboxes = ( int ) $_data [ 'mailboxes' ];
$defquota = ( int ) $_data [ 'defquota' ];
$maxquota = ( int ) $_data [ 'maxquota' ];
$restart_sogo = ( int ) $_data [ 'restart_sogo' ];
$quota = ( int ) $_data [ 'quota' ];
2019-05-11 17:16:40 +08:00
if ( $defquota > $maxquota ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'mailbox_defquota_exceeds_mailbox_maxquota'
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( $maxquota > $quota ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'mailbox_quota_exceeds_domain_quota'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2019-05-11 17:16:40 +08:00
if ( $defquota == " 0 " || empty ( $defquota )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'defquota_empty'
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( $maxquota == " 0 " || empty ( $maxquota )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'maxquota_empty'
2017-05-23 15:36:59 +08:00
);
return false ;
}
$active = intval ( $_data [ 'active' ]);
$relay_all_recipients = intval ( $_data [ 'relay_all_recipients' ]);
2020-04-04 02:39:53 +08:00
$relay_unknown_only = intval ( $_data [ 'relay_unknown_only' ]);
2017-05-23 15:36:59 +08:00
$backupmx = intval ( $_data [ 'backupmx' ]);
2019-01-17 06:41:02 +08:00
$gal = intval ( $_data [ 'gal' ]);
2021-02-11 16:34:21 +08:00
$xmpp = intval ( $_data [ 'xmpp' ]);
2020-04-04 02:39:53 +08:00
if ( $relay_all_recipients == 1 ) {
$backupmx = '1' ;
}
if ( $relay_unknown_only == 1 ) {
$backupmx = 1 ;
$relay_all_recipients = 1 ;
}
2017-05-23 15:36:59 +08:00
if ( ! is_valid_domain_name ( $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
foreach ( array ( $quota , $maxquota , $mailboxes , $aliases ) as $data ) {
if ( ! is_numeric ( $data )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'object_is_not_numeric' , htmlspecialchars ( $data ))
2017-05-23 15:36:59 +08:00
);
return false ;
}
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain`
WHERE `domain` = : domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
$stmt = $pdo -> prepare ( " SELECT `alias_domain` FROM `alias_domain`
WHERE `alias_domain` = : domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$num_results = $num_results + count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
2017-05-23 15:36:59 +08:00
if ( $num_results != 0 ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_exists' , htmlspecialchars ( $domain ))
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-07-29 06:38:22 +08:00
if ( $domain == getenv ( 'MAILCOW_HOSTNAME' )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2018-05-04 04:42:31 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_cannot_match_hostname'
2018-05-04 04:42:31 +08:00
);
return false ;
}
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `external` = 1 AND `send_as` LIKE :domain " );
$stmt -> execute ( array (
':domain' => '%@' . $domain
));
2021-02-11 16:34:21 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `defquota`, `maxquota`, `quota`, `backupmx`, `gal`, `xmpp`, `xmpp_prefix`, `active`, `relay_unknown_only`, `relay_all_recipients`)
VALUES ( : domain , : description , : aliases , : mailboxes , : defquota , : maxquota , : quota , : backupmx , : gal , : xmpp , : xmpp_prefix , : active , : relay_unknown_only , : relay_all_recipients ) " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':domain' => $domain ,
':description' => $description ,
':aliases' => $aliases ,
':mailboxes' => $mailboxes ,
2019-05-11 17:16:40 +08:00
':defquota' => $defquota ,
2018-08-14 05:20:40 +08:00
':maxquota' => $maxquota ,
':quota' => $quota ,
':backupmx' => $backupmx ,
2019-01-17 06:41:02 +08:00
':gal' => $gal ,
2021-02-11 16:34:21 +08:00
':xmpp' => $xmpp ,
':xmpp_prefix' => $xmpp_prefix ,
2018-08-14 05:20:40 +08:00
':active' => $active ,
2020-04-04 02:39:53 +08:00
':relay_unknown_only' => $relay_unknown_only ,
2018-08-14 05:20:40 +08:00
':relay_all_recipients' => $relay_all_recipients
));
2017-05-23 15:36:59 +08:00
try {
2018-08-14 05:20:40 +08:00
$redis -> hSet ( 'DOMAIN_MAP' , $domain , 1 );
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
catch ( RedisException $e ) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'redis_error' , $e )
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-08-22 03:06:22 +08:00
if ( ! empty ( intval ( $_data [ 'rl_value' ]))) {
2018-08-22 03:23:06 +08:00
ratelimit ( 'edit' , 'domain' , array ( 'rl_value' => $_data [ 'rl_value' ], 'rl_frame' => $_data [ 'rl_frame' ], 'object' => $domain ));
2018-08-22 03:06:22 +08:00
}
2018-08-14 05:20:40 +08:00
if ( ! empty ( $restart_sogo )) {
2020-04-13 01:26:32 +08:00
$restart_response = json_decode ( docker ( 'post' , 'sogo-mailcow' , 'restart' ), true );
if ( $restart_response [ 'type' ] == " success " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_added' , htmlspecialchars ( $domain ))
);
return true ;
}
else {
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_added_sogo_failed'
);
return false ;
}
}
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_added' , htmlspecialchars ( $domain ))
);
return true ;
2017-05-23 15:36:59 +08:00
break ;
case 'alias' :
$addresses = array_map ( 'trim' , preg_split ( " /( |,|;| \n )/ " , $_data [ 'address' ]));
$gotos = array_map ( 'trim' , preg_split ( " /( |,|;| \n )/ " , $_data [ 'goto' ]));
$active = intval ( $_data [ 'active' ]);
2019-09-22 21:10:56 +08:00
$sogo_visible = intval ( $_data [ 'sogo_visible' ]);
2017-09-16 19:17:37 +08:00
$goto_null = intval ( $_data [ 'goto_null' ]);
2018-07-29 06:38:22 +08:00
$goto_spam = intval ( $_data [ 'goto_spam' ]);
$goto_ham = intval ( $_data [ 'goto_ham' ]);
2019-01-29 07:20:39 +08:00
$private_comment = $_data [ 'private_comment' ];
$public_comment = $_data [ 'public_comment' ];
if ( strlen ( $private_comment ) > 160 | strlen ( $public_comment ) > 160 ){
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'comment_too_long'
);
return false ;
2019-11-11 16:55:15 +08:00
}
2017-05-23 15:36:59 +08:00
if ( empty ( $addresses [ 0 ])) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'alias_empty'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-07-30 05:04:54 +08:00
if ( empty ( $gotos [ 0 ]) && ( $goto_null + $goto_spam + $goto_ham == 0 )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'goto_empty'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2017-09-16 19:17:37 +08:00
if ( $goto_null == " 1 " ) {
$goto = " null@localhost " ;
}
2018-07-29 06:38:22 +08:00
elseif ( $goto_spam == " 1 " ) {
$goto = " spam@localhost " ;
}
elseif ( $goto_ham == " 1 " ) {
$goto = " ham@localhost " ;
}
2017-09-16 19:17:37 +08:00
else {
2018-08-14 05:20:40 +08:00
foreach ( $gotos as $i => & $goto ) {
2017-09-16 19:17:37 +08:00
if ( empty ( $goto )) {
continue ;
}
2019-02-05 07:10:21 +08:00
$goto_domain = idn_to_ascii ( substr ( strstr ( $goto , '@' ), 1 ), 0 , INTL_IDNA_VARIANT_UTS46 );
2017-09-16 19:17:37 +08:00
$goto_local_part = strstr ( $goto , '@' , true );
$goto = $goto_local_part . '@' . $goto_domain ;
$stmt = $pdo -> prepare ( " SELECT `username` FROM `mailbox`
WHERE `kind` REGEXP 'location|thing|group'
AND `username` = : goto " );
$stmt -> execute ( array ( ':goto' => $goto ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-09-16 19:17:37 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'goto_invalid' , htmlspecialchars ( $goto ))
2017-09-16 19:17:37 +08:00
);
2018-08-14 05:20:40 +08:00
unset ( $gotos [ $i ]);
continue ;
2017-09-16 19:17:37 +08:00
}
if ( ! filter_var ( $goto , FILTER_VALIDATE_EMAIL ) === true ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-09-16 19:17:37 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'goto_invalid' , htmlspecialchars ( $goto ))
2017-09-16 19:17:37 +08:00
);
2018-08-14 05:20:40 +08:00
unset ( $gotos [ $i ]);
continue ;
2017-09-16 19:17:37 +08:00
}
2017-06-22 05:27:01 +08:00
}
2021-05-23 19:18:52 +08:00
$gotos = array_unique ( $gotos );
2017-09-16 19:17:37 +08:00
$gotos = array_filter ( $gotos );
2018-08-14 05:20:40 +08:00
if ( empty ( $gotos )) { return false ; }
2017-09-16 19:17:37 +08:00
$goto = implode ( " , " , $gotos );
2017-06-22 05:27:01 +08:00
}
2017-05-23 15:36:59 +08:00
foreach ( $addresses as $address ) {
if ( empty ( $address )) {
continue ;
}
2017-06-22 05:27:01 +08:00
if ( in_array ( $address , $gotos )) {
continue ;
}
2019-02-05 07:10:21 +08:00
$domain = idn_to_ascii ( substr ( strstr ( $address , '@' ), 1 ), 0 , INTL_IDNA_VARIANT_UTS46 );
2018-02-17 16:50:58 +08:00
$local_part = strstr ( $address , '@' , true );
2017-12-09 20:17:15 +08:00
$address = $local_part . '@' . $domain ;
2018-08-14 05:20:40 +08:00
$domaindata = mailbox ( 'get' , 'domain_details' , $domain );
if ( is_array ( $domaindata ) && $domaindata [ 'aliases_left' ] == " 0 " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'max_alias_exceeded'
);
return false ;
}
2017-05-23 15:36:59 +08:00
$stmt = $pdo -> prepare ( " SELECT `address` FROM `alias`
2017-12-09 20:17:15 +08:00
WHERE `address` = : address OR `address` IN (
SELECT `username` FROM `mailbox` , `alias_domain`
WHERE (
`alias_domain` . `alias_domain` = : address_d
AND `mailbox` . `username` = CONCAT ( : address_l , '@' , alias_domain . target_domain ))) " );
$stmt -> execute ( array (
':address' => $address ,
':address_l' => $local_part ,
':address_d' => $domain
));
2017-05-23 15:36:59 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'is_alias_or_mailbox' , htmlspecialchars ( $address ))
2017-05-23 15:36:59 +08:00
);
2019-03-14 08:46:15 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain`
WHERE `domain` = : domain1 OR `domain` = ( SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = : domain2 ) " );
$stmt -> execute ( array ( ':domain1' => $domain , ':domain2' => $domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'domain_not_found' , htmlspecialchars ( $domain ))
2017-05-23 15:36:59 +08:00
);
2019-03-14 08:46:15 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `address` FROM `spamalias`
WHERE `address` = : address " );
$stmt -> execute ( array ( ':address' => $address ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'is_spam_alias' , htmlspecialchars ( $address ))
2017-05-23 15:36:59 +08:00
);
2019-03-14 08:46:15 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if (( ! filter_var ( $address , FILTER_VALIDATE_EMAIL ) === true ) && ! empty ( $local_part )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2019-12-23 21:46:57 +08:00
'msg' => array ( 'alias_invalid' , $address )
2017-05-23 15:36:59 +08:00
);
2019-03-14 08:46:15 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2019-03-14 08:46:15 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2019-09-22 21:10:56 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `alias` (`address`, `public_comment`, `private_comment`, `goto`, `domain`, `sogo_visible`, `active`)
VALUES ( : address , : public_comment , : private_comment , : goto , : domain , : sogo_visible , : active ) " );
2018-08-14 05:20:40 +08:00
if ( ! filter_var ( $address , FILTER_VALIDATE_EMAIL ) === true ) {
$stmt -> execute ( array (
2019-01-29 07:20:39 +08:00
':address' => '@' . $domain ,
':public_comment' => $public_comment ,
':private_comment' => $private_comment ,
2018-08-14 05:20:40 +08:00
':address' => '@' . $domain ,
':goto' => $goto ,
':domain' => $domain ,
2019-09-22 21:10:56 +08:00
':sogo_visible' => $sogo_visible ,
2018-08-14 05:20:40 +08:00
':active' => $active
));
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
else {
$stmt -> execute ( array (
':address' => $address ,
2019-01-29 07:20:39 +08:00
':public_comment' => $public_comment ,
':private_comment' => $private_comment ,
2018-08-14 05:20:40 +08:00
':goto' => $goto ,
':domain' => $domain ,
2019-09-22 21:10:56 +08:00
':sogo_visible' => $sogo_visible ,
2018-08-14 05:20:40 +08:00
':active' => $active
));
2017-05-23 15:36:59 +08:00
}
2020-05-25 22:20:59 +08:00
$id = $pdo -> lastInsertId ();
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2020-05-25 22:20:59 +08:00
'msg' => array ( 'alias_added' , $address , $id )
2018-08-14 05:20:40 +08:00
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'alias_domain' :
$active = intval ( $_data [ 'active' ]);
2017-06-13 02:21:31 +08:00
$alias_domains = array_map ( 'trim' , preg_split ( " /( |,|;| \n )/ " , $_data [ 'alias_domain' ]));
2018-08-14 05:20:40 +08:00
$alias_domains = array_filter ( $alias_domains );
2019-02-05 07:10:21 +08:00
$target_domain = idn_to_ascii ( strtolower ( trim ( $_data [ 'target_domain' ])), 0 , INTL_IDNA_VARIANT_UTS46 );
2018-11-14 15:20:56 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'alias_domains' ]) || $_SESSION [ 'acl' ][ 'alias_domains' ] != " 1 " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( ! is_valid_domain_name ( $target_domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'target_domain_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $target_domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-08-23 14:49:02 +08:00
foreach ( $alias_domains as $i => $alias_domain ) {
2019-02-05 07:10:21 +08:00
$alias_domain = idn_to_ascii ( strtolower ( trim ( $alias_domain )), 0 , INTL_IDNA_VARIANT_UTS46 );
2017-06-13 02:21:31 +08:00
if ( ! is_valid_domain_name ( $alias_domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'alias_domain_invalid' , htmlspecialchars ( alias_domain ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2017-06-13 02:21:31 +08:00
if ( $alias_domain == $target_domain ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-06-13 02:21:31 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'aliasd_targetd_identical' , htmlspecialchars ( $target_domain ))
2017-06-13 02:21:31 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-06-13 02:21:31 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain`
WHERE `domain` = : target_domain " );
$stmt -> execute ( array ( ':target_domain' => $target_domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
$_SESSION [ 'return' ][] = array (
2017-06-13 02:21:31 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'targetd_not_found' , htmlspecialchars ( $target_domain ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2018-01-17 22:23:33 +08:00
}
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain`
WHERE `domain` = : target_domain AND `backupmx` = '1' " );
$stmt -> execute ( array ( ':target_domain' => $target_domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
2019-09-05 16:54:35 +08:00
if ( $num_results == 1 ) {
2019-09-02 17:11:41 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'targetd_relay_domain' , htmlspecialchars ( $target_domain ))
);
continue ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain
UNION
SELECT `domain` FROM `domain` WHERE `domain` = : alias_domain_in_domain " );
$stmt -> execute ( array ( ':alias_domain' => $alias_domain , ':alias_domain_in_domain' => $alias_domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
2018-01-17 22:23:33 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'alias_domain_invalid' , $alias_domain )
2018-01-17 22:23:33 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2018-01-17 22:23:33 +08:00
}
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `external` = 1 AND `send_as` LIKE :domain " );
$stmt -> execute ( array (
':domain' => '%@' . $domain
));
2018-08-23 14:49:02 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `active`)
VALUES ( : alias_domain , : target_domain , : active ) " );
$stmt -> execute ( array (
':alias_domain' => $alias_domain ,
':target_domain' => $target_domain ,
':active' => $active
));
try {
$redis -> hSet ( 'DOMAIN_MAP' , $alias_domain , 1 );
}
catch ( RedisException $e ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
);
return false ;
}
2018-11-14 15:20:56 +08:00
if ( ! empty ( intval ( $_data [ 'rl_value' ]))) {
ratelimit ( 'edit' , 'domain' , array ( 'rl_value' => $_data [ 'rl_value' ], 'rl_frame' => $_data [ 'rl_frame' ], 'object' => $alias_domain ));
}
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2018-08-23 14:49:02 +08:00
'type' => 'success' ,
2018-08-14 05:20:40 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-23 14:49:02 +08:00
'msg' => array ( 'aliasd_added' , htmlspecialchars ( $alias_domain ))
2018-08-14 05:20:40 +08:00
);
}
2017-05-23 15:36:59 +08:00
break ;
case 'mailbox' :
$local_part = strtolower ( trim ( $_data [ 'local_part' ]));
2019-02-05 07:10:21 +08:00
$domain = idn_to_ascii ( strtolower ( trim ( $_data [ 'domain' ])), 0 , INTL_IDNA_VARIANT_UTS46 );
2017-05-23 15:36:59 +08:00
$username = $local_part . '@' . $domain ;
if ( ! filter_var ( $username , FILTER_VALIDATE_EMAIL )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'mailbox_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( empty ( $_data [ 'local_part' ])) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'mailbox_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
$password = $_data [ 'password' ];
$password2 = $_data [ 'password2' ];
2019-02-26 16:23:16 +08:00
$name = ltrim ( rtrim ( $_data [ 'name' ], '>' ), '<' );
2019-03-29 05:05:12 +08:00
$quota_m = intval ( $_data [ 'quota' ]);
2019-07-29 22:16:31 +08:00
if (( ! isset ( $_SESSION [ 'acl' ][ 'unlimited_quota' ]) || $_SESSION [ 'acl' ][ 'unlimited_quota' ] != " 1 " ) && $quota_m === 0 ) {
2019-03-31 02:14:24 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'unlimited_quota_acl'
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( empty ( $name )) {
$name = $local_part ;
}
$active = intval ( $_data [ 'active' ]);
2020-08-23 04:59:13 +08:00
$force_pw_update = ( isset ( $_data [ 'force_pw_update' ])) ? intval ( $_data [ 'force_pw_update' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'force_pw_update' ]);
$tls_enforce_in = ( isset ( $_data [ 'tls_enforce_in' ])) ? intval ( $_data [ 'tls_enforce_in' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'tls_enforce_in' ]);
$tls_enforce_out = ( isset ( $_data [ 'tls_enforce_out' ])) ? intval ( $_data [ 'tls_enforce_out' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'tls_enforce_out' ]);
$sogo_access = ( isset ( $_data [ 'sogo_access' ])) ? intval ( $_data [ 'sogo_access' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'sogo_access' ]);
2020-09-18 01:49:15 +08:00
$imap_access = ( isset ( $_data [ 'imap_access' ])) ? intval ( $_data [ 'imap_access' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'imap_access' ]);
$pop3_access = ( isset ( $_data [ 'pop3_access' ])) ? intval ( $_data [ 'pop3_access' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'pop3_access' ]);
$smtp_access = ( isset ( $_data [ 'smtp_access' ])) ? intval ( $_data [ 'smtp_access' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'smtp_access' ]);
2021-02-11 16:34:21 +08:00
$xmpp_access = ( isset ( $_data [ 'xmpp_access' ])) ? intval ( $_data [ 'xmpp_access' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'xmpp_access' ]);
$xmpp_admin = ( isset ( $_data [ 'xmpp_admin' ])) ? intval ( $_data [ 'xmpp_admin' ]) : intval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'xmpp_admin' ]);
2020-08-23 04:59:13 +08:00
$quarantine_notification = ( isset ( $_data [ 'quarantine_notification' ])) ? strval ( $_data [ 'quarantine_notification' ]) : strval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'quarantine_notification' ]);
2020-11-29 00:41:48 +08:00
$quarantine_category = ( isset ( $_data [ 'quarantine_category' ])) ? strval ( $_data [ 'quarantine_category' ]) : strval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'quarantine_category' ]);
2019-10-05 23:34:25 +08:00
$quota_b = ( $quota_m * 1048576 );
2018-10-03 17:28:25 +08:00
$mailbox_attrs = json_encode (
array (
2020-08-23 04:59:13 +08:00
'force_pw_update' => strval ( $force_pw_update ),
'tls_enforce_in' => strval ( $tls_enforce_in ),
'tls_enforce_out' => strval ( $tls_enforce_out ),
'sogo_access' => strval ( $sogo_access ),
2020-09-18 01:49:15 +08:00
'imap_access' => strval ( $imap_access ),
'pop3_access' => strval ( $pop3_access ),
'smtp_access' => strval ( $smtp_access ),
2021-02-11 16:34:21 +08:00
'xmpp_access' => strval ( $xmpp_access ),
'xmpp_admin' => strval ( $xmpp_admin ),
2019-01-29 07:20:39 +08:00
'mailbox_format' => strval ( $MAILBOX_DEFAULT_ATTRIBUTES [ 'mailbox_format' ]),
2020-11-29 00:41:48 +08:00
'quarantine_notification' => strval ( $quarantine_notification ),
'quarantine_category' => strval ( $quarantine_category )
2018-10-24 03:14:57 +08:00
)
);
2017-05-23 15:36:59 +08:00
if ( ! is_valid_domain_name ( $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `mailboxes`, `maxquota`, `quota` FROM `domain`
WHERE `domain` = : domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$DomainData = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " SELECT
2018-08-14 05:20:40 +08:00
COUNT ( * ) as count ,
COALESCE ( ROUND ( SUM ( `quota` ) / 1048576 ), 0 ) as `quota`
FROM `mailbox`
2021-03-19 23:33:50 +08:00
WHERE ( `kind` = '' OR `kind` = NULL )
2018-08-14 05:20:40 +08:00
AND `domain` = : domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$MailboxData = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$stmt = $pdo -> prepare ( " SELECT `local_part` FROM `mailbox` WHERE `local_part` = :local_part and `domain`= :domain " );
$stmt -> execute ( array ( ':local_part' => $local_part , ':domain' => $domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'object_exists' , htmlspecialchars ( $username ))
);
return false ;
}
$stmt = $pdo -> prepare ( " SELECT `address` FROM `alias` WHERE address= :username " );
$stmt -> execute ( array ( ':username' => $username ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'is_alias' , htmlspecialchars ( $username ))
);
return false ;
}
$stmt = $pdo -> prepare ( " SELECT `address` FROM `spamalias` WHERE `address`= :username " );
$stmt -> execute ( array ( ':username' => $username ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'is_spam_alias' , htmlspecialchars ( $username ))
);
return false ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain` WHERE `domain`= :domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'domain_not_found' , htmlspecialchars ( $domain ))
2017-05-23 15:36:59 +08:00
);
return false ;
}
2021-04-09 19:46:17 +08:00
if ( password_check ( $password , $password2 ) !== true ) {
return false ;
}
// support pre hashed passwords
if ( preg_match ( '/^{(ARGON2I|ARGON2ID|BLF-CRYPT|CLEAR|CLEARTEXT|CRYPT|DES-CRYPT|LDAP-MD5|MD5|MD5-CRYPT|PBKDF2|PLAIN|PLAIN-MD4|PLAIN-MD5|PLAIN-TRUNC|PLAIN-TRUNC|SHA|SHA1|SHA256|SHA256-CRYPT|SHA512|SHA512-CRYPT|SMD5|SSHA|SSHA256|SSHA512)}/i' , $password )) {
$password_hashed = $password ;
2017-05-23 15:36:59 +08:00
}
else {
2021-04-09 19:46:17 +08:00
$password_hashed = hash_password ( $password );
2017-05-23 15:36:59 +08:00
}
if ( $MailboxData [ 'count' ] >= $DomainData [ 'mailboxes' ]) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'max_mailbox_exceeded' , $MailboxData [ 'count' ], $DomainData [ 'mailboxes' ])
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( $quota_m > $DomainData [ 'maxquota' ]) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_quota_exceeded' , $DomainData [ 'maxquota' ])
2017-05-23 15:36:59 +08:00
);
return false ;
}
if (( $MailboxData [ 'quota' ] + $quota_m ) > $DomainData [ 'quota' ]) {
$quota_left_m = ( $DomainData [ 'quota' ] - $MailboxData [ 'quota' ]);
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_quota_left_exceeded' , $quota_left_m )
2017-05-23 15:36:59 +08:00
);
return false ;
}
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `mailbox` (`username`, `password`, `name`, `quota`, `local_part`, `domain`, `attributes`, `active`)
2018-11-12 17:03:50 +08:00
VALUES ( : username , : password_hashed , : name , : quota_b , : local_part , : domain , : mailbox_attrs , : active ) " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':username' => $username ,
':password_hashed' => $password_hashed ,
':name' => $name ,
':quota_b' => $quota_b ,
':local_part' => $local_part ,
':domain' => $domain ,
2018-10-03 17:28:25 +08:00
':mailbox_attrs' => $mailbox_attrs ,
2018-08-14 05:20:40 +08:00
':active' => $active
));
$stmt = $pdo -> prepare ( " INSERT INTO `quota2` (`username`, `bytes`, `messages`)
VALUES ( : username , '0' , '0' ) ON DUPLICATE KEY UPDATE `bytes` = '0' , `messages` = '0' ; " );
$stmt -> execute ( array ( ':username' => $username ));
2020-02-05 18:04:14 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `quota2replica` (`username`, `bytes`, `messages`)
VALUES ( : username , '0' , '0' ) ON DUPLICATE KEY UPDATE `bytes` = '0' , `messages` = '0' ; " );
$stmt -> execute ( array ( ':username' => $username ));
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
VALUES ( : username1 , : username2 , : domain , : active ) " );
$stmt -> execute ( array (
':username1' => $username ,
':username2' => $username ,
':domain' => $domain ,
':active' => $active
));
$stmt = $pdo -> prepare ( " INSERT INTO `user_acl` (`username`) VALUES (:username) " );
$stmt -> execute ( array (
':username' => $username
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_added' , htmlspecialchars ( $username ))
);
2017-05-23 15:36:59 +08:00
break ;
case 'resource' :
2019-02-05 07:10:21 +08:00
$domain = idn_to_ascii ( strtolower ( trim ( $_data [ 'domain' ])), 0 , INTL_IDNA_VARIANT_UTS46 );
2017-05-23 15:36:59 +08:00
$description = $_data [ 'description' ];
$local_part = preg_replace ( '/[^\da-z]/i' , '' , preg_quote ( $description , '/' ));
$name = $local_part . '@' . $domain ;
$kind = $_data [ 'kind' ];
2018-05-07 03:51:00 +08:00
$multiple_bookings = intval ( $_data [ 'multiple_bookings' ]);
2017-05-23 15:36:59 +08:00
$active = intval ( $_data [ 'active' ]);
if ( ! filter_var ( $name , FILTER_VALIDATE_EMAIL )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'resource_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( empty ( $description )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'description_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-05-07 03:51:00 +08:00
if ( ! isset ( $multiple_bookings ) || $multiple_bookings < - 1 ) {
$multiple_bookings = - 1 ;
}
2017-05-23 15:36:59 +08:00
if ( $kind != 'location' && $kind != 'group' && $kind != 'thing' ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'resource_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( ! is_valid_domain_name ( $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
2017-05-23 15:36:59 +08:00
);
return false ;
}
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `username` FROM `mailbox` WHERE `username` = :name " );
$stmt -> execute ( array ( ':name' => $name ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'object_exists' , htmlspecialchars ( $name ))
);
return false ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `address` FROM `alias` WHERE address= :name " );
$stmt -> execute ( array ( ':name' => $name ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'is_alias' , htmlspecialchars ( $name ))
2017-05-23 15:36:59 +08:00
);
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `address` FROM `spamalias` WHERE `address`= :name " );
$stmt -> execute ( array ( ':name' => $name ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'is_spam_alias' , htmlspecialchars ( $name ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
return false ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain` WHERE `domain`= :domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'domain_not_found' , htmlspecialchars ( $domain ))
2017-05-23 15:36:59 +08:00
);
return false ;
}
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `mailbox` (`username`, `password`, `name`, `quota`, `local_part`, `domain`, `active`, `multiple_bookings`, `kind`)
2018-11-12 17:03:50 +08:00
VALUES ( : name , 'RESOURCE' , : description , 0 , : local_part , : domain , : active , : multiple_bookings , : kind ) " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':name' => $name ,
':description' => $description ,
':local_part' => $local_part ,
':domain' => $domain ,
':active' => $active ,
':kind' => $kind ,
':multiple_bookings' => $multiple_bookings
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'resource_added' , htmlspecialchars ( $name ))
);
2017-05-23 15:36:59 +08:00
break ;
}
break ;
case 'edit' :
switch ( $_type ) {
case 'alias_domain' :
2017-05-27 05:02:04 +08:00
$alias_domains = ( array ) $_data [ 'alias_domain' ];
2017-05-23 15:36:59 +08:00
foreach ( $alias_domains as $alias_domain ) {
2019-02-05 07:10:21 +08:00
$alias_domain = idn_to_ascii ( strtolower ( trim ( $alias_domain )), 0 , INTL_IDNA_VARIANT_UTS46 );
2017-05-23 15:36:59 +08:00
$is_now = mailbox ( 'get' , 'alias_domain_details' , $alias_domain );
if ( ! empty ( $is_now )) {
2020-09-18 01:49:15 +08:00
$active = ( isset ( $_data [ 'active' ])) ? intval ( $_data [ 'active' ]) : $is_now [ 'active' ];
2019-02-05 07:10:21 +08:00
$target_domain = ( ! empty ( $_data [ 'target_domain' ])) ? idn_to_ascii ( strtolower ( trim ( $_data [ 'target_domain' ])), 0 , INTL_IDNA_VARIANT_UTS46 ) : $is_now [ 'target_domain' ];
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'alias_domain_invalid' , htmlspecialchars ( $alias_domain ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! is_valid_domain_name ( $target_domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'target_domain_invalid' , htmlspecialchars ( $target_domain ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $target_domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2017-07-16 17:03:28 +08:00
if ( empty ( mailbox ( 'get' , 'domain_details' , $target_domain )) || ! empty ( mailbox ( 'get' , 'alias_domain_details' , $target_domain ))) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'target_domain_invalid' , htmlspecialchars ( $target_domain ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `alias_domain` SET
`target_domain` = : target_domain ,
`active` = : active
WHERE `alias_domain` = : alias_domain " );
$stmt -> execute ( array (
':alias_domain' => $alias_domain ,
':target_domain' => $target_domain ,
':active' => $active
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'aliasd_modified' , htmlspecialchars ( $alias_domain ))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'tls_policy' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'tls_policy' ]) || $_SESSION [ 'acl' ][ 'tls_policy' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
foreach ( $usernames as $username ) {
if ( ! filter_var ( $username , FILTER_VALIDATE_EMAIL ) || ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $username )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
$is_now = mailbox ( 'get' , 'tls_policy' , $username );
if ( ! empty ( $is_now )) {
2017-07-16 17:03:28 +08:00
$tls_enforce_in = ( isset ( $_data [ 'tls_enforce_in' ])) ? intval ( $_data [ 'tls_enforce_in' ]) : $is_now [ 'tls_enforce_in' ];
$tls_enforce_out = ( isset ( $_data [ 'tls_enforce_out' ])) ? intval ( $_data [ 'tls_enforce_out' ]) : $is_now [ 'tls_enforce_out' ];
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `mailbox`
SET `attributes` = JSON_SET ( `attributes` , '$.tls_enforce_out' , : tls_out ),
`attributes` = JSON_SET ( `attributes` , '$.tls_enforce_in' , : tls_in )
WHERE `username` = : username " );
$stmt -> execute ( array (
':tls_out' => intval ( $tls_enforce_out ),
':tls_in' => intval ( $tls_enforce_in ),
':username' => $username
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
2017-05-23 15:36:59 +08:00
}
break ;
2019-01-29 07:20:39 +08:00
case 'quarantine_notification' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
if ( ! isset ( $_SESSION [ 'acl' ][ 'quarantine_notification' ]) || $_SESSION [ 'acl' ][ 'quarantine_notification' ] != " 1 " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
return false ;
}
foreach ( $usernames as $username ) {
if ( ! filter_var ( $username , FILTER_VALIDATE_EMAIL ) || ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $username )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
}
$is_now = mailbox ( 'get' , 'quarantine_notification' , $username );
if ( ! empty ( $is_now )) {
$quarantine_notification = ( isset ( $_data [ 'quarantine_notification' ])) ? $_data [ 'quarantine_notification' ] : $is_now [ 'quarantine_notification' ];
}
else {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
}
if ( ! in_array ( $quarantine_notification , array ( 'never' , 'hourly' , 'daily' , 'weekly' ))) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
2019-11-11 16:55:15 +08:00
}
2019-01-29 07:20:39 +08:00
$stmt = $pdo -> prepare ( " UPDATE `mailbox`
SET `attributes` = JSON_SET ( `attributes` , '$.quarantine_notification' , : quarantine_notification )
WHERE `username` = : username " );
$stmt -> execute ( array (
':quarantine_notification' => $quarantine_notification ,
':username' => $username
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
}
break ;
2020-11-29 00:41:48 +08:00
case 'quarantine_category' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
if ( ! isset ( $_SESSION [ 'acl' ][ 'quarantine_category' ]) || $_SESSION [ 'acl' ][ 'quarantine_category' ] != " 1 " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
return false ;
}
foreach ( $usernames as $username ) {
if ( ! filter_var ( $username , FILTER_VALIDATE_EMAIL ) || ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $username )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
}
$is_now = mailbox ( 'get' , 'quarantine_category' , $username );
if ( ! empty ( $is_now )) {
$quarantine_category = ( isset ( $_data [ 'quarantine_category' ])) ? $_data [ 'quarantine_category' ] : $is_now [ 'quarantine_category' ];
}
else {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
}
if ( ! in_array ( $quarantine_category , array ( 'add_header' , 'reject' , 'all' ))) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
}
$stmt = $pdo -> prepare ( " UPDATE `mailbox`
SET `attributes` = JSON_SET ( `attributes` , '$.quarantine_category' , : quarantine_category )
WHERE `username` = : username " );
$stmt -> execute ( array (
':quarantine_category' => $quarantine_category ,
':username' => $username
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
}
break ;
2017-05-23 15:36:59 +08:00
case 'spam_score' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'spam_score' ]) || $_SESSION [ 'acl' ][ 'spam_score' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
foreach ( $usernames as $username ) {
2018-10-19 03:48:30 +08:00
if ( $_data [ 'spam_score' ] == " default " ) {
$stmt = $pdo -> prepare ( " DELETE FROM `filterconf` WHERE `object` = :username
AND ( `option` = 'lowspamlevel' OR `option` = 'highspamlevel' ) " );
$stmt -> execute ( array (
':username' => $username
));
2018-10-19 04:32:37 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
2018-10-19 03:48:30 +08:00
continue ;
}
2017-05-23 15:36:59 +08:00
$lowspamlevel = explode ( ',' , $_data [ 'spam_score' ])[ 0 ];
$highspamlevel = explode ( ',' , $_data [ 'spam_score' ])[ 1 ];
if ( ! is_numeric ( $lowspamlevel ) || ! is_numeric ( $highspamlevel )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-10-19 03:48:30 +08:00
'msg' => 'Invalid spam score, format must be "1,2" where first is low and second is high spam value.'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2021-05-22 18:13:37 +08:00
if ( $lowspamlevel == $highspamlevel ) {
$highspamlevel = $highspamlevel + 0.1 ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `filterconf` WHERE `object` = :username
AND ( `option` = 'lowspamlevel' OR `option` = 'highspamlevel' ) " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " INSERT INTO `filterconf` (`object`, `option`, `value`)
VALUES ( : username , 'highspamlevel' , : highspamlevel ) " );
$stmt -> execute ( array (
':username' => $username ,
':highspamlevel' => $highspamlevel
));
$stmt = $pdo -> prepare ( " INSERT INTO `filterconf` (`object`, `option`, `value`)
VALUES ( : username , 'lowspamlevel' , : lowspamlevel ) " );
$stmt -> execute ( array (
':username' => $username ,
':lowspamlevel' => $lowspamlevel
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'time_limited_alias' :
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'spam_alias' ]) || $_SESSION [ 'acl' ][ 'spam_alias' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( ! is_array ( $_data [ 'address' ])) {
$addresses = array ();
$addresses [] = $_data [ 'address' ];
}
else {
$addresses = $_data [ 'address' ];
}
foreach ( $addresses as $address ) {
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `goto` FROM `spamalias` WHERE `address` = :address " );
$stmt -> execute ( array ( ':address' => $address ));
$goto = $stmt -> fetch ( PDO :: FETCH_ASSOC )[ 'goto' ];
2017-05-23 15:36:59 +08:00
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $goto )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-10-17 02:08:52 +08:00
if ( empty ( $_data [ 'validity' ])) {
continue ;
}
$validity = round (( int ) time () + ( $_data [ 'validity' ] * 3600 ));
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " UPDATE `spamalias` SET `validity` = :validity WHERE
2018-10-17 02:08:52 +08:00
`address` = : address " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':address' => $address ,
2018-10-17 02:08:52 +08:00
':validity' => $validity
2018-08-14 05:20:40 +08:00
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , htmlspecialchars ( implode ( ', ' , $usernames )))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'delimiter_action' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'delimiter_action' ]) || $_SESSION [ 'acl' ][ 'delimiter_action' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
foreach ( $usernames as $username ) {
if ( ! filter_var ( $username , FILTER_VALIDATE_EMAIL ) || ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $username )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( isset ( $_data [ 'tagged_mail_handler' ]) && $_data [ 'tagged_mail_handler' ] == " subject " ) {
try {
$redis -> hSet ( 'RCPT_WANTS_SUBJECT_TAG' , $username , 1 );
2018-01-16 23:31:37 +08:00
$redis -> hDel ( 'RCPT_WANTS_SUBFOLDER_TAG' , $username );
2017-05-23 15:36:59 +08:00
}
catch ( RedisException $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
}
2018-01-16 19:47:59 +08:00
else if ( isset ( $_data [ 'tagged_mail_handler' ]) && $_data [ 'tagged_mail_handler' ] == " subfolder " ) {
try {
2018-01-16 23:31:37 +08:00
$redis -> hSet ( 'RCPT_WANTS_SUBFOLDER_TAG' , $username , 1 );
$redis -> hDel ( 'RCPT_WANTS_SUBJECT_TAG' , $username );
2017-05-23 15:36:59 +08:00
}
catch ( RedisException $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
}
else {
try {
$redis -> hDel ( 'RCPT_WANTS_SUBJECT_TAG' , $username );
2018-01-16 23:31:37 +08:00
$redis -> hDel ( 'RCPT_WANTS_SUBFOLDER_TAG' , $username );
2017-05-23 15:36:59 +08:00
}
catch ( RedisException $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
}
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'syncjob' :
if ( ! is_array ( $_data [ 'id' ])) {
$ids = array ();
$ids [] = $_data [ 'id' ];
}
else {
$ids = $_data [ 'id' ];
}
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'syncjobs' ]) || $_SESSION [ 'acl' ][ 'syncjobs' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
foreach ( $ids as $id ) {
2017-11-05 19:20:05 +08:00
$is_now = mailbox ( 'get' , 'syncjob_details' , $id , array ( 'with_password' ));
2017-05-23 15:36:59 +08:00
if ( ! empty ( $is_now )) {
$username = $is_now [ 'user2' ];
$user1 = ( ! empty ( $_data [ 'user1' ])) ? $_data [ 'user1' ] : $is_now [ 'user1' ];
2020-09-18 01:49:15 +08:00
$active = ( isset ( $_data [ 'active' ])) ? intval ( $_data [ 'active' ]) : $is_now [ 'active' ];
2017-11-05 19:20:05 +08:00
$last_run = ( isset ( $_data [ 'last_run' ])) ? NULL : $is_now [ 'last_run' ];
2017-07-16 17:03:28 +08:00
$delete2duplicates = ( isset ( $_data [ 'delete2duplicates' ])) ? intval ( $_data [ 'delete2duplicates' ]) : $is_now [ 'delete2duplicates' ];
2018-07-28 04:19:59 +08:00
$subscribeall = ( isset ( $_data [ 'subscribeall' ])) ? intval ( $_data [ 'subscribeall' ]) : $is_now [ 'subscribeall' ];
2017-07-16 17:03:28 +08:00
$delete1 = ( isset ( $_data [ 'delete1' ])) ? intval ( $_data [ 'delete1' ]) : $is_now [ 'delete1' ];
2017-08-31 16:36:10 +08:00
$delete2 = ( isset ( $_data [ 'delete2' ])) ? intval ( $_data [ 'delete2' ]) : $is_now [ 'delete2' ];
2018-01-24 19:59:04 +08:00
$automap = ( isset ( $_data [ 'automap' ])) ? intval ( $_data [ 'automap' ]) : $is_now [ 'automap' ];
$skipcrossduplicates = ( isset ( $_data [ 'skipcrossduplicates' ])) ? intval ( $_data [ 'skipcrossduplicates' ]) : $is_now [ 'skipcrossduplicates' ];
2017-05-23 15:36:59 +08:00
$port1 = ( ! empty ( $_data [ 'port1' ])) ? $_data [ 'port1' ] : $is_now [ 'port1' ];
$password1 = ( ! empty ( $_data [ 'password1' ])) ? $_data [ 'password1' ] : $is_now [ 'password1' ];
$host1 = ( ! empty ( $_data [ 'host1' ])) ? $_data [ 'host1' ] : $is_now [ 'host1' ];
2017-10-21 16:07:06 +08:00
$subfolder2 = ( isset ( $_data [ 'subfolder2' ])) ? $_data [ 'subfolder2' ] : $is_now [ 'subfolder2' ];
2017-05-23 15:36:59 +08:00
$enc1 = ( ! empty ( $_data [ 'enc1' ])) ? $_data [ 'enc1' ] : $is_now [ 'enc1' ];
$mins_interval = ( ! empty ( $_data [ 'mins_interval' ])) ? $_data [ 'mins_interval' ] : $is_now [ 'mins_interval' ];
2018-03-09 17:51:36 +08:00
$exclude = ( isset ( $_data [ 'exclude' ])) ? $_data [ 'exclude' ] : $is_now [ 'exclude' ];
2018-07-28 04:19:59 +08:00
$custom_params = ( isset ( $_data [ 'custom_params' ])) ? $_data [ 'custom_params' ] : $is_now [ 'custom_params' ];
2017-10-21 16:07:06 +08:00
$maxage = ( isset ( $_data [ 'maxage' ]) && $_data [ 'maxage' ] != " " ) ? intval ( $_data [ 'maxage' ]) : $is_now [ 'maxage' ];
2018-01-24 19:59:04 +08:00
$maxbytespersecond = ( isset ( $_data [ 'maxbytespersecond' ]) && $_data [ 'maxbytespersecond' ] != " " ) ? intval ( $_data [ 'maxbytespersecond' ]) : $is_now [ 'maxbytespersecond' ];
2018-07-28 04:19:59 +08:00
$timeout1 = ( isset ( $_data [ 'timeout1' ]) && $_data [ 'timeout1' ] != " " ) ? intval ( $_data [ 'timeout1' ]) : $is_now [ 'timeout1' ];
$timeout2 = ( isset ( $_data [ 'timeout2' ]) && $_data [ 'timeout2' ] != " " ) ? intval ( $_data [ 'timeout2' ]) : $is_now [ 'timeout2' ];
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2020-11-06 21:26:48 +08:00
if ( strpos ( $custom_params , 'pipemess' )) {
$custom_params = '' ;
}
2017-05-23 15:36:59 +08:00
if ( empty ( $subfolder2 )) {
$subfolder2 = " " ;
}
2018-07-28 04:19:59 +08:00
if ( ! isset ( $maxage ) || ! filter_var ( $maxage , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 32000 )))) {
2017-05-23 15:36:59 +08:00
$maxage = " 0 " ;
}
2018-07-28 04:19:59 +08:00
if ( ! isset ( $timeout1 ) || ! filter_var ( $timeout1 , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 32000 )))) {
$timeout1 = " 600 " ;
}
if ( ! isset ( $timeout2 ) || ! filter_var ( $timeout2 , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 32000 )))) {
$timeout2 = " 600 " ;
}
2018-01-24 19:59:04 +08:00
if ( ! isset ( $maxbytespersecond ) || ! filter_var ( $maxbytespersecond , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 125000000 )))) {
$maxbytespersecond = " 0 " ;
}
2017-05-23 15:36:59 +08:00
if ( ! filter_var ( $port1 , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 65535 )))) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2020-07-09 01:36:05 +08:00
if ( ! filter_var ( $mins_interval , FILTER_VALIDATE_INT , array ( 'options' => array ( 'min_range' => 1 , 'max_range' => 43800 )))) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! is_valid_domain_name ( $host1 )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $enc1 != " TLS " && $enc1 != " SSL " && $enc1 != " PLAIN " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( @ preg_match ( " / " . $exclude . " / " , null ) === false ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `imapsync` SET `delete1` = :delete1,
`delete2` = : delete2 ,
`automap` = : automap ,
`skipcrossduplicates` = : skipcrossduplicates ,
`maxage` = : maxage ,
`maxbytespersecond` = : maxbytespersecond ,
`subfolder2` = : subfolder2 ,
`exclude` = : exclude ,
`host1` = : host1 ,
`last_run` = : last_run ,
`user1` = : user1 ,
`password1` = : password1 ,
`mins_interval` = : mins_interval ,
`port1` = : port1 ,
`enc1` = : enc1 ,
`delete2duplicates` = : delete2duplicates ,
`custom_params` = : custom_params ,
`timeout1` = : timeout1 ,
`timeout2` = : timeout2 ,
`subscribeall` = : subscribeall ,
`active` = : active
WHERE `id` = : id " );
$stmt -> execute ( array (
':delete1' => $delete1 ,
':delete2' => $delete2 ,
':automap' => $automap ,
':skipcrossduplicates' => $skipcrossduplicates ,
':id' => $id ,
':exclude' => $exclude ,
':maxage' => $maxage ,
':maxbytespersecond' => $maxbytespersecond ,
':subfolder2' => $subfolder2 ,
':host1' => $host1 ,
':user1' => $user1 ,
':password1' => $password1 ,
':last_run' => $last_run ,
':mins_interval' => $mins_interval ,
':port1' => $port1 ,
':enc1' => $enc1 ,
':delete2duplicates' => $delete2duplicates ,
':custom_params' => $custom_params ,
':timeout1' => $timeout1 ,
':timeout2' => $timeout2 ,
':subscribeall' => $subscribeall ,
':active' => $active ,
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
2017-05-23 15:36:59 +08:00
}
break ;
2017-11-04 03:37:24 +08:00
case 'filter' :
if ( ! isset ( $_SESSION [ 'acl' ][ 'filters' ]) || $_SESSION [ 'acl' ][ 'filters' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-11-04 03:37:24 +08:00
);
return false ;
}
2018-09-10 03:17:59 +08:00
$sieve = new Sieve\SieveParser ();
if ( ! is_array ( $_data [ 'id' ])) {
$ids = array ();
$ids [] = $_data [ 'id' ];
}
else {
$ids = $_data [ 'id' ];
}
2017-11-04 03:37:24 +08:00
foreach ( $ids as $id ) {
$is_now = mailbox ( 'get' , 'filter_details' , $id );
if ( ! empty ( $is_now )) {
$username = $is_now [ 'username' ];
2020-09-18 01:49:15 +08:00
$active = ( isset ( $_data [ 'active' ])) ? intval ( $_data [ 'active' ]) : $is_now [ 'active' ];
2017-11-04 03:37:24 +08:00
$script_desc = ( ! empty ( $_data [ 'script_desc' ])) ? $_data [ 'script_desc' ] : $is_now [ 'script_desc' ];
$script_data = ( ! empty ( $_data [ 'script_data' ])) ? $_data [ 'script_data' ] : $is_now [ 'script_data' ];
$filter_type = ( ! empty ( $_data [ 'filter_type' ])) ? $_data [ 'filter_type' ] : $is_now [ 'filter_type' ];
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-11-04 03:37:24 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-11-04 03:37:24 +08:00
}
try {
$sieve -> parse ( $script_data );
}
catch ( Exception $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'sieve_error' , $e -> getMessage ())
2017-11-04 03:37:24 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-11-04 03:37:24 +08:00
}
if ( $filter_type != 'postfilter' && $filter_type != 'prefilter' ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'filter_type'
2017-11-04 03:37:24 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-11-04 03:37:24 +08:00
}
if ( $active == '1' ) {
$script_name = 'active' ;
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `sieve_filters`
SET `script_name` = 'inactive'
WHERE `username` = : username
AND `filter_type` = : filter_type " );
2017-11-04 03:37:24 +08:00
$stmt -> execute ( array (
2018-08-14 05:20:40 +08:00
':username' => $username ,
':filter_type' => $filter_type
2017-11-04 03:37:24 +08:00
));
}
2018-08-14 05:20:40 +08:00
else {
$script_name = 'inactive' ;
2017-11-04 03:37:24 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `sieve_filters` SET `script_desc` = :script_desc, `script_data` = :script_data, `script_name` = :script_name, `filter_type` = :filter_type
WHERE `id` = : id " );
$stmt -> execute ( array (
':script_desc' => $script_desc ,
':script_data' => $script_data ,
':script_name' => $script_name ,
':filter_type' => $filter_type ,
':id' => $id
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
2017-11-04 03:37:24 +08:00
}
break ;
2017-05-23 15:36:59 +08:00
case 'alias' :
2018-08-14 05:20:40 +08:00
if ( ! is_array ( $_data [ 'id' ])) {
$ids = array ();
$ids [] = $_data [ 'id' ];
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$ids = $_data [ 'id' ];
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
foreach ( $ids as $id ) {
$is_now = mailbox ( 'get' , 'alias_details' , $id );
2017-05-23 15:36:59 +08:00
if ( ! empty ( $is_now )) {
2020-09-18 01:49:15 +08:00
$active = ( isset ( $_data [ 'active' ])) ? intval ( $_data [ 'active' ]) : $is_now [ 'active' ];
$sogo_visible = ( isset ( $_data [ 'sogo_visible' ])) ? intval ( $_data [ 'sogo_visible' ]) : $is_now [ 'sogo_visible' ];
2018-08-14 05:20:40 +08:00
$goto_null = ( isset ( $_data [ 'goto_null' ])) ? intval ( $_data [ 'goto_null' ]) : 0 ;
$goto_spam = ( isset ( $_data [ 'goto_spam' ])) ? intval ( $_data [ 'goto_spam' ]) : 0 ;
$goto_ham = ( isset ( $_data [ 'goto_ham' ])) ? intval ( $_data [ 'goto_ham' ]) : 0 ;
2019-01-29 07:20:39 +08:00
$public_comment = ( isset ( $_data [ 'public_comment' ])) ? $_data [ 'public_comment' ] : $is_now [ 'public_comment' ];
$private_comment = ( isset ( $_data [ 'private_comment' ])) ? $_data [ 'private_comment' ] : $is_now [ 'private_comment' ];
2018-08-14 05:20:40 +08:00
$goto = ( ! empty ( $_data [ 'goto' ])) ? $_data [ 'goto' ] : $is_now [ 'goto' ];
$address = ( ! empty ( $_data [ 'address' ])) ? $_data [ 'address' ] : $is_now [ 'address' ];
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2019-12-23 21:46:57 +08:00
'msg' => array ( 'alias_invalid' , $address )
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
}
2021-03-19 16:11:55 +08:00
if ( $_data [ 'expand_alias' ] === true || $_data [ 'expand_alias' ] == 1 ) {
2021-03-19 16:28:45 +08:00
$stmt = $pdo -> prepare ( " SELECT `address` FROM `alias`
WHERE `address` = : address
AND `domain` NOT IN (
SELECT `alias_domain` FROM `alias_domain`
) " );
$stmt -> execute ( array (
':address' => $address ,
));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'is_not_primary_alias' , htmlspecialchars ( $address ))
);
continue ;
}
2021-03-19 16:11:55 +08:00
$stmt = $pdo -> prepare ( " SELECT `goto`, GROUP_CONCAT(CONCAT(SUBSTRING(`alias`.`address`, 1, LOCATE('@', `alias`.`address`) - 1), '@', `alias_domain`.`alias_domain`)) AS `missing_alias`
FROM `alias` JOIN `alias_domain` ON `alias_domain` . `target_domain` = `alias` . `domain`
WHERE CONCAT ( SUBSTRING ( `alias` . `address` , 1 , LOCATE ( '@' , `alias` . `address` ) - 1 ), '@' , `alias_domain` . `alias_domain` ) NOT IN (
SELECT `address` FROM `alias` WHERE `address` != `goto`
)
AND `alias` . `address` NOT IN (
SELECT `address` FROM `alias` WHERE `address` = `goto`
)
AND `address` = : address ; " );
$stmt -> execute ( array (
':address' => $address
));
$missing_aliases = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( ! empty ( $missing_aliases [ 'missing_alias' ])) {
mailbox ( 'add' , 'alias' , array (
'address' => $missing_aliases [ 'missing_alias' ],
'goto' => $missing_aliases [ 'goto' ],
'sogo_visible' => 1 ,
'active' => 1
));
}
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'alias_modified' , htmlspecialchars ( $address ))
);
continue ;
}
2020-04-04 02:39:53 +08:00
$domain = idn_to_ascii ( substr ( strstr ( $address , '@' ), 1 ), 0 , INTL_IDNA_VARIANT_UTS46 );
2018-08-14 05:20:40 +08:00
if ( $is_now [ 'address' ] != $address ) {
$local_part = strstr ( $address , '@' , true );
$address = $local_part . '@' . $domain ;
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
}
if (( ! filter_var ( $address , FILTER_VALIDATE_EMAIL ) === true ) && ! empty ( $local_part )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2019-12-23 21:46:57 +08:00
'msg' => array ( 'alias_invalid' , $address )
2018-08-14 05:20:40 +08:00
);
continue ;
}
2019-05-06 02:01:53 +08:00
if ( strtolower ( $is_now [ 'address' ]) != strtolower ( $address )) {
$stmt = $pdo -> prepare ( " SELECT `address` FROM `alias`
WHERE `address` = : address OR `address` IN (
SELECT `username` FROM `mailbox` , `alias_domain`
WHERE (
`alias_domain` . `alias_domain` = : address_d
AND `mailbox` . `username` = CONCAT ( : address_l , '@' , alias_domain . target_domain ))) " );
$stmt -> execute ( array (
':address' => $address ,
':address_l' => $local_part ,
':address_d' => $domain
));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'is_alias_or_mailbox' , htmlspecialchars ( $address ))
);
continue ;
}
2018-08-14 05:20:40 +08:00
}
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain`
WHERE `domain` = : domain1 OR `domain` = ( SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = : domain2 ) " );
$stmt -> execute ( array ( ':domain1' => $domain , ':domain2' => $domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_not_found' , htmlspecialchars ( $domain ))
);
continue ;
}
$stmt = $pdo -> prepare ( " SELECT `address` FROM `spamalias`
WHERE `address` = : address " );
$stmt -> execute ( array ( ':address' => $address ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'is_spam_alias' , htmlspecialchars ( $address ))
);
continue ;
}
2017-05-23 15:36:59 +08:00
}
2017-09-16 19:17:37 +08:00
if ( $goto_null == " 1 " ) {
$goto = " null@localhost " ;
}
2018-07-29 06:38:22 +08:00
elseif ( $goto_spam == " 1 " ) {
$goto = " spam@localhost " ;
}
elseif ( $goto_ham == " 1 " ) {
$goto = " ham@localhost " ;
}
2017-09-16 19:17:37 +08:00
else {
2018-08-14 05:20:40 +08:00
$gotos = array_map ( 'trim' , preg_split ( " /( |,|;| \n )/ " , $goto ));
foreach ( $gotos as $i => & $goto ) {
2017-09-16 19:17:37 +08:00
if ( empty ( $goto )) {
continue ;
}
if ( ! filter_var ( $goto , FILTER_VALIDATE_EMAIL )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-09-16 19:17:37 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'goto_invalid' , $goto )
2017-09-16 19:17:37 +08:00
);
2018-08-14 05:20:40 +08:00
unset ( $gotos [ $i ]);
continue ;
2017-09-16 19:17:37 +08:00
}
if ( $goto == $address ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-09-16 19:17:37 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'alias_goto_identical'
2017-09-16 19:17:37 +08:00
);
2018-08-14 05:20:40 +08:00
unset ( $gotos [ $i ]);
continue ;
2017-09-16 19:17:37 +08:00
}
2019-05-26 15:22:06 +08:00
// Delete from sender_acl to prevent duplicates
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE
`logged_in_as` = : goto AND
`send_as` = : address " );
$stmt -> execute ( array (
':goto' => $goto ,
':address' => $address
));
2017-05-23 15:36:59 +08:00
}
2021-05-23 19:18:52 +08:00
$gotos = array_unique ( $gotos );
2017-09-16 19:17:37 +08:00
$gotos = array_filter ( $gotos );
$goto = implode ( " , " , $gotos );
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
if ( ! empty ( $goto )) {
$stmt = $pdo -> prepare ( " UPDATE `alias` SET
`address` = : address ,
2019-01-29 07:20:39 +08:00
`public_comment` = : public_comment ,
`private_comment` = : private_comment ,
2020-04-04 02:39:53 +08:00
`domain` = : domain ,
2018-08-14 05:20:40 +08:00
`goto` = : goto ,
2019-09-22 21:10:56 +08:00
`sogo_visible` = : sogo_visible ,
2018-08-14 05:20:40 +08:00
`active` = : active
WHERE `id` = : id " );
$stmt -> execute ( array (
':address' => $address ,
2019-01-29 07:20:39 +08:00
':public_comment' => $public_comment ,
':private_comment' => $private_comment ,
2020-04-04 02:39:53 +08:00
':domain' => $domain ,
2018-08-14 05:20:40 +08:00
':goto' => $goto ,
2019-09-22 21:10:56 +08:00
':sogo_visible' => $sogo_visible ,
2018-08-14 05:20:40 +08:00
':active' => $active ,
2020-05-26 03:59:13 +08:00
':id' => $is_now [ 'id' ]
2018-08-14 05:20:40 +08:00
));
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'alias_modified' , htmlspecialchars ( $address ))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'domain' :
if ( ! is_array ( $_data [ 'domain' ])) {
$domains = array ();
$domains [] = $_data [ 'domain' ];
}
else {
$domains = $_data [ 'domain' ];
}
foreach ( $domains as $domain ) {
2019-02-05 07:10:21 +08:00
$domain = idn_to_ascii ( $domain , 0 , INTL_IDNA_VARIANT_UTS46 );
2017-05-23 15:36:59 +08:00
if ( ! is_valid_domain_name ( $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $_SESSION [ 'mailcow_cc_role' ] == " domainadmin " &&
hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain )) {
2019-01-17 06:41:02 +08:00
$is_now = mailbox ( 'get' , 'domain_details' , $domain );
if ( ! empty ( $is_now )) {
2020-09-18 01:49:15 +08:00
$gal = ( isset ( $_data [ 'gal' ])) ? intval ( $_data [ 'gal' ]) : $is_now [ 'gal' ];
2021-02-11 16:34:21 +08:00
$xmpp = ( isset ( $_data [ 'xmpp' ]) && ! empty ( $_SESSION [ 'acl' ][ 'xmpp_domain_access' ]) && $_SESSION [ 'acl' ][ 'xmpp_domain_access' ] == " 1 " ) ? intval ( $_data [ 'xmpp' ]) : $is_now [ 'xmpp' ];
$xmpp_prefix = ( ! empty ( $_data [ 'xmpp_prefix' ]) && ! empty ( $_SESSION [ 'acl' ][ 'xmpp_prefix' ]) && $_SESSION [ 'acl' ][ 'xmpp_prefix' ] == " 1 " ) ? $_data [ 'xmpp_prefix' ] : $is_now [ 'xmpp_prefix' ];
2020-08-19 21:31:54 +08:00
$description = ( ! empty ( $_data [ 'description' ]) && isset ( $_SESSION [ 'acl' ][ 'domain_desc' ]) && $_SESSION [ 'acl' ][ 'domain_desc' ] == " 1 " ) ? $_data [ 'description' ] : $is_now [ 'description' ];
2019-01-17 06:41:02 +08:00
}
else {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
);
continue ;
}
2021-02-12 17:04:19 +08:00
$xmpp_prefix = preg_replace ( '/[^\da-z-]/i' , '' , $xmpp_prefix );
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " UPDATE `domain` SET
2019-01-17 06:41:02 +08:00
`description` = : description ,
2021-02-11 16:34:21 +08:00
`gal` = : gal ,
`xmpp` = : xmpp ,
`xmpp_prefix` = : xmpp_prefix
2018-08-14 05:20:40 +08:00
WHERE `domain` = : domain " );
$stmt -> execute ( array (
':description' => $description ,
2019-01-17 06:41:02 +08:00
':gal' => $gal ,
2021-02-11 16:34:21 +08:00
':xmpp' => $xmpp ,
':xmpp_prefix' => $xmpp_prefix ,
2018-08-14 05:20:40 +08:00
':domain' => $domain
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_modified' , htmlspecialchars ( $domain ))
);
2017-05-23 15:36:59 +08:00
}
elseif ( $_SESSION [ 'mailcow_cc_role' ] == " admin " ) {
$is_now = mailbox ( 'get' , 'domain_details' , $domain );
if ( ! empty ( $is_now )) {
2020-09-18 01:49:15 +08:00
$active = ( isset ( $_data [ 'active' ])) ? intval ( $_data [ 'active' ]) : $is_now [ 'active' ];
$backupmx = ( isset ( $_data [ 'backupmx' ])) ? intval ( $_data [ 'backupmx' ]) : $is_now [ 'backupmx' ];
$gal = ( isset ( $_data [ 'gal' ])) ? intval ( $_data [ 'gal' ]) : $is_now [ 'gal' ];
2021-02-11 16:34:21 +08:00
$xmpp = ( isset ( $_data [ 'xmpp' ])) ? intval ( $_data [ 'xmpp' ]) : $is_now [ 'xmpp' ];
2020-09-18 01:49:15 +08:00
$relay_all_recipients = ( isset ( $_data [ 'relay_all_recipients' ])) ? intval ( $_data [ 'relay_all_recipients' ]) : $is_now [ 'relay_all_recipients' ];
$relay_unknown_only = ( isset ( $_data [ 'relay_unknown_only' ])) ? intval ( $_data [ 'relay_unknown_only' ]) : $is_now [ 'relay_unknown_only' ];
2017-07-23 02:39:54 +08:00
$relayhost = ( isset ( $_data [ 'relayhost' ])) ? intval ( $_data [ 'relayhost' ]) : $is_now [ 'relayhost' ];
2017-05-23 15:36:59 +08:00
$aliases = ( ! empty ( $_data [ 'aliases' ])) ? $_data [ 'aliases' ] : $is_now [ 'max_num_aliases_for_domain' ];
2018-11-17 06:12:46 +08:00
$mailboxes = ( isset ( $_data [ 'mailboxes' ]) && $_data [ 'mailboxes' ] != '' ) ? intval ( $_data [ 'mailboxes' ]) : $is_now [ 'max_num_mboxes_for_domain' ];
2019-08-09 20:16:52 +08:00
$defquota = ( isset ( $_data [ 'defquota' ]) && $_data [ 'defquota' ] != '' ) ? intval ( $_data [ 'defquota' ]) : ( $is_now [ 'def_quota_for_mbox' ] / 1048576 );
2017-05-30 03:51:06 +08:00
$maxquota = ( ! empty ( $_data [ 'maxquota' ])) ? $_data [ 'maxquota' ] : ( $is_now [ 'max_quota_for_mbox' ] / 1048576 );
2017-05-23 15:36:59 +08:00
$quota = ( ! empty ( $_data [ 'quota' ])) ? $_data [ 'quota' ] : ( $is_now [ 'max_quota_for_domain' ] / 1048576 );
$description = ( ! empty ( $_data [ 'description' ])) ? $_data [ 'description' ] : $is_now [ 'description' ];
2021-02-11 16:34:21 +08:00
$xmpp_prefix = ( ! empty ( $_data [ 'xmpp_prefix' ])) ? $_data [ 'xmpp_prefix' ] : $is_now [ 'xmpp_prefix' ];
2020-04-04 02:39:53 +08:00
if ( $relay_all_recipients == '1' ) {
$backupmx = '1' ;
}
if ( $relay_unknown_only == '1' ) {
$backupmx = '1' ;
$relay_all_recipients = '1' ;
}
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2021-02-12 17:04:19 +08:00
$xmpp_prefix = preg_replace ( '/[^\da-z-]/i' , '' , $xmpp_prefix );
2018-08-14 05:20:40 +08:00
// todo: should be using api here
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " SELECT
2018-08-14 05:20:40 +08:00
COUNT ( * ) AS count ,
MAX ( COALESCE ( ROUND ( `quota` / 1048576 ), 0 )) AS `biggest_mailbox` ,
COALESCE ( ROUND ( SUM ( `quota` ) / 1048576 ), 0 ) AS `quota_all`
FROM `mailbox`
2021-03-19 23:33:50 +08:00
WHERE ( `kind` = '' OR `kind` = NULL )
2018-08-14 05:20:40 +08:00
AND domain = : domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$MailboxData = $stmt -> fetch ( PDO :: FETCH_ASSOC );
// todo: should be using api here
$stmt = $pdo -> prepare ( " SELECT COUNT(*) AS `count` FROM `alias`
WHERE domain = : domain
AND address NOT IN (
SELECT `username` FROM `mailbox`
) " );
$stmt -> execute ( array ( ':domain' => $domain ));
$AliasData = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2019-05-11 17:16:40 +08:00
if ( $defquota > $maxquota ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'mailbox_defquota_exceeds_mailbox_maxquota'
);
continue ;
}
if ( $defquota == " 0 " || empty ( $defquota )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'defquota_empty'
);
continue ;
}
2017-05-23 15:36:59 +08:00
if ( $maxquota > $quota ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'mailbox_quota_exceeds_domain_quota'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $maxquota == " 0 " || empty ( $maxquota )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'maxquota_empty'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $MailboxData [ 'biggest_mailbox' ] > $maxquota ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'max_quota_in_use' , $MailboxData [ 'biggest_mailbox' ])
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $MailboxData [ 'quota_all' ] > $quota ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_quota_m_in_use' , $MailboxData [ 'quota_all' ])
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $MailboxData [ 'count' ] > $mailboxes ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailboxes_in_use' , $MailboxData [ 'count' ])
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $AliasData [ 'count' ] > $aliases ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'aliases_in_use' , $AliasData [ 'count' ])
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " UPDATE `domain` SET
2018-08-14 05:20:40 +08:00
`relay_all_recipients` = : relay_all_recipients ,
2020-04-04 02:39:53 +08:00
`relay_unknown_only` = : relay_unknown_only ,
2018-08-14 05:20:40 +08:00
`backupmx` = : backupmx ,
2019-01-17 06:41:02 +08:00
`gal` = : gal ,
2021-02-11 16:34:21 +08:00
`xmpp` = : xmpp ,
`xmpp_prefix` = : xmpp_prefix ,
2018-08-14 05:20:40 +08:00
`active` = : active ,
`quota` = : quota ,
2019-05-11 17:16:40 +08:00
`defquota` = : defquota ,
2018-08-14 05:20:40 +08:00
`maxquota` = : maxquota ,
`relayhost` = : relayhost ,
`mailboxes` = : mailboxes ,
`aliases` = : aliases ,
`description` = : description
WHERE `domain` = : domain " );
$stmt -> execute ( array (
':relay_all_recipients' => $relay_all_recipients ,
2020-04-04 02:39:53 +08:00
':relay_unknown_only' => $relay_unknown_only ,
2018-08-14 05:20:40 +08:00
':backupmx' => $backupmx ,
2019-01-17 06:41:02 +08:00
':gal' => $gal ,
2021-02-11 16:34:21 +08:00
':xmpp' => $xmpp ,
':xmpp_prefix' => $xmpp_prefix ,
2018-08-14 05:20:40 +08:00
':active' => $active ,
':quota' => $quota ,
2019-05-11 17:16:40 +08:00
':defquota' => $defquota ,
2018-08-14 05:20:40 +08:00
':maxquota' => $maxquota ,
':relayhost' => $relayhost ,
':mailboxes' => $mailboxes ,
':aliases' => $aliases ,
':description' => $description ,
':domain' => $domain
));
2018-08-15 06:05:18 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_modified' , htmlspecialchars ( $domain ))
);
2017-05-23 15:36:59 +08:00
}
}
break ;
case 'mailbox' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
foreach ( $usernames as $username ) {
if ( ! filter_var ( $username , FILTER_VALIDATE_EMAIL )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'username_invalid' , $username )
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
$is_now = mailbox ( 'get' , 'mailbox_details' , $username );
2020-09-18 01:49:15 +08:00
if ( isset ( $_data [ 'protocol_access' ])) {
$_data [ 'imap_access' ] = ( in_array ( 'imap' , $_data [ 'protocol_access' ])) ? 1 : 0 ;
$_data [ 'pop3_access' ] = ( in_array ( 'pop3' , $_data [ 'protocol_access' ])) ? 1 : 0 ;
$_data [ 'smtp_access' ] = ( in_array ( 'smtp' , $_data [ 'protocol_access' ])) ? 1 : 0 ;
}
2017-05-23 15:36:59 +08:00
if ( ! empty ( $is_now )) {
2020-09-18 01:49:15 +08:00
$active = ( isset ( $_data [ 'active' ])) ? intval ( $_data [ 'active' ]) : $is_now [ 'active' ];
2018-02-17 05:40:51 +08:00
( int ) $force_pw_update = ( isset ( $_data [ 'force_pw_update' ])) ? intval ( $_data [ 'force_pw_update' ]) : intval ( $is_now [ 'attributes' ][ 'force_pw_update' ]);
2020-09-18 01:49:15 +08:00
( int ) $sogo_access = ( isset ( $_data [ 'sogo_access' ]) && isset ( $_SESSION [ 'acl' ][ 'protocol_access' ]) && $_SESSION [ 'acl' ][ 'protocol_access' ] == " 1 " ) ? intval ( $_data [ 'sogo_access' ]) : intval ( $is_now [ 'attributes' ][ 'sogo_access' ]);
( int ) $imap_access = ( isset ( $_data [ 'imap_access' ]) && isset ( $_SESSION [ 'acl' ][ 'protocol_access' ]) && $_SESSION [ 'acl' ][ 'protocol_access' ] == " 1 " ) ? intval ( $_data [ 'imap_access' ]) : intval ( $is_now [ 'attributes' ][ 'imap_access' ]);
( int ) $pop3_access = ( isset ( $_data [ 'pop3_access' ]) && isset ( $_SESSION [ 'acl' ][ 'protocol_access' ]) && $_SESSION [ 'acl' ][ 'protocol_access' ] == " 1 " ) ? intval ( $_data [ 'pop3_access' ]) : intval ( $is_now [ 'attributes' ][ 'pop3_access' ]);
( int ) $smtp_access = ( isset ( $_data [ 'smtp_access' ]) && isset ( $_SESSION [ 'acl' ][ 'protocol_access' ]) && $_SESSION [ 'acl' ][ 'protocol_access' ] == " 1 " ) ? intval ( $_data [ 'smtp_access' ]) : intval ( $is_now [ 'attributes' ][ 'smtp_access' ]);
2021-02-11 16:34:21 +08:00
( int ) $xmpp_admin = ( isset ( $_data [ 'xmpp_admin' ]) && isset ( $_SESSION [ 'acl' ][ 'xmpp_admin' ]) && $_SESSION [ 'acl' ][ 'xmpp_admin' ] == " 1 " ) ? intval ( $_data [ 'xmpp_admin' ]) : intval ( $is_now [ 'attributes' ][ 'xmpp_admin' ]);
( int ) $xmpp_access = ( isset ( $_data [ 'xmpp_access' ]) && isset ( $_SESSION [ 'acl' ][ 'xmpp_mailbox_access' ]) && $_SESSION [ 'acl' ][ 'xmpp_mailbox_access' ] == " 1 " ) ? intval ( $_data [ 'xmpp_access' ]) : intval ( $is_now [ 'attributes' ][ 'xmpp_access' ]);
2019-03-29 05:05:12 +08:00
( int ) $quota_m = ( isset_has_content ( $_data [ 'quota' ])) ? intval ( $_data [ 'quota' ]) : ( $is_now [ 'quota' ] / 1048576 );
2019-02-26 16:23:16 +08:00
$name = ( ! empty ( $_data [ 'name' ])) ? ltrim ( rtrim ( $_data [ 'name' ], '>' ), '<' ) : $is_now [ 'name' ];
2017-05-23 15:36:59 +08:00
$domain = $is_now [ 'domain' ];
$quota_b = $quota_m * 1048576 ;
$password = ( ! empty ( $_data [ 'password' ])) ? $_data [ 'password' ] : null ;
2019-11-11 16:55:15 +08:00
$password2 = ( ! empty ( $_data [ 'password2' ])) ? $_data [ 'password2' ] : null ;
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2019-03-31 02:14:24 +08:00
// if already 0 == ok
if (( ! isset ( $_SESSION [ 'acl' ][ 'unlimited_quota' ]) || $_SESSION [ 'acl' ][ 'unlimited_quota' ] != " 1 " ) && ( $quota_m == 0 && $is_now [ 'quota' ] != 0 )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'unlimited_quota_acl'
);
return false ;
}
2017-05-23 15:36:59 +08:00
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2021-04-08 17:17:27 +08:00
$DomainData = mailbox ( 'get' , 'domain_details' , $domain );
if ( $quota_m > ( $is_now [ 'max_new_quota' ] / 1048576 )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2021-02-23 15:42:04 +08:00
'msg' => array ( 'mailbox_quota_left_exceeded' , ( $is_now [ 'max_new_quota' ] / 1048576 ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2021-04-08 17:17:27 +08:00
if ( $quota_m > $DomainData [ 'max_quota_for_mbox' ]) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2021-04-08 17:17:27 +08:00
'msg' => array ( 'mailbox_quota_exceeded' , $DomainData [ 'max_quota_for_mbox' ])
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2019-09-02 17:11:41 +08:00
$extra_acls = array ();
if ( isset ( $_data [ 'extended_sender_acl' ])) {
if ( ! isset ( $_SESSION [ 'acl' ][ 'extend_sender_acl' ]) || $_SESSION [ 'acl' ][ 'extend_sender_acl' ] != " 1 " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
return false ;
}
$extra_acls = array_map ( 'trim' , preg_split ( " /( |,|;| \n )/ " , $_data [ 'extended_sender_acl' ]));
foreach ( $extra_acls as $i => & $extra_acl ) {
if ( empty ( $extra_acl )) {
continue ;
}
if ( substr ( $extra_acl , 0 , 1 ) === " @ " ) {
$extra_acl = ltrim ( $extra_acl , '@' );
}
if ( ! filter_var ( $extra_acl , FILTER_VALIDATE_EMAIL ) && ! is_valid_domain_name ( $extra_acl )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'extra_acl_invalid' , htmlspecialchars ( $extra_acl ))
);
unset ( $extra_acls [ $i ]);
continue ;
}
$domains = array_merge ( mailbox ( 'get' , 'domains' ), mailbox ( 'get' , 'alias_domains' ));
if ( filter_var ( $extra_acl , FILTER_VALIDATE_EMAIL )) {
$extra_acl_domain = idn_to_ascii ( substr ( strstr ( $extra_acl , '@' ), 1 ), 0 , INTL_IDNA_VARIANT_UTS46 );
if ( in_array ( $extra_acl_domain , $domains )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'extra_acl_invalid_domain' , $extra_acl_domain )
);
unset ( $extra_acls [ $i ]);
continue ;
}
}
else {
if ( in_array ( $extra_acl , $domains )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'extra_acl_invalid_domain' , $extra_acl_domain )
);
unset ( $extra_acls [ $i ]);
continue ;
}
$extra_acl = '@' . $extra_acl ;
}
}
$extra_acls = array_filter ( $extra_acls );
$extra_acls = array_values ( $extra_acls );
$extra_acls = array_unique ( $extra_acls );
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `external` = 1 AND `logged_in_as` = :username " );
$stmt -> execute ( array (
':username' => $username
));
foreach ( $extra_acls as $sender_acl_external ) {
$stmt = $pdo -> prepare ( " INSERT INTO `sender_acl` (`send_as`, `logged_in_as`, `external`)
VALUES ( : sender_acl , : username , 1 ) " );
$stmt -> execute ( array (
':sender_acl' => $sender_acl_external ,
':username' => $username
));
}
}
2017-05-23 15:36:59 +08:00
if ( isset ( $_data [ 'sender_acl' ])) {
// Get sender_acl items set by admin
$sender_acl_admin = array_merge (
mailbox ( 'get' , 'sender_acl_handles' , $username )[ 'sender_acl_domains' ][ 'ro' ],
mailbox ( 'get' , 'sender_acl_handles' , $username )[ 'sender_acl_addresses' ][ 'ro' ]
);
// Get sender_acl items from POST array
2018-08-04 02:31:33 +08:00
// Set sender_acl_domain_admin to empty array if sender_acl contains "default" to trigger a reset
// Delete records from sender_acl if sender_acl contains "*" and set to array("*")
$_data [ 'sender_acl' ] = ( array ) $_data [ 'sender_acl' ];
if ( in_array ( " * " , $_data [ 'sender_acl' ])) {
$sender_acl_domain_admin = array ( '*' );
}
elseif ( array ( " default " ) === $_data [ 'sender_acl' ]) {
$sender_acl_domain_admin = array ();
}
else {
if ( array_search ( 'default' , $_data [ 'sender_acl' ]) !== false ){
2018-08-14 05:20:40 +08:00
unset ( $_data [ 'sender_acl' ][ array_search ( 'default' , $_data [ 'sender_acl' ])]);
2018-08-04 02:31:33 +08:00
}
$sender_acl_domain_admin = $_data [ 'sender_acl' ];
}
2017-05-23 15:36:59 +08:00
if ( ! empty ( $sender_acl_domain_admin ) || ! empty ( $sender_acl_admin )) {
2017-07-16 17:03:28 +08:00
// Check items in POST array and skip invalid
foreach ( $sender_acl_domain_admin as $key => $val ) {
2018-08-04 02:31:33 +08:00
// Check for invalid domain or email format or not *
if ( ! filter_var ( $val , FILTER_VALIDATE_EMAIL ) && ! is_valid_domain_name ( ltrim ( $val , '@' )) && $val != '*' ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'sender_acl_invalid' , $sender_acl_domain_admin [ $key ])
);
2017-07-16 17:03:28 +08:00
unset ( $sender_acl_domain_admin [ $key ]);
2018-08-04 02:31:33 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-04 02:31:33 +08:00
// Check if user has domain access (if object is domain)
2018-08-14 05:20:40 +08:00
$domain = ltrim ( $sender_acl_domain_admin [ $key ], '@' );
2018-08-04 02:31:33 +08:00
if ( is_valid_domain_name ( $domain )) {
// Check for- and skip non-mailcow domains
$domains = array_merge ( mailbox ( 'get' , 'domains' ), mailbox ( 'get' , 'alias_domains' ));
if ( ! empty ( $domains )) {
if ( ! in_array ( $domain , $domains )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'sender_acl_invalid' , $sender_acl_domain_admin [ $key ])
);
2018-08-04 02:31:33 +08:00
unset ( $sender_acl_domain_admin [ $key ]);
continue ;
}
}
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'sender_acl_invalid' , $sender_acl_domain_admin [ $key ])
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
unset ( $sender_acl_domain_admin [ $key ]);
continue ;
2017-05-23 15:36:59 +08:00
}
}
2018-08-04 02:31:33 +08:00
// Wildcard can only be used if role == admin
if ( $val == '*' && $_SESSION [ 'mailcow_cc_role' ] != 'admin' ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2018-08-04 02:31:33 +08:00
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'sender_acl_invalid' , $sender_acl_domain_admin [ $key ])
2018-08-04 02:31:33 +08:00
);
2018-08-14 05:20:40 +08:00
unset ( $sender_acl_domain_admin [ $key ]);
continue ;
2018-08-04 02:31:33 +08:00
}
2019-05-26 14:29:10 +08:00
// Check if user has alias access (if object is email)
2017-07-16 17:03:28 +08:00
if ( filter_var ( $val , FILTER_VALIDATE_EMAIL )) {
2019-05-26 14:29:10 +08:00
if ( ! hasAliasObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $val )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'sender_acl_invalid' , $sender_acl_domain_admin [ $key ])
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
unset ( $sender_acl_domain_admin [ $key ]);
continue ;
2017-05-23 15:36:59 +08:00
}
}
}
// Merge both arrays
$sender_acl_merged = array_merge ( $sender_acl_domain_admin , $sender_acl_admin );
2018-08-04 02:31:33 +08:00
// If merged array still contains "*", set it as only value
! in_array ( '*' , $sender_acl_merged ) ? : $sender_acl_merged = array ( '*' );
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `external` = 0 AND `logged_in_as` = :username " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':username' => $username
));
2019-05-26 15:22:06 +08:00
$fixed_sender_aliases = mailbox ( 'get' , 'sender_acl_handles' , $username )[ 'fixed_sender_aliases' ];
2017-05-23 15:36:59 +08:00
foreach ( $sender_acl_merged as $sender_acl ) {
$domain = ltrim ( $sender_acl , '@' );
if ( is_valid_domain_name ( $domain )) {
$sender_acl = '@' . $domain ;
}
2019-05-26 15:22:06 +08:00
// Don't add if allowed by alias
if ( in_array ( $sender_acl , $fixed_sender_aliases )) {
continue ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " INSERT INTO `sender_acl` (`send_as`, `logged_in_as`)
VALUES ( : sender_acl , : username ) " );
2017-05-23 15:36:59 +08:00
$stmt -> execute ( array (
2018-08-14 05:20:40 +08:00
':sender_acl' => $sender_acl ,
2017-05-23 15:36:59 +08:00
':username' => $username
));
}
2018-08-14 05:20:40 +08:00
}
else {
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `external` = 0 AND `logged_in_as` = :username " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':username' => $username
));
2017-05-23 15:36:59 +08:00
}
}
2021-04-14 03:34:47 +08:00
if ( ! empty ( $password )) {
if ( password_check ( $password , $password2 ) !== true ) {
continue ;
}
// support pre hashed passwords
if ( preg_match ( '/^{(ARGON2I|ARGON2ID|BLF-CRYPT|CLEAR|CLEARTEXT|CRYPT|DES-CRYPT|LDAP-MD5|MD5|MD5-CRYPT|PBKDF2|PLAIN|PLAIN-MD4|PLAIN-MD5|PLAIN-TRUNC|PLAIN-TRUNC|SHA|SHA1|SHA256|SHA256-CRYPT|SHA512|SHA512-CRYPT|SMD5|SSHA|SSHA256|SSHA512)}/i' , $password )) {
$password_hashed = $password ;
}
else {
$password_hashed = hash_password ( $password );
}
$stmt = $pdo -> prepare ( " UPDATE `mailbox` SET
`password` = : password_hashed
WHERE `username` = : username " );
$stmt -> execute ( array (
':password_hashed' => $password_hashed ,
':username' => $username
));
2021-04-09 19:46:17 +08:00
}
2020-06-06 07:12:31 +08:00
// We could either set alias = 1 if alias = 2 or tune the Postfix alias table (that's what we did, TODO: to it the other way)
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `alias` SET
`active` = : active
WHERE `address` = : address " );
$stmt -> execute ( array (
':address' => $username ,
':active' => $active
));
$stmt = $pdo -> prepare ( " UPDATE `mailbox` SET
`active` = : active ,
`name` = : name ,
`quota` = : quota_b ,
2018-10-24 03:14:57 +08:00
`attributes` = JSON_SET ( `attributes` , '$.force_pw_update' , : force_pw_update ),
2020-09-18 01:49:15 +08:00
`attributes` = JSON_SET ( `attributes` , '$.sogo_access' , : sogo_access ),
`attributes` = JSON_SET ( `attributes` , '$.imap_access' , : imap_access ),
`attributes` = JSON_SET ( `attributes` , '$.pop3_access' , : pop3_access ),
2021-02-11 16:34:21 +08:00
`attributes` = JSON_SET ( `attributes` , '$.xmpp_admin' , : xmpp_admin ),
`attributes` = JSON_SET ( `attributes` , '$.xmpp_access' , : xmpp_access ),
2020-09-18 01:49:15 +08:00
`attributes` = JSON_SET ( `attributes` , '$.smtp_access' , : smtp_access )
2018-08-14 05:20:40 +08:00
WHERE `username` = : username " );
$stmt -> execute ( array (
':active' => $active ,
':name' => $name ,
':quota_b' => $quota_b ,
':force_pw_update' => $force_pw_update ,
2018-10-24 03:14:57 +08:00
':sogo_access' => $sogo_access ,
2020-09-18 01:49:15 +08:00
':imap_access' => $imap_access ,
':pop3_access' => $pop3_access ,
':smtp_access' => $smtp_access ,
2021-02-11 16:34:21 +08:00
':xmpp_admin' => $xmpp_admin ,
':xmpp_access' => $xmpp_access ,
2018-08-14 05:20:40 +08:00
':username' => $username
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , $username )
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'resource' :
if ( ! is_array ( $_data [ 'name' ])) {
$names = array ();
$names [] = $_data [ 'name' ];
}
else {
$names = $_data [ 'name' ];
}
foreach ( $names as $name ) {
$is_now = mailbox ( 'get' , 'resource_details' , $name );
if ( ! empty ( $is_now )) {
2020-09-18 01:49:15 +08:00
$active = ( isset ( $_data [ 'active' ])) ? intval ( $_data [ 'active' ]) : $is_now [ 'active' ];
2018-05-07 03:51:00 +08:00
$multiple_bookings = ( isset ( $_data [ 'multiple_bookings' ])) ? intval ( $_data [ 'multiple_bookings' ]) : $is_now [ 'multiple_bookings' ];
2017-05-23 15:36:59 +08:00
$description = ( ! empty ( $_data [ 'description' ])) ? $_data [ 'description' ] : $is_now [ 'description' ];
$kind = ( ! empty ( $_data [ 'kind' ])) ? $_data [ 'kind' ] : $is_now [ 'kind' ];
}
else {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'resource_invalid' , htmlspecialchars ( $name ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! filter_var ( $name , FILTER_VALIDATE_EMAIL )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'resource_invalid' , htmlspecialchars ( $name ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-05-07 03:51:00 +08:00
if ( ! isset ( $multiple_bookings ) || $multiple_bookings < - 1 ) {
$multiple_bookings = - 1 ;
}
2017-05-23 15:36:59 +08:00
if ( empty ( $description )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'description_invalid' , htmlspecialchars ( $name ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( $kind != 'location' && $kind != 'group' && $kind != 'thing' ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => array ( 'resource_invalid' , htmlspecialchars ( $name ))
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $name )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " UPDATE `mailbox` SET
`active` = : active ,
`name` = : description ,
`kind` = : kind ,
`multiple_bookings` = : multiple_bookings
WHERE `username` = : name " );
$stmt -> execute ( array (
':active' => $active ,
':description' => $description ,
':multiple_bookings' => $multiple_bookings ,
':kind' => $kind ,
':name' => $name
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'resource_modified' , htmlspecialchars ( $name ))
);
2017-05-23 15:36:59 +08:00
}
break ;
}
break ;
case 'get' :
switch ( $_type ) {
case 'sender_acl_handles' :
if ( $_SESSION [ 'mailcow_cc_role' ] != " admin " && $_SESSION [ 'mailcow_cc_role' ] != " domainadmin " ) {
return false ;
}
$data [ 'sender_acl_domains' ][ 'ro' ] = array ();
$data [ 'sender_acl_domains' ][ 'rw' ] = array ();
$data [ 'sender_acl_domains' ][ 'selectable' ] = array ();
$data [ 'sender_acl_addresses' ][ 'ro' ] = array ();
$data [ 'sender_acl_addresses' ][ 'rw' ] = array ();
$data [ 'sender_acl_addresses' ][ 'selectable' ] = array ();
$data [ 'fixed_sender_aliases' ] = array ();
2019-09-02 17:11:41 +08:00
$data [ 'external_sender_aliases' ] = array ();
2018-08-14 05:20:40 +08:00
// Fixed addresses
$stmt = $pdo -> prepare ( " SELECT `address` FROM `alias` WHERE `goto` REGEXP :goto AND `address` NOT LIKE '@%' " );
$stmt -> execute ( array ( ':goto' => '(^|,)' . $_data . '($|,)' ));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$data [ 'fixed_sender_aliases' ][] = $row [ 'address' ];
}
$stmt = $pdo -> prepare ( " SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `alias_domain_alias` FROM `mailbox`, `alias_domain`
WHERE `alias_domain` . `target_domain` = `mailbox` . `domain`
AND `mailbox` . `username` = : username " );
$stmt -> execute ( array ( ':username' => $_data ));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
if ( ! empty ( $row [ 'alias_domain_alias' ])) {
$data [ 'fixed_sender_aliases' ][] = $row [ 'alias_domain_alias' ];
}
}
2019-09-02 17:11:41 +08:00
// External addresses
$stmt = $pdo -> prepare ( " SELECT `send_as` as `send_as_external` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `external` = '1' " );
$stmt -> execute ( array ( ':logged_in_as' => $_data ));
$exernal_rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $exernal_rows )) {
if ( ! empty ( $row [ 'send_as_external' ])) {
$data [ 'external_sender_aliases' ][] = $row [ 'send_as_external' ];
}
}
2018-08-14 05:20:40 +08:00
// Return array $data['sender_acl_domains/addresses']['ro'] with read-only objects
// Return array $data['sender_acl_domains/addresses']['rw'] with read-write objects (can be deleted)
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " SELECT REPLACE(`send_as`, '@', '') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `external` = '0' AND (`send_as` LIKE '@%' OR `send_as` = '*') " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array ( ':logged_in_as' => $_data ));
$domain_rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $domain_row = array_shift ( $domain_rows )) {
if ( is_valid_domain_name ( $domain_row [ 'send_as' ]) && ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain_row [ 'send_as' ])) {
$data [ 'sender_acl_domains' ][ 'ro' ][] = $domain_row [ 'send_as' ];
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
if ( is_valid_domain_name ( $domain_row [ 'send_as' ]) && hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $domain_row [ 'send_as' ])) {
$data [ 'sender_acl_domains' ][ 'rw' ][] = $domain_row [ 'send_as' ];
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
if ( $domain_row [ 'send_as' ] == '*' && $_SESSION [ 'mailcow_cc_role' ] != 'admin' ) {
$data [ 'sender_acl_domains' ][ 'ro' ][] = $domain_row [ 'send_as' ];
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
if ( $domain_row [ 'send_as' ] == '*' && $_SESSION [ 'mailcow_cc_role' ] == 'admin' ) {
$data [ 'sender_acl_domains' ][ 'rw' ][] = $domain_row [ 'send_as' ];
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
}
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `external` = '0' AND (`send_as` NOT LIKE '@%' AND `send_as` != '*') " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array ( ':logged_in_as' => $_data ));
$address_rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $address_row = array_shift ( $address_rows )) {
2019-05-26 14:29:10 +08:00
if ( filter_var ( $address_row [ 'send_as' ], FILTER_VALIDATE_EMAIL ) && ! hasAliasObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $address_row [ 'send_as' ])) {
2018-08-14 05:20:40 +08:00
$data [ 'sender_acl_addresses' ][ 'ro' ][] = $address_row [ 'send_as' ];
continue ;
2017-05-23 15:36:59 +08:00
}
2019-05-26 14:29:10 +08:00
if ( filter_var ( $address_row [ 'send_as' ], FILTER_VALIDATE_EMAIL ) && hasAliasObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $address_row [ 'send_as' ])) {
2018-08-14 05:20:40 +08:00
$data [ 'sender_acl_addresses' ][ 'rw' ][] = $address_row [ 'send_as' ];
continue ;
2017-05-23 15:36:59 +08:00
}
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain`
WHERE `domain` NOT IN (
2019-11-11 16:55:15 +08:00
SELECT REPLACE ( `send_as` , '@' , '' ) FROM `sender_acl`
2018-08-14 05:20:40 +08:00
WHERE `logged_in_as` = : logged_in_as1
2019-09-02 17:11:41 +08:00
AND `external` = '0'
2018-08-14 05:20:40 +08:00
AND `send_as` LIKE '@%' )
UNION
SELECT '*' FROM `domain`
WHERE '*' NOT IN (
2019-11-11 16:55:15 +08:00
SELECT `send_as` FROM `sender_acl`
2018-08-14 05:20:40 +08:00
WHERE `logged_in_as` = : logged_in_as2
2019-09-02 17:11:41 +08:00
AND `external` = '0'
2018-08-14 05:20:40 +08:00
) " );
$stmt -> execute ( array (
':logged_in_as1' => $_data ,
':logged_in_as2' => $_data
));
$rows_domain = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row_domain = array_shift ( $rows_domain )) {
if ( is_valid_domain_name ( $row_domain [ 'domain' ]) && hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $row_domain [ 'domain' ])) {
$data [ 'sender_acl_domains' ][ 'selectable' ][] = $row_domain [ 'domain' ];
continue ;
}
if ( $row_domain [ 'domain' ] == '*' && $_SESSION [ 'mailcow_cc_role' ] == 'admin' ) {
$data [ 'sender_acl_domains' ][ 'selectable' ][] = $row_domain [ 'domain' ];
continue ;
}
}
$stmt = $pdo -> prepare ( " SELECT `address` FROM `alias`
WHERE `goto` != : goto
AND `address` NOT IN (
2019-11-11 16:55:15 +08:00
SELECT `send_as` FROM `sender_acl`
2018-08-14 05:20:40 +08:00
WHERE `logged_in_as` = : logged_in_as
2019-09-02 17:11:41 +08:00
AND `external` = '0'
2018-08-14 05:20:40 +08:00
AND `send_as` NOT LIKE '@%' ) " );
$stmt -> execute ( array (
':logged_in_as' => $_data ,
':goto' => $_data
));
$rows_mbox = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows_mbox )) {
2019-05-26 15:22:06 +08:00
// Aliases are not selectable
if ( in_array ( $row [ 'address' ], $data [ 'fixed_sender_aliases' ])) {
continue ;
}
2019-05-26 14:29:10 +08:00
if ( filter_var ( $row [ 'address' ], FILTER_VALIDATE_EMAIL ) && hasAliasObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $row [ 'address' ])) {
2018-08-14 05:20:40 +08:00
$data [ 'sender_acl_addresses' ][ 'selectable' ][] = $row [ 'address' ];
}
2017-05-23 15:36:59 +08:00
}
return $data ;
break ;
case 'mailboxes' :
$mailboxes = array ();
if ( isset ( $_data ) && ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
elseif ( isset ( $_data ) && hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
2021-03-19 23:33:50 +08:00
$stmt = $pdo -> prepare ( " SELECT `username` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':domain' => $_data ,
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$mailboxes [] = $row [ 'username' ];
2017-05-23 15:36:59 +08:00
}
}
else {
2021-03-19 23:33:50 +08:00
$stmt = $pdo -> prepare ( " SELECT `username` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND (`domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role) " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':username' => $_SESSION [ 'mailcow_cc_username' ],
':role' => $_SESSION [ 'mailcow_cc_role' ],
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$mailboxes [] = $row [ 'username' ];
2017-05-23 15:36:59 +08:00
}
}
return $mailboxes ;
break ;
case 'tls_policy' :
2018-02-17 18:12:16 +08:00
$attrs = array ();
2017-05-23 15:36:59 +08:00
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `attributes` FROM `mailbox` WHERE `username` = :username " );
$stmt -> execute ( array ( ':username' => $_data ));
$attrs = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2018-02-17 18:12:16 +08:00
$attrs = json_decode ( $attrs [ 'attributes' ], true );
return array (
'tls_enforce_in' => $attrs [ 'tls_enforce_in' ],
'tls_enforce_out' => $attrs [ 'tls_enforce_out' ]
);
2017-05-23 15:36:59 +08:00
break ;
2019-01-29 07:20:39 +08:00
case 'quarantine_notification' :
$attrs = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
$stmt = $pdo -> prepare ( " SELECT `attributes` FROM `mailbox` WHERE `username` = :username " );
$stmt -> execute ( array ( ':username' => $_data ));
$attrs = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$attrs = json_decode ( $attrs [ 'attributes' ], true );
return $attrs [ 'quarantine_notification' ];
break ;
2020-11-29 00:41:48 +08:00
case 'quarantine_category' :
$attrs = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
$stmt = $pdo -> prepare ( " SELECT `attributes` FROM `mailbox` WHERE `username` = :username " );
$stmt -> execute ( array ( ':username' => $_data ));
$attrs = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$attrs = json_decode ( $attrs [ 'attributes' ], true );
return $attrs [ 'quarantine_category' ];
break ;
2017-11-04 03:37:24 +08:00
case 'filters' :
$filters = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `id` FROM `sieve_filters` WHERE `username` = :username " );
$stmt -> execute ( array ( ':username' => $_data ));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$filters [] = $row [ 'id' ];
2017-11-04 03:37:24 +08:00
}
return $filters ;
break ;
2020-03-19 19:23:48 +08:00
case 'global_filter_details' :
$global_filters = array ();
if ( $_SESSION [ 'mailcow_cc_role' ] != " admin " ) {
return false ;
}
$global_filters [ 'prefilter' ] = file_get_contents ( '/global_sieve/before' );
$global_filters [ 'postfilter' ] = file_get_contents ( '/global_sieve/after' );
return $global_filters ;
break ;
2017-11-04 03:37:24 +08:00
case 'filter_details' :
$filter_details = array ();
if ( ! is_numeric ( $_data )) {
return false ;
}
2020-09-18 01:49:15 +08:00
$stmt = $pdo -> prepare ( " SELECT CASE `script_name` WHEN 'active' THEN 1 ELSE 0 END AS `active`,
2018-08-14 05:20:40 +08:00
id ,
username ,
filter_type ,
script_data ,
script_desc
FROM `sieve_filters`
WHERE `id` = : id " );
$stmt -> execute ( array ( ':id' => $_data ));
$filter_details = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2017-11-04 03:37:24 +08:00
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $filter_details [ 'username' ])) {
return false ;
}
return $filter_details ;
break ;
case 'active_user_sieve' :
$filter_details = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
$exec_fields = array (
2018-10-24 03:14:57 +08:00
'cmd' => 'sieve' ,
'task' => 'list' ,
2017-11-04 03:37:24 +08:00
'username' => $_data
);
2018-10-24 03:14:57 +08:00
$filters = docker ( 'post' , 'dovecot-mailcow' , 'exec' , $exec_fields );
$filters = array_filter ( preg_split ( " /( \r \n | \n | \r )/ " , $filters ));
2017-11-04 03:37:24 +08:00
foreach ( $filters as $filter ) {
if ( preg_match ( '/.+ ACTIVE/i' , $filter )) {
$exec_fields = array (
2018-10-24 03:14:57 +08:00
'cmd' => 'sieve' ,
'task' => 'print' ,
2017-11-04 03:37:24 +08:00
'script_name' => substr ( $filter , 0 , - 7 ),
'username' => $_data
);
2018-10-24 03:14:57 +08:00
$script = docker ( 'post' , 'dovecot-mailcow' , 'exec' , $exec_fields );
// Remove first line
return preg_replace ( '/^.+\n/' , '' , $script );
2017-11-04 03:37:24 +08:00
}
}
return false ;
break ;
2017-05-23 15:36:59 +08:00
case 'syncjob_details' :
$syncjobdetails = array ();
if ( ! is_numeric ( $_data )) {
return false ;
}
2018-08-14 05:20:40 +08:00
if ( isset ( $_extra ) && in_array ( 'no_log' , $_extra )) {
$field_query = $pdo -> query ( 'SHOW FIELDS FROM `imapsync` WHERE FIELD NOT IN ("returned_text", "password1")' );
$fields = $field_query -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $field = array_shift ( $fields )) {
$shown_fields [] = $field [ 'Field' ];
2017-11-04 03:37:24 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT " . implode ( ',' , $shown_fields ) . " ,
2020-09-18 01:49:15 +08:00
`active`
2018-08-14 05:20:40 +08:00
FROM `imapsync` WHERE id = : id " );
}
elseif ( isset ( $_extra ) && in_array ( 'with_password' , $_extra )) {
$stmt = $pdo -> prepare ( " SELECT *,
2020-09-18 01:49:15 +08:00
`active`
2018-08-14 05:20:40 +08:00
FROM `imapsync` WHERE id = : id " );
}
else {
$field_query = $pdo -> query ( 'SHOW FIELDS FROM `imapsync` WHERE FIELD NOT IN ("password1")' );
$fields = $field_query -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $field = array_shift ( $fields )) {
$shown_fields [] = $field [ 'Field' ];
2017-11-04 03:37:24 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT " . implode ( ',' , $shown_fields ) . " ,
2020-09-18 01:49:15 +08:00
`active`
2018-08-14 05:20:40 +08:00
FROM `imapsync` WHERE id = : id " );
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array ( ':id' => $_data ));
$syncjobdetails = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( ! empty ( $syncjobdetails [ 'returned_text' ])) {
$syncjobdetails [ 'log' ] = $syncjobdetails [ 'returned_text' ];
}
else {
$syncjobdetails [ 'log' ] = '' ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
unset ( $syncjobdetails [ 'returned_text' ]);
2017-05-23 15:36:59 +08:00
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $syncjobdetails [ 'user2' ])) {
return false ;
}
return $syncjobdetails ;
break ;
case 'syncjobs' :
$syncjobdata = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `id` FROM `imapsync` WHERE `user2` = :username " );
$stmt -> execute ( array ( ':username' => $_data ));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$syncjobdata [] = $row [ 'id' ];
2017-05-23 15:36:59 +08:00
}
return $syncjobdata ;
break ;
case 'spam_score' :
2018-10-19 03:48:30 +08:00
$curl = curl_init ();
curl_setopt ( $curl , CURLOPT_UNIX_SOCKET_PATH , '/var/lib/rspamd/rspamd.sock' );
curl_setopt ( $curl , CURLOPT_URL , " http://rspamd/actions " );
curl_setopt ( $curl , CURLOPT_RETURNTRANSFER , true );
$default_actions = curl_exec ( $curl );
if ( ! curl_errno ( $curl )) {
$data_array = json_decode ( $default_actions , true );
curl_close ( $curl );
foreach ( $data_array as $data ) {
if ( $data [ 'action' ] == 'reject' ) {
$reject = $data [ 'value' ];
continue ;
}
elseif ( $data [ 'action' ] == 'add header' ) {
$add_header = $data [ 'value' ];
continue ;
}
}
if ( empty ( $add_header ) || empty ( $reject )) {
// Assume default, set warning
$default = " 5, 15 " ;
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'Could not determine servers default spam score, assuming default'
);
}
else {
$default = $add_header . ', ' . $reject ;
}
}
else {
// Assume default, set warning
$default = " 5, 15 " ;
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'Could not determine servers default spam score, assuming default'
);
}
curl_close ( $curl );
2017-05-23 15:36:59 +08:00
$policydata = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `value` FROM `filterconf` WHERE `object` = :username AND
( `option` = 'lowspamlevel' OR `option` = 'highspamlevel' ) " );
$stmt -> execute ( array ( ':username' => $_data ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
2017-05-23 15:36:59 +08:00
if ( empty ( $num_results )) {
return $default ;
}
else {
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `value` FROM `filterconf` WHERE `option` = 'highspamlevel' AND `object` = :username " );
$stmt -> execute ( array ( ':username' => $_data ));
$highspamlevel = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$stmt = $pdo -> prepare ( " SELECT `value` FROM `filterconf` WHERE `option` = 'lowspamlevel' AND `object` = :username " );
$stmt -> execute ( array ( ':username' => $_data ));
$lowspamlevel = $stmt -> fetch ( PDO :: FETCH_ASSOC );
return $lowspamlevel [ 'value' ] . ', ' . $highspamlevel [ 'value' ];
2017-05-23 15:36:59 +08:00
}
break ;
case 'time_limited_aliases' :
$tladata = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `address`,
`goto` ,
2021-05-21 18:48:19 +08:00
`validity` ,
`created` ,
`modified`
2018-08-14 05:20:40 +08:00
FROM `spamalias`
WHERE `goto` = : username
AND `validity` >= : unixnow " );
$stmt -> execute ( array ( ':username' => $_data , ':unixnow' => time ()));
$tladata = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
2017-05-23 15:36:59 +08:00
return $tladata ;
break ;
case 'delimiter_action' :
$policydata = array ();
if ( isset ( $_data ) && filter_var ( $_data , FILTER_VALIDATE_EMAIL )) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
}
else {
$_data = $_SESSION [ 'mailcow_cc_username' ];
}
try {
if ( $redis -> hGet ( 'RCPT_WANTS_SUBJECT_TAG' , $_data )) {
return " subject " ;
}
2018-01-16 23:31:37 +08:00
elseif ( $redis -> hGet ( 'RCPT_WANTS_SUBFOLDER_TAG' , $_data )) {
2017-05-23 15:36:59 +08:00
return " subfolder " ;
}
2018-01-16 19:47:59 +08:00
else {
return " none " ;
}
2017-05-23 15:36:59 +08:00
}
catch ( RedisException $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
2017-05-23 15:36:59 +08:00
);
return false ;
}
break ;
case 'resources' :
$resources = array ();
if ( isset ( $_data ) && ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
elseif ( isset ( $_data ) && hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
2018-10-11 17:59:23 +08:00
$stmt = $pdo -> prepare ( " SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `domain` = :domain " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':domain' => $_data ,
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$resources [] = $row [ 'username' ];
2017-05-23 15:36:59 +08:00
}
}
else {
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role " );
$stmt -> execute ( array (
':username' => $_SESSION [ 'mailcow_cc_username' ],
':role' => $_SESSION [ 'mailcow_cc_role' ],
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$resources [] = $row [ 'username' ];
2017-05-23 15:36:59 +08:00
}
}
return $resources ;
break ;
case 'alias_domains' :
$aliasdomains = array ();
if ( isset ( $_data ) && ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
elseif ( isset ( $_data ) && hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain " );
$stmt -> execute ( array (
':domain' => $_data ,
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$aliasdomains [] = $row [ 'alias_domain' ];
2017-05-23 15:36:59 +08:00
}
}
else {
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role " );
$stmt -> execute ( array (
':username' => $_SESSION [ 'mailcow_cc_username' ],
':role' => $_SESSION [ 'mailcow_cc_role' ],
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$aliasdomains [] = $row [ 'alias_domain' ];
2017-05-23 15:36:59 +08:00
}
}
return $aliasdomains ;
break ;
case 'aliases' :
$aliases = array ();
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `id` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain " );
$stmt -> execute ( array (
':domain' => $_data ,
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$aliases [] = $row [ 'id' ];
2017-05-23 15:36:59 +08:00
}
return $aliases ;
break ;
case 'alias_details' :
$aliasdata = array ();
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT
`id` ,
`domain` ,
`goto` ,
`address` ,
2019-01-29 07:20:39 +08:00
`public_comment` ,
`private_comment` ,
2020-09-18 01:49:15 +08:00
`active` ,
`sogo_visible` ,
2018-08-14 05:20:40 +08:00
`created` ,
`modified`
FROM `alias`
2020-05-25 22:20:59 +08:00
WHERE ( `id` = : id OR `address` = : address ) AND `address` != `goto` " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
2020-05-25 22:20:59 +08:00
':id' => $_data ,
':address' => $_data ,
2018-08-14 05:20:40 +08:00
));
$row = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$stmt = $pdo -> prepare ( " SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain " );
$stmt -> execute ( array (
':domain' => $row [ 'domain' ],
));
$row_alias_domain = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( isset ( $row_alias_domain [ 'target_domain' ]) && ! empty ( $row_alias_domain [ 'target_domain' ])) {
$aliasdata [ 'in_primary_domain' ] = $row_alias_domain [ 'target_domain' ];
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
else {
$aliasdata [ 'in_primary_domain' ] = " " ;
}
$aliasdata [ 'id' ] = $row [ 'id' ];
$aliasdata [ 'domain' ] = $row [ 'domain' ];
2019-01-29 07:20:39 +08:00
$aliasdata [ 'public_comment' ] = $row [ 'public_comment' ];
$aliasdata [ 'private_comment' ] = $row [ 'private_comment' ];
$aliasdata [ 'domain' ] = $row [ 'domain' ];
2018-08-14 05:20:40 +08:00
$aliasdata [ 'goto' ] = $row [ 'goto' ];
$aliasdata [ 'address' ] = $row [ 'address' ];
( ! filter_var ( $aliasdata [ 'address' ], FILTER_VALIDATE_EMAIL )) ? $aliasdata [ 'is_catch_all' ] = 1 : $aliasdata [ 'is_catch_all' ] = 0 ;
$aliasdata [ 'active' ] = $row [ 'active' ];
2020-09-27 04:04:55 +08:00
$aliasdata [ 'active_int' ] = $row [ 'active' ];
2019-09-22 21:10:56 +08:00
$aliasdata [ 'sogo_visible' ] = $row [ 'sogo_visible' ];
2020-09-27 04:04:55 +08:00
$aliasdata [ 'sogo_visible_int' ] = $row [ 'sogo_visible' ];
2018-08-14 05:20:40 +08:00
$aliasdata [ 'created' ] = $row [ 'created' ];
$aliasdata [ 'modified' ] = $row [ 'modified' ];
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $aliasdata [ 'domain' ])) {
2017-05-23 15:36:59 +08:00
return false ;
}
return $aliasdata ;
break ;
case 'alias_domain_details' :
$aliasdomaindata = array ();
2018-08-21 23:41:04 +08:00
$rl = ratelimit ( 'get' , 'domain' , $_data );
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT
`alias_domain` ,
`target_domain` ,
2020-09-18 01:49:15 +08:00
`active` ,
2018-08-14 05:20:40 +08:00
`created` ,
`modified`
FROM `alias_domain`
WHERE `alias_domain` = : aliasdomain " );
$stmt -> execute ( array (
':aliasdomain' => $_data ,
));
$row = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2019-09-02 17:11:41 +08:00
$stmt = $pdo -> prepare ( " SELECT `backupmx` FROM `domain` WHERE `domain` = :target_domain " );
$stmt -> execute ( array (
':target_domain' => $row [ 'target_domain' ]
));
$row_parent = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2018-08-14 05:20:40 +08:00
$aliasdomaindata [ 'alias_domain' ] = $row [ 'alias_domain' ];
2019-09-02 17:11:41 +08:00
$aliasdomaindata [ 'parent_is_backupmx' ] = $row_parent [ 'backupmx' ];
2018-08-14 05:20:40 +08:00
$aliasdomaindata [ 'target_domain' ] = $row [ 'target_domain' ];
$aliasdomaindata [ 'active' ] = $row [ 'active' ];
2020-09-27 04:04:55 +08:00
$aliasdomaindata [ 'active_int' ] = $row [ 'active' ];
2018-08-21 23:41:04 +08:00
$aliasdomaindata [ 'rl' ] = $rl ;
2018-08-14 05:20:40 +08:00
$aliasdomaindata [ 'created' ] = $row [ 'created' ];
$aliasdomaindata [ 'modified' ] = $row [ 'modified' ];
2017-05-23 15:36:59 +08:00
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $aliasdomaindata [ 'target_domain' ])) {
return false ;
}
return $aliasdomaindata ;
break ;
case 'domains' :
$domains = array ();
if ( $_SESSION [ 'mailcow_cc_role' ] != " admin " && $_SESSION [ 'mailcow_cc_role' ] != " domainadmin " ) {
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `domain` FROM `domain`
WHERE ( `domain` IN (
SELECT `domain` from `domain_admins`
WHERE ( `active` = '1' AND `username` = : username ))
)
2018-10-11 17:59:23 +08:00
OR 'admin' = : role " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':username' => $_SESSION [ 'mailcow_cc_username' ],
':role' => $_SESSION [ 'mailcow_cc_role' ],
));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$domains [] = $row [ 'domain' ];
2017-05-23 15:36:59 +08:00
}
return $domains ;
break ;
case 'domain_details' :
$domaindata = array ();
2019-02-05 07:10:21 +08:00
$_data = idn_to_ascii ( strtolower ( trim ( $_data )), 0 , INTL_IDNA_VARIANT_UTS46 );
2017-05-23 15:36:59 +08:00
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain " );
$stmt -> execute ( array (
':domain' => $_data
));
$row = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( ! empty ( $row )) {
$_data = $row [ 'target_domain' ];
2017-05-23 15:36:59 +08:00
}
2019-11-11 16:55:15 +08:00
$stmt = $pdo -> prepare ( " SELECT
2018-08-14 05:20:40 +08:00
`domain` ,
`description` ,
`aliases` ,
2019-11-11 16:55:15 +08:00
`mailboxes` ,
2019-05-11 17:16:40 +08:00
`defquota` ,
2018-08-14 05:20:40 +08:00
`maxquota` ,
`quota` ,
`relayhost` ,
2020-09-18 01:49:15 +08:00
`relay_all_recipients` ,
`relay_unknown_only` ,
`backupmx` ,
`gal` ,
2021-02-11 16:34:21 +08:00
`xmpp` ,
`xmpp_prefix` ,
2020-09-18 01:49:15 +08:00
`active`
2018-08-14 05:20:40 +08:00
FROM `domain` WHERE `domain` = : domain " );
$stmt -> execute ( array (
':domain' => $_data
));
$row = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2019-11-11 16:55:15 +08:00
if ( empty ( $row )) {
2018-08-14 05:20:40 +08:00
return false ;
}
2021-03-19 23:33:50 +08:00
$stmt = $pdo -> prepare ( " SELECT COUNT(`username`) AS `count`,
2018-08-14 05:20:40 +08:00
COALESCE ( SUM ( `quota` ), 0 ) AS `in_use`
FROM `mailbox`
2021-03-19 23:33:50 +08:00
WHERE ( `kind` = '' OR `kind` = NULL )
2018-08-14 05:20:40 +08:00
AND `domain` = : domain " );
$stmt -> execute ( array ( ':domain' => $row [ 'domain' ]));
2020-04-05 17:35:35 +08:00
$MailboxDataDomain = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$stmt = $pdo -> prepare ( " SELECT SUM(bytes) AS `bytes_total`, SUM(messages) AS `msgs_total` FROM `quota2`
WHERE `username` IN (
SELECT `username` FROM `mailbox`
WHERE `domain` = : domain
); " );
$stmt -> execute ( array ( ':domain' => $row [ 'domain' ]));
$SumQuotaInUse = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2018-08-21 23:41:04 +08:00
$rl = ratelimit ( 'get' , 'domain' , $_data );
2018-08-14 05:20:40 +08:00
$domaindata [ 'max_new_mailbox_quota' ] = ( $row [ 'quota' ] * 1048576 ) - $MailboxDataDomain [ 'in_use' ];
if ( $domaindata [ 'max_new_mailbox_quota' ] > ( $row [ 'maxquota' ] * 1048576 )) {
$domaindata [ 'max_new_mailbox_quota' ] = ( $row [ 'maxquota' ] * 1048576 );
}
2019-05-11 17:16:40 +08:00
$domaindata [ 'def_new_mailbox_quota' ] = $domaindata [ 'max_new_mailbox_quota' ];
if ( $domaindata [ 'def_new_mailbox_quota' ] > ( $row [ 'defquota' ] * 1048576 )) {
$domaindata [ 'def_new_mailbox_quota' ] = ( $row [ 'defquota' ] * 1048576 );
}
2018-08-14 05:20:40 +08:00
$domaindata [ 'quota_used_in_domain' ] = $MailboxDataDomain [ 'in_use' ];
2020-04-06 14:52:27 +08:00
if ( ! empty ( $SumQuotaInUse [ 'bytes_total' ])) {
$domaindata [ 'bytes_total' ] = $SumQuotaInUse [ 'bytes_total' ];
}
else {
$domaindata [ 'bytes_total' ] = 0 ;
}
if ( ! empty ( $SumQuotaInUse [ 'msgs_total' ])) {
$domaindata [ 'msgs_total' ] = $SumQuotaInUse [ 'msgs_total' ];
}
else {
$domaindata [ 'msgs_total' ] = 0 ;
}
2018-08-14 05:20:40 +08:00
$domaindata [ 'mboxes_in_domain' ] = $MailboxDataDomain [ 'count' ];
$domaindata [ 'mboxes_left' ] = $row [ 'mailboxes' ] - $MailboxDataDomain [ 'count' ];
$domaindata [ 'domain_name' ] = $row [ 'domain' ];
$domaindata [ 'description' ] = $row [ 'description' ];
$domaindata [ 'max_num_aliases_for_domain' ] = $row [ 'aliases' ];
$domaindata [ 'max_num_mboxes_for_domain' ] = $row [ 'mailboxes' ];
2019-05-11 17:16:40 +08:00
$domaindata [ 'def_quota_for_mbox' ] = $row [ 'defquota' ] * 1048576 ;
2018-08-14 05:20:40 +08:00
$domaindata [ 'max_quota_for_mbox' ] = $row [ 'maxquota' ] * 1048576 ;
$domaindata [ 'max_quota_for_domain' ] = $row [ 'quota' ] * 1048576 ;
$domaindata [ 'relayhost' ] = $row [ 'relayhost' ];
$domaindata [ 'backupmx' ] = $row [ 'backupmx' ];
2020-09-27 04:04:55 +08:00
$domaindata [ 'backupmx_int' ] = $row [ 'backupmx' ];
2019-01-17 06:41:02 +08:00
$domaindata [ 'gal' ] = $row [ 'gal' ];
2021-02-11 16:34:21 +08:00
$domaindata [ 'xmpp' ] = $row [ 'xmpp' ];
$domaindata [ 'xmpp_prefix' ] = $row [ 'xmpp_prefix' ];
2020-09-27 04:04:55 +08:00
$domaindata [ 'gal_int' ] = $row [ 'gal' ];
2018-08-21 23:41:04 +08:00
$domaindata [ 'rl' ] = $rl ;
2018-08-14 05:20:40 +08:00
$domaindata [ 'active' ] = $row [ 'active' ];
2020-09-27 04:04:55 +08:00
$domaindata [ 'active_int' ] = $row [ 'active' ];
2018-08-14 05:20:40 +08:00
$domaindata [ 'relay_all_recipients' ] = $row [ 'relay_all_recipients' ];
2020-09-27 04:04:55 +08:00
$domaindata [ 'relay_all_recipients_int' ] = $row [ 'relay_all_recipients' ];
2020-04-04 02:39:53 +08:00
$domaindata [ 'relay_unknown_only' ] = $row [ 'relay_unknown_only' ];
2020-09-27 04:04:55 +08:00
$domaindata [ 'relay_unknown_only_int' ] = $row [ 'relay_unknown_only' ];
2021-03-19 23:33:50 +08:00
$stmt = $pdo -> prepare ( " SELECT COUNT(`address`) AS `alias_count` FROM `alias`
2018-08-14 05:20:40 +08:00
WHERE ( `domain` = : domain OR `domain` IN ( SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = : domain2 ))
AND `address` NOT IN (
SELECT `username` FROM `mailbox`
) " );
$stmt -> execute ( array (
':domain' => $_data ,
':domain2' => $_data
));
$AliasDataDomain = $stmt -> fetch ( PDO :: FETCH_ASSOC );
( isset ( $AliasDataDomain [ 'alias_count' ])) ? $domaindata [ 'aliases_in_domain' ] = $AliasDataDomain [ 'alias_count' ] : $domaindata [ 'aliases_in_domain' ] = " 0 " ;
$domaindata [ 'aliases_left' ] = $row [ 'aliases' ] - $AliasDataDomain [ 'alias_count' ];
2019-11-11 16:55:15 +08:00
if ( $_SESSION [ 'mailcow_cc_role' ] == " admin " )
{
$stmt = $pdo -> prepare ( " SELECT GROUP_CONCAT(`username` SEPARATOR ', ') AS domain_admins FROM `domain_admins` WHERE `domain` = :domain " );
$stmt -> execute ( array (
':domain' => $_data
));
$domain_admins = $stmt -> fetch ( PDO :: FETCH_ASSOC );
( isset ( $domain_admins [ 'domain_admins' ])) ? $domaindata [ 'domain_admins' ] = $domain_admins [ 'domain_admins' ] : $domaindata [ 'domain_admins' ] = " - " ;
}
2017-05-23 15:36:59 +08:00
return $domaindata ;
break ;
case 'mailbox_details' :
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
$mailboxdata = array ();
2020-04-14 02:34:39 +08:00
$last_imap_login = $redis -> Get ( 'last-login/imap/' . $_data );
2020-09-15 17:02:53 +08:00
$last_smtp_login = $redis -> Get ( 'last-login/smtp/' . $_data );
2020-04-14 02:34:39 +08:00
$last_pop3_login = $redis -> Get ( 'last-login/pop3/' . $_data );
if ( $last_imap_login === false || $GLOBALS [ 'SHOW_LAST_LOGIN' ] === false ) {
$last_imap_login = '0' ;
}
2020-09-15 17:02:53 +08:00
if ( $last_smtp_login === false || $GLOBALS [ 'SHOW_LAST_LOGIN' ] === false ) {
$last_smtp_login = '0' ;
}
2020-04-14 02:34:39 +08:00
if ( $last_pop3_login === false || $GLOBALS [ 'SHOW_LAST_LOGIN' ] === false ) {
$last_pop3_login = '0' ;
2020-02-26 02:38:20 +08:00
}
2020-03-31 16:03:40 +08:00
if ( preg_match ( '/y|yes/i' , getenv ( 'MASTER' ))) {
$stmt = $pdo -> prepare ( " SELECT
2018-08-14 05:20:40 +08:00
`domain` . `backupmx` ,
`mailbox` . `username` ,
`mailbox` . `name` ,
2020-09-18 01:49:15 +08:00
`mailbox` . `active` ,
2018-08-14 05:20:40 +08:00
`mailbox` . `domain` ,
2018-11-12 17:03:50 +08:00
`mailbox` . `local_part` ,
2018-08-14 05:20:40 +08:00
`mailbox` . `quota` ,
2021-02-11 16:34:21 +08:00
`domain` . `xmpp` AS `domain_xmpp` ,
`domain` . `xmpp_prefix` AS `domain_xmpp_prefix` ,
2018-08-14 05:20:40 +08:00
`quota2` . `bytes` ,
`attributes` ,
`quota2` . `messages`
FROM `mailbox` , `quota2` , `domain`
2021-03-19 23:33:50 +08:00
WHERE ( `mailbox` . `kind` = '' OR `mailbox` . `kind` = NULL )
AND `mailbox` . `username` = `quota2` . `username`
AND `domain` . `domain` = `mailbox` . `domain`
AND `mailbox` . `username` = : mailbox " );
2020-03-31 16:03:40 +08:00
}
else {
$stmt = $pdo -> prepare ( " SELECT
`domain` . `backupmx` ,
`mailbox` . `username` ,
`mailbox` . `name` ,
2020-09-18 01:49:15 +08:00
`mailbox` . `active` ,
2020-03-31 16:03:40 +08:00
`mailbox` . `domain` ,
`mailbox` . `local_part` ,
`mailbox` . `quota` ,
2021-02-11 16:34:21 +08:00
`domain` . `xmpp` AS `domain_xmpp` ,
`domain` . `xmpp_prefix` AS `domain_xmpp_prefix` ,
2020-03-31 16:03:40 +08:00
`quota2replica` . `bytes` ,
`attributes` ,
`quota2replica` . `messages`
FROM `mailbox` , `quota2replica` , `domain`
2021-03-19 23:33:50 +08:00
WHERE ( `mailbox` . `kind` = '' OR `mailbox` . `kind` = NULL )
AND `mailbox` . `username` = `quota2replica` . `username`
AND `domain` . `domain` = `mailbox` . `domain`
AND `mailbox` . `username` = : mailbox " );
2020-03-31 16:03:40 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':mailbox' => $_data ,
));
$row = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2021-03-19 23:33:50 +08:00
2018-08-14 05:20:40 +08:00
$mailboxdata [ 'username' ] = $row [ 'username' ];
$mailboxdata [ 'active' ] = $row [ 'active' ];
2020-09-27 04:04:55 +08:00
$mailboxdata [ 'active_int' ] = $row [ 'active' ];
2018-08-14 05:20:40 +08:00
$mailboxdata [ 'domain' ] = $row [ 'domain' ];
2021-02-11 16:34:21 +08:00
$mailboxdata [ 'domain_xmpp' ] = $row [ 'domain_xmpp' ];
2021-03-19 23:33:50 +08:00
$mailboxdata [ 'name' ] = $row [ 'name' ];
2021-02-11 16:34:21 +08:00
$mailboxdata [ 'domain_xmpp_prefix' ] = $row [ 'domain_xmpp_prefix' ];
2018-11-12 17:03:50 +08:00
$mailboxdata [ 'local_part' ] = $row [ 'local_part' ];
2018-08-14 05:20:40 +08:00
$mailboxdata [ 'quota' ] = $row [ 'quota' ];
2021-03-19 23:33:50 +08:00
$mailboxdata [ 'messages' ] = $row [ 'messages' ];
2018-08-14 05:20:40 +08:00
$mailboxdata [ 'attributes' ] = json_decode ( $row [ 'attributes' ], true );
$mailboxdata [ 'quota_used' ] = intval ( $row [ 'bytes' ]);
2019-03-29 05:05:12 +08:00
$mailboxdata [ 'percent_in_use' ] = ( $row [ 'quota' ] == 0 ) ? '- ' : round (( intval ( $row [ 'bytes' ]) / intval ( $row [ 'quota' ])) * 100 );
2021-03-19 23:33:50 +08:00
$mailboxdata [ 'last_imap_login' ] = $last_imap_login ;
$mailboxdata [ 'last_smtp_login' ] = $last_smtp_login ;
$mailboxdata [ 'last_pop3_login' ] = $last_pop3_login ;
2019-03-29 05:05:12 +08:00
if ( $mailboxdata [ 'percent_in_use' ] === '- ' ) {
$mailboxdata [ 'percent_class' ] = " info " ;
2018-08-14 05:20:40 +08:00
}
2019-03-29 05:05:12 +08:00
elseif ( $mailboxdata [ 'percent_in_use' ] >= 90 ) {
$mailboxdata [ 'percent_class' ] = " danger " ;
}
2019-04-05 19:08:16 +08:00
elseif ( $mailboxdata [ 'percent_in_use' ] >= 75 ) {
$mailboxdata [ 'percent_class' ] = " warning " ;
}
2018-08-14 05:20:40 +08:00
else {
$mailboxdata [ 'percent_class' ] = " success " ;
2017-05-23 15:36:59 +08:00
}
2021-03-19 23:33:50 +08:00
if ( ! isset ( $_extra ) || $_extra != 'reduced' ) {
$rl = ratelimit ( 'get' , 'mailbox' , $_data );
$stmt = $pdo -> prepare ( " SELECT `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain " );
$stmt -> execute ( array ( ':domain' => $row [ 'domain' ]));
$DomainQuota = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$stmt = $pdo -> prepare ( " SELECT IFNULL(COUNT(`active`), 0) AS `pushover_active` FROM `pushover` WHERE `username` = :username AND `active` = 1 " );
$stmt -> execute ( array ( ':username' => $_data ));
$PushoverActive = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$stmt = $pdo -> prepare ( " SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain AND `username` != :username " );
$stmt -> execute ( array ( ':domain' => $row [ 'domain' ], ':username' => $_data ));
$MailboxUsage = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$stmt = $pdo -> prepare ( " SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND `validity` >= :unixnow " );
$stmt -> execute ( array ( ':address' => $_data , ':unixnow' => time ()));
$SpamaliasUsage = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$mailboxdata [ 'max_new_quota' ] = ( $DomainQuota [ 'quota' ] * 1048576 ) - $MailboxUsage [ 'in_use' ];
$mailboxdata [ 'spam_aliases' ] = $SpamaliasUsage [ 'sa_count' ];
$mailboxdata [ 'pushover_active' ] = ( $PushoverActive [ 'pushover_active' ] == 1 ) ? 1 : 0 ;
if ( $mailboxdata [ 'max_new_quota' ] > ( $DomainQuota [ 'maxquota' ] * 1048576 )) {
$mailboxdata [ 'max_new_quota' ] = ( $DomainQuota [ 'maxquota' ] * 1048576 );
}
if ( ! empty ( $rl )) {
$mailboxdata [ 'rl' ] = $rl ;
$mailboxdata [ 'rl_scope' ] = 'mailbox' ;
}
else {
$mailboxdata [ 'rl' ] = ratelimit ( 'get' , 'domain' , $row [ 'domain' ]);
$mailboxdata [ 'rl_scope' ] = 'domain' ;
}
$mailboxdata [ 'is_relayed' ] = $row [ 'backupmx' ];
}
2017-05-23 15:36:59 +08:00
return $mailboxdata ;
break ;
case 'resource_details' :
$resourcedata = array ();
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $_data )) {
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT
`username` ,
`name` ,
`kind` ,
`multiple_bookings` ,
`local_part` ,
2020-09-18 01:49:15 +08:00
`active` ,
2018-08-14 05:20:40 +08:00
`domain`
FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `username` = : resource " );
$stmt -> execute ( array (
':resource' => $_data ,
));
$row = $stmt -> fetch ( PDO :: FETCH_ASSOC );
$resourcedata [ 'name' ] = $row [ 'username' ];
$resourcedata [ 'kind' ] = $row [ 'kind' ];
$resourcedata [ 'multiple_bookings' ] = $row [ 'multiple_bookings' ];
$resourcedata [ 'description' ] = $row [ 'name' ];
$resourcedata [ 'active' ] = $row [ 'active' ];
2020-09-27 04:04:55 +08:00
$resourcedata [ 'active_int' ] = $row [ 'active' ];
2018-08-14 05:20:40 +08:00
$resourcedata [ 'domain' ] = $row [ 'domain' ];
$resourcedata [ 'local_part' ] = $row [ 'local_part' ];
2017-05-23 15:36:59 +08:00
if ( ! isset ( $resourcedata [ 'domain' ]) ||
( isset ( $resourcedata [ 'domain' ]) && ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $resourcedata [ 'domain' ]))) {
return false ;
}
return $resourcedata ;
break ;
}
break ;
case 'delete' :
switch ( $_type ) {
case 'syncjob' :
if ( ! is_array ( $_data [ 'id' ])) {
$ids = array ();
$ids [] = $_data [ 'id' ];
}
else {
$ids = $_data [ 'id' ];
}
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'syncjobs' ]) || $_SESSION [ 'acl' ][ 'syncjobs' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
foreach ( $ids as $id ) {
if ( ! is_numeric ( $id )) {
return false ;
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `user2` FROM `imapsync` WHERE id = :id " );
$stmt -> execute ( array ( ':id' => $id ));
$user2 = $stmt -> fetch ( PDO :: FETCH_ASSOC )[ 'user2' ];
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $user2 )) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `imapsync` WHERE `id`= :id " );
$stmt -> execute ( array ( ':id' => $id ));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'deleted_syncjob' , $id )
);
2017-05-23 15:36:59 +08:00
}
break ;
2017-11-04 03:37:24 +08:00
case 'filter' :
if ( ! is_array ( $_data [ 'id' ])) {
$ids = array ();
$ids [] = $_data [ 'id' ];
}
else {
$ids = $_data [ 'id' ];
}
if ( ! isset ( $_SESSION [ 'acl' ][ 'filters' ]) || $_SESSION [ 'acl' ][ 'filters' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-11-04 03:37:24 +08:00
);
return false ;
}
foreach ( $ids as $id ) {
if ( ! is_numeric ( $id )) {
2018-08-14 05:20:40 +08:00
continue ;
2017-11-04 03:37:24 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `username` FROM `sieve_filters` WHERE id = :id " );
$stmt -> execute ( array ( ':id' => $id ));
$usr = $stmt -> fetch ( PDO :: FETCH_ASSOC )[ 'username' ];
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $usr )) {
$_SESSION [ 'return' ][] = array (
2017-11-04 03:37:24 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-08-14 05:20:40 +08:00
'msg' => 'access_denied'
2017-11-04 03:37:24 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-11-04 03:37:24 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sieve_filters` WHERE `id`= :id " );
$stmt -> execute ( array ( ':id' => $id ));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'delete_filter' , $id )
);
2017-11-04 03:37:24 +08:00
}
break ;
2017-05-23 15:36:59 +08:00
case 'time_limited_alias' :
if ( ! is_array ( $_data [ 'address' ])) {
$addresses = array ();
$addresses [] = $_data [ 'address' ];
}
else {
$addresses = $_data [ 'address' ];
}
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'spam_alias' ]) || $_SESSION [ 'acl' ][ 'spam_alias' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
foreach ( $addresses as $address ) {
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `goto` FROM `spamalias` WHERE `address` = :address " );
$stmt -> execute ( array ( ':address' => $address ));
$goto = $stmt -> fetch ( PDO :: FETCH_ASSOC )[ 'goto' ];
2017-05-23 15:36:59 +08:00
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $goto )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `spamalias` WHERE `goto` = :username AND `address` = :item " );
$stmt -> execute ( array (
':username' => $goto ,
':item' => $address
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_modified' , htmlspecialchars ( $goto ))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'eas_cache' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
2017-08-19 04:18:14 +08:00
if ( ! isset ( $_SESSION [ 'acl' ][ 'eas_reset' ]) || $_SESSION [ 'acl' ][ 'eas_reset' ] != " 1 " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-08-19 04:18:14 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-08-19 04:18:14 +08:00
);
return false ;
}
2017-05-23 15:36:59 +08:00
foreach ( $usernames as $username ) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $username )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'eas_reset' , htmlspecialchars ( $username ))
);
2017-05-23 15:36:59 +08:00
}
break ;
2018-10-24 03:14:57 +08:00
case 'sogo_profile' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
if ( ! isset ( $_SESSION [ 'acl' ][ 'sogo_profile_reset' ]) || $_SESSION [ 'acl' ][ 'sogo_profile_reset' ] != " 1 " ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
return false ;
}
foreach ( $usernames as $username ) {
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $username )) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
);
continue ;
}
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/ " . $username . " /%' OR `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'sogo_profile_reset' , htmlspecialchars ( $username ))
);
}
break ;
2017-05-23 15:36:59 +08:00
case 'domain' :
if ( ! is_array ( $_data [ 'domain' ])) {
$domains = array ();
$domains [] = $_data [ 'domain' ];
}
else {
$domains = $_data [ 'domain' ];
}
if ( $_SESSION [ 'mailcow_cc_role' ] != " admin " ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
return false ;
}
foreach ( $domains as $domain ) {
if ( ! is_valid_domain_name ( $domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2019-02-05 07:10:21 +08:00
$domain = idn_to_ascii ( strtolower ( trim ( $domain )), 0 , INTL_IDNA_VARIANT_UTS46 );
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `username` FROM `mailbox`
WHERE `domain` = : domain " );
$stmt -> execute ( array ( ':domain' => $domain ));
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
2017-05-23 15:36:59 +08:00
if ( $num_results != 0 || ! empty ( $num_results )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2019-08-10 21:57:07 +08:00
'msg' => array ( 'domain_not_empty' , $domain )
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-10-24 03:14:57 +08:00
$exec_fields = array ( 'cmd' => 'maildir' , 'task' => 'cleanup' , 'maildir' => $domain );
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
$maildir_gc = json_decode ( docker ( 'post' , 'dovecot-mailcow' , 'exec' , $exec_fields ), true );
if ( $maildir_gc [ 'type' ] != 'success' ) {
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-11-12 17:03:50 +08:00
'msg' => 'Could not move mail storage to garbage collector: ' . $maildir_gc [ 'msg' ]
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
);
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `domain` WHERE `domain` = :domain " );
$stmt -> execute ( array (
':domain' => $domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `domain_admins` WHERE `domain` = :domain " );
$stmt -> execute ( array (
':domain' => $domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `alias` WHERE `domain` = :domain " );
$stmt -> execute ( array (
':domain' => $domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `alias_domain` WHERE `target_domain` = :domain " );
$stmt -> execute ( array (
':domain' => $domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `mailbox` WHERE `domain` = :domain " );
$stmt -> execute ( array (
':domain' => $domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `logged_in_as` LIKE :domain " );
$stmt -> execute ( array (
':domain' => '%@' . $domain ,
));
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `quota2` WHERE `username` LIKE :domain " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':domain' => '%@' . $domain ,
));
2020-04-16 17:32:53 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `pushover` WHERE `username` LIKE :domain " );
$stmt -> execute ( array (
':domain' => '%@' . $domain ,
));
2020-02-05 18:04:14 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `quota2replica` WHERE `username` LIKE :domain " );
$stmt -> execute ( array (
':domain' => '%@' . $domain ,
));
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `spamalias` WHERE `address` LIKE :domain " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':domain' => '%@' . $domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `filterconf` WHERE `object` = :domain " );
$stmt -> execute ( array (
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
':domain' => $domain ,
2018-08-14 05:20:40 +08:00
));
$stmt = $pdo -> prepare ( " DELETE FROM `bcc_maps` WHERE `local_dest` = :domain " );
$stmt -> execute ( array (
':domain' => $domain ,
));
2019-10-11 14:25:23 +08:00
$stmt = $pdo -> query ( " DELETE FROM `admin` WHERE `superadmin` = 0 AND `username` NOT IN (SELECT `username`FROM `domain_admins`); " );
2019-10-11 22:47:39 +08:00
$stmt = $pdo -> query ( " DELETE FROM `da_acl` WHERE `username` NOT IN (SELECT `username`FROM `domain_admins`); " );
2017-05-23 15:36:59 +08:00
try {
$redis -> hDel ( 'DOMAIN_MAP' , $domain );
2018-08-22 03:06:22 +08:00
$redis -> hDel ( 'RL_VALUE' , $domain );
2017-05-23 15:36:59 +08:00
}
catch ( RedisException $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'domain_removed' , htmlspecialchars ( $domain ))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'alias' :
2018-08-14 05:20:40 +08:00
if ( ! is_array ( $_data [ 'id' ])) {
$ids = array ();
$ids [] = $_data [ 'id' ];
2017-05-23 15:36:59 +08:00
}
else {
2018-08-14 05:20:40 +08:00
$ids = $_data [ 'id' ];
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
foreach ( $ids as $id ) {
$alias_data = mailbox ( 'get' , 'alias_details' , $id );
if ( empty ( $alias_data )) {
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `alias` WHERE `id` = :id " );
$stmt -> execute ( array (
2020-05-25 22:20:59 +08:00
':id' => $alias_data [ 'id' ]
2018-08-14 05:20:40 +08:00
));
2019-05-26 15:39:04 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `send_as` = :alias_address " );
$stmt -> execute ( array (
':alias_address' => $alias_data [ 'address' ]
));
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'alias_removed' , htmlspecialchars ( $alias_data [ 'address' ]))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'alias_domain' :
if ( ! is_array ( $_data [ 'alias_domain' ])) {
$alias_domains = array ();
$alias_domains [] = $_data [ 'alias_domain' ];
}
else {
$alias_domains = $_data [ 'alias_domain' ];
}
foreach ( $alias_domains as $alias_domain ) {
if ( ! is_valid_domain_name ( $alias_domain )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'domain_invalid'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `target_domain` FROM `alias_domain`
WHERE `alias_domain` = : alias_domain " );
$stmt -> execute ( array ( ':alias_domain' => $alias_domain ));
$DomainData = $stmt -> fetch ( PDO :: FETCH_ASSOC );
2017-05-23 15:36:59 +08:00
if ( ! hasDomainAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $DomainData [ 'target_domain' ])) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `alias_domain` WHERE `alias_domain` = :alias_domain " );
$stmt -> execute ( array (
':alias_domain' => $alias_domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `alias` WHERE `domain` = :alias_domain " );
$stmt -> execute ( array (
':alias_domain' => $alias_domain ,
));
$stmt = $pdo -> prepare ( " DELETE FROM `bcc_maps` WHERE `local_dest` = :alias_domain " );
$stmt -> execute ( array (
':alias_domain' => $alias_domain ,
));
2018-01-17 22:23:33 +08:00
try {
$redis -> hDel ( 'DOMAIN_MAP' , $alias_domain );
2018-08-22 03:06:22 +08:00
$redis -> hDel ( 'RL_VALUE' , $domain );
2018-01-17 22:23:33 +08:00
}
catch ( RedisException $e ) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2018-01-17 22:23:33 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
2018-01-17 22:23:33 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2018-01-17 22:23:33 +08:00
}
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'alias_domain_removed' , htmlspecialchars ( $alias_domain ))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'mailbox' :
if ( ! is_array ( $_data [ 'username' ])) {
$usernames = array ();
$usernames [] = $_data [ 'username' ];
}
else {
$usernames = $_data [ 'username' ];
}
foreach ( $usernames as $username ) {
if ( ! filter_var ( $username , FILTER_VALIDATE_EMAIL )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $username )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-11-12 17:03:50 +08:00
$mailbox_details = mailbox ( 'get' , 'mailbox_details' , $username );
if ( ! empty ( $mailbox_details [ 'domain' ]) && ! empty ( $mailbox_details [ 'local_part' ])) {
$maildir = $mailbox_details [ 'domain' ] . '/' . $mailbox_details [ 'local_part' ];
$exec_fields = array ( 'cmd' => 'maildir' , 'task' => 'cleanup' , 'maildir' => $maildir );
$maildir_gc = json_decode ( docker ( 'post' , 'dovecot-mailcow' , 'exec' , $exec_fields ), true );
if ( $maildir_gc [ 'type' ] != 'success' ) {
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'Could not move maildir to garbage collector: ' . $maildir_gc [ 'msg' ]
);
}
}
else {
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
2018-11-12 17:03:50 +08:00
'msg' => 'Could not move maildir to garbage collector: variables local_part and/or domain empty'
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
);
}
2019-01-17 02:10:47 +08:00
if ( strtolower ( getenv ( 'SKIP_SOLR' )) == 'n' ) {
$curl = curl_init ();
2019-03-10 17:20:49 +08:00
curl_setopt ( $curl , CURLOPT_URL , 'http://solr:8983/solr/dovecot-fts/update?commit=true' );
2019-01-17 02:10:47 +08:00
curl_setopt ( $curl , CURLOPT_HTTPHEADER , array ( 'Content-Type: text/xml' ));
curl_setopt ( $curl , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt ( $curl , CURLOPT_POST , 1 );
2019-11-11 16:55:15 +08:00
curl_setopt ( $curl , CURLOPT_POSTFIELDS , '<delete><query>user:' . $username . '</query></delete>' );
2019-01-17 02:10:47 +08:00
curl_setopt ( $curl , CURLOPT_TIMEOUT , 30 );
$response = curl_exec ( $curl );
if ( $response === false ) {
$err = curl_error ( $curl );
$_SESSION [ 'return' ][] = array (
'type' => 'warning' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'Could not remove Solr index: ' . print_r ( $err , true )
);
}
curl_close ( $curl );
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `alias` WHERE `goto` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2020-04-16 17:32:53 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `pushover` WHERE `username` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2019-02-06 16:24:13 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `quarantine` WHERE `rcpt` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `quota2` WHERE `username` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2020-02-05 18:04:14 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `quota2replica` WHERE `username` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `mailbox` WHERE `username` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sender_acl` WHERE `logged_in_as` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2019-02-06 16:24:13 +08:00
// fk, better safe than sorry
$stmt = $pdo -> prepare ( " DELETE FROM `user_acl` WHERE `username` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `spamalias` WHERE `goto` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `imapsync` WHERE `user2` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `filterconf` WHERE `object` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2019-08-10 22:12:06 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/ " . str_replace ( '%' , '\%' , $username ) . " /%' OR `c_uid` = :username " );
2018-08-14 05:20:40 +08:00
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `bcc_maps` WHERE `local_dest` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2019-10-03 01:00:36 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `oauth_access_tokens` WHERE `user_id` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `oauth_refresh_tokens` WHERE `user_id` = :username " );
$stmt -> execute ( array (
':username' => $username
));
$stmt = $pdo -> prepare ( " DELETE FROM `oauth_authorization_codes` WHERE `user_id` = :username " );
$stmt -> execute ( array (
':username' => $username
));
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " SELECT `address`, `goto` FROM `alias`
WHERE `goto` REGEXP : username " );
$stmt -> execute ( array ( ':username' => '(^|,)' . $username . '($|,)' ));
$GotoData = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
foreach ( $GotoData as $gotos ) {
$goto_exploded = explode ( ',' , $gotos [ 'goto' ]);
if (( $key = array_search ( $username , $goto_exploded )) !== false ) {
unset ( $goto_exploded [ $key ]);
}
$gotos_rebuild = implode ( ',' , $goto_exploded );
$stmt = $pdo -> prepare ( " UPDATE `alias` SET
`goto` = : goto
WHERE `address` = : address " );
2017-11-19 22:13:43 +08:00
$stmt -> execute ( array (
2018-08-14 05:20:40 +08:00
':goto' => $gotos_rebuild ,
':address' => $gotos [ 'address' ]
2017-11-19 22:13:43 +08:00
));
2017-05-23 15:36:59 +08:00
}
2018-08-22 03:06:22 +08:00
try {
$redis -> hDel ( 'RL_VALUE' , $username );
}
catch ( RedisException $e ) {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'redis_error' , $e )
);
continue ;
}
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'mailbox_removed' , htmlspecialchars ( $username ))
);
2017-05-23 15:36:59 +08:00
}
break ;
case 'resource' :
if ( ! is_array ( $_data [ 'name' ])) {
$names = array ();
$names [] = $_data [ 'name' ];
}
else {
$names = $_data [ 'name' ];
}
foreach ( $names as $name ) {
if ( ! filter_var ( $name , FILTER_VALIDATE_EMAIL )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
if ( ! hasMailboxObjectAccess ( $_SESSION [ 'mailcow_cc_username' ], $_SESSION [ 'mailcow_cc_role' ], $name )) {
2018-08-14 05:20:40 +08:00
$_SESSION [ 'return' ][] = array (
2017-05-23 15:36:59 +08:00
'type' => 'danger' ,
2018-08-04 02:31:33 +08:00
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => 'access_denied'
2017-05-23 15:36:59 +08:00
);
2018-08-14 05:20:40 +08:00
continue ;
2017-05-23 15:36:59 +08:00
}
2018-08-14 05:20:40 +08:00
$stmt = $pdo -> prepare ( " DELETE FROM `mailbox` WHERE `username` = :username " );
$stmt -> execute ( array (
':username' => $name
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $name
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $name
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/ " . $name . " /%' OR `c_uid` = :username " );
$stmt -> execute ( array (
':username' => $name
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $name
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $name
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username) " );
$stmt -> execute ( array (
':username' => $name
));
$stmt = $pdo -> prepare ( " DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username " );
$stmt -> execute ( array (
':username' => $name
));
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ , $_action , $_type , $_data_log , $_attr ),
'msg' => array ( 'resource_removed' , htmlspecialchars ( $name ))
);
2017-05-23 15:36:59 +08:00
}
break ;
}
break ;
}
2019-03-18 17:16:33 +08:00
if ( $_action != 'get' && in_array ( $_type , array ( 'domain' , 'alias' , 'alias_domain' , 'mailbox' , 'resource' ))) {
2018-07-12 04:13:43 +08:00
update_sogo_static_view ();
2021-02-11 16:34:21 +08:00
xmpp_rebuild_configs ();
2018-07-12 04:13:43 +08:00
}
2018-08-27 00:31:44 +08:00
}