functions.policy.inc.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <?php
  2. function policy($_action, $_scope, $_data = null) {
  3. global $pdo;
  4. global $redis;
  5. global $lang;
  6. $_data_log = $_data;
  7. switch ($_action) {
  8. case 'add':
  9. switch ($_scope) {
  10. case 'domain':
  11. $object = $_data['domain'];
  12. if (is_valid_domain_name($object)) {
  13. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  14. $_SESSION['return'] = array(
  15. 'type' => 'danger',
  16. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  17. 'msg' => 'access_denied'
  18. );
  19. return false;
  20. }
  21. $object = idn_to_ascii(strtolower(trim($object)));
  22. }
  23. else {
  24. $_SESSION['return'] = array(
  25. 'type' => 'danger',
  26. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  27. 'msg' => 'access_denied'
  28. );
  29. return false;
  30. }
  31. if ($_data['object_list'] == "bl") {
  32. $object_list = "blacklist_from";
  33. }
  34. elseif ($_data['object_list'] == "wl") {
  35. $object_list = "whitelist_from";
  36. }
  37. $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($_data['object_from']))), '.'));
  38. if (!ctype_alnum(str_replace(array('@', '_', '.', '-', '*'), '', $object_from))) {
  39. $_SESSION['return'] = array(
  40. 'type' => 'danger',
  41. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  42. 'msg' => 'policy_list_from_invalid'
  43. );
  44. return false;
  45. }
  46. if ($object_list != "blacklist_from" && $object_list != "whitelist_from") {
  47. $_SESSION['return'] = array(
  48. 'type' => 'danger',
  49. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  50. 'msg' => 'access_denied'
  51. );
  52. return false;
  53. }
  54. try {
  55. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
  56. WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
  57. AND `object` = :object
  58. AND `value` = :object_from");
  59. $stmt->execute(array(':object' => $object, ':object_from' => $object_from));
  60. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  61. if ($num_results != 0) {
  62. $_SESSION['return'] = array(
  63. 'type' => 'danger',
  64. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  65. 'msg' => 'policy_list_from_exists'
  66. );
  67. return false;
  68. }
  69. }
  70. catch(PDOException $e) {
  71. $_SESSION['return'] = array(
  72. 'type' => 'danger',
  73. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  74. 'msg' => array('mysql_error', $e)
  75. );
  76. return false;
  77. }
  78. try {
  79. $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
  80. VALUES (:object, :object_list, :object_from)");
  81. $stmt->execute(array(
  82. ':object' => $object,
  83. ':object_list' => $object_list,
  84. ':object_from' => $object_from
  85. ));
  86. }
  87. catch (PDOException $e) {
  88. $_SESSION['return'] = array(
  89. 'type' => 'danger',
  90. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  91. 'msg' => array('mysql_error', $e)
  92. );
  93. return false;
  94. }
  95. $_SESSION['return'] = array(
  96. 'type' => 'success',
  97. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  98. 'msg' => array('domain_modified', $object)
  99. );
  100. break;
  101. case 'mailbox':
  102. $object = $_data['username'];
  103. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  104. $_SESSION['return'] = array(
  105. 'type' => 'danger',
  106. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  107. 'msg' => 'access_denied'
  108. );
  109. return false;
  110. }
  111. if (!isset($_SESSION['acl']['spam_policy']) || $_SESSION['acl']['spam_policy'] != "1" ) {
  112. $_SESSION['return'] = array(
  113. 'type' => 'danger',
  114. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  115. 'msg' => 'access_denied'
  116. );
  117. return false;
  118. }
  119. if ($_data['object_list'] == "bl") {
  120. $object_list = "blacklist_from";
  121. }
  122. elseif ($_data['object_list'] == "wl") {
  123. $object_list = "whitelist_from";
  124. }
  125. $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($_data['object_from']))), '.'));
  126. if (!ctype_alnum(str_replace(array('@', '_', '.', '-', '*'), '', $object_from))) {
  127. $_SESSION['return'] = array(
  128. 'type' => 'danger',
  129. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  130. 'msg' => 'policy_list_from_invalid'
  131. );
  132. return false;
  133. }
  134. if ($object_list != "blacklist_from" && $object_list != "whitelist_from") {
  135. $_SESSION['return'] = array(
  136. 'type' => 'danger',
  137. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  138. 'msg' => 'access_denied'
  139. );
  140. return false;
  141. }
  142. try {
  143. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
  144. WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
  145. AND `object` = :object
  146. AND `value` = :object_from");
  147. $stmt->execute(array(':object' => $object, ':object_from' => $object_from));
  148. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  149. if ($num_results != 0) {
  150. $_SESSION['return'] = array(
  151. 'type' => 'danger',
  152. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  153. 'msg' => 'policy_list_from_exists'
  154. );
  155. return false;
  156. }
  157. }
  158. catch(PDOException $e) {
  159. $_SESSION['return'] = array(
  160. 'type' => 'danger',
  161. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  162. 'msg' => array('mysql_error', $e)
  163. );
  164. return false;
  165. }
  166. try {
  167. $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
  168. VALUES (:object, :object_list, :object_from)");
  169. $stmt->execute(array(
  170. ':object' => $object,
  171. ':object_list' => $object_list,
  172. ':object_from' => $object_from
  173. ));
  174. }
  175. catch (PDOException $e) {
  176. $_SESSION['return'] = array(
  177. 'type' => 'danger',
  178. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  179. 'msg' => array('mysql_error', $e)
  180. );
  181. return false;
  182. }
  183. $_SESSION['return'] = array(
  184. 'type' => 'success',
  185. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  186. 'msg' => array('mailbox_modified', $object)
  187. );
  188. break;
  189. }
  190. break;
  191. case 'delete':
  192. switch ($_scope) {
  193. case 'domain':
  194. (array)$prefids = $_data['prefid'];
  195. foreach ($prefids as $prefid) {
  196. if (!is_numeric($prefid)) {
  197. $_SESSION['return'] = array(
  198. 'type' => 'danger',
  199. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  200. 'msg' => 'access_denied'
  201. );
  202. return false;
  203. }
  204. try {
  205. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
  206. $stmt->execute(array(':prefid' => $prefid));
  207. $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
  208. }
  209. catch(PDOException $e) {
  210. $_SESSION['return'] = array(
  211. 'type' => 'danger',
  212. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  213. 'msg' => array('mysql_error', $e)
  214. );
  215. }
  216. if (is_valid_domain_name($object)) {
  217. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  218. $_SESSION['return'] = array(
  219. 'type' => 'danger',
  220. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  221. 'msg' => 'access_denied'
  222. );
  223. return false;
  224. }
  225. $object = idn_to_ascii(strtolower(trim($object)));
  226. }
  227. else {
  228. $_SESSION['return'] = array(
  229. 'type' => 'danger',
  230. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  231. 'msg' => 'access_denied'
  232. );
  233. return false;
  234. }
  235. try {
  236. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
  237. $stmt->execute(array(
  238. ':object' => $object,
  239. ':prefid' => $prefid
  240. ));
  241. }
  242. catch (PDOException $e) {
  243. $_SESSION['return'] = array(
  244. 'type' => 'danger',
  245. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  246. 'msg' => array('mysql_error', $e)
  247. );
  248. return false;
  249. }
  250. }
  251. $_SESSION['return'] = array(
  252. 'type' => 'success',
  253. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  254. 'msg' => array('items_deleted', implode(', ', $prefids))
  255. );
  256. break;
  257. case 'mailbox':
  258. if (!is_array($_data['prefid'])) {
  259. $prefids = array();
  260. $prefids[] = $_data['prefid'];
  261. }
  262. else {
  263. $prefids = $_data['prefid'];
  264. }
  265. if (!isset($_SESSION['acl']['spam_policy']) || $_SESSION['acl']['spam_policy'] != "1" ) {
  266. $_SESSION['return'] = array(
  267. 'type' => 'danger',
  268. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  269. 'msg' => 'access_denied'
  270. );
  271. return false;
  272. }
  273. foreach ($prefids as $prefid) {
  274. if (!is_numeric($prefid)) {
  275. $_SESSION['return'] = array(
  276. 'type' => 'danger',
  277. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  278. 'msg' => 'access_denied'
  279. );
  280. return false;
  281. }
  282. try {
  283. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
  284. $stmt->execute(array(':prefid' => $prefid));
  285. $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
  286. }
  287. catch(PDOException $e) {
  288. $_SESSION['return'] = array(
  289. 'type' => 'danger',
  290. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  291. 'msg' => array('mysql_error', $e)
  292. );
  293. }
  294. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  295. $_SESSION['return'] = array(
  296. 'type' => 'danger',
  297. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  298. 'msg' => 'access_denied'
  299. );
  300. return false;
  301. }
  302. try {
  303. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
  304. $stmt->execute(array(
  305. ':object' => $object,
  306. ':prefid' => $prefid
  307. ));
  308. }
  309. catch (PDOException $e) {
  310. $_SESSION['return'] = array(
  311. 'type' => 'danger',
  312. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  313. 'msg' => array('mysql_error', $e)
  314. );
  315. return false;
  316. }
  317. }
  318. $_SESSION['return'] = array(
  319. 'type' => 'success',
  320. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  321. 'msg' => array('items_deleted', implode(', ', $prefids))
  322. );
  323. break;
  324. }
  325. break;
  326. case 'get':
  327. switch ($_scope) {
  328. case 'domain':
  329. if (!is_valid_domain_name($_data)) {
  330. return false;
  331. }
  332. else {
  333. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
  334. return false;
  335. }
  336. $_data = idn_to_ascii(strtolower(trim($_data)));
  337. }
  338. try {
  339. // WHITELIST
  340. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
  341. $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
  342. $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  343. // BLACKLIST
  344. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
  345. $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
  346. $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  347. }
  348. catch(PDOException $e) {
  349. $_SESSION['return'] = array(
  350. 'type' => 'danger',
  351. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  352. 'msg' => array('mysql_error', $e)
  353. );
  354. }
  355. return $rows;
  356. break;
  357. case 'mailbox':
  358. if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
  359. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
  360. return false;
  361. }
  362. }
  363. else {
  364. $_data = $_SESSION['mailcow_cc_username'];
  365. }
  366. $domain = mailbox('get', 'mailbox_details', $_data)['domain'];
  367. if (empty($domain)) {
  368. return false;
  369. }
  370. try {
  371. // WHITELIST
  372. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` = :username OR `object` = :domain)");
  373. $stmt->execute(array(':username' => $_data, ':domain' => $domain));
  374. $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  375. // BLACKLIST
  376. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` = :username OR `object` = :domain)");
  377. $stmt->execute(array(':username' => $_data, ':domain' => $domain));
  378. $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  379. }
  380. catch(PDOException $e) {
  381. $_SESSION['return'] = array(
  382. 'type' => 'danger',
  383. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  384. 'msg' => array('mysql_error', $e)
  385. );
  386. }
  387. return $rows;
  388. break;
  389. }
  390. break;
  391. }
  392. }