functions.policy.inc.php 14 KB

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