functions.policy.inc.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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 ($_data['object_list'] == "bl") {
  102. $object_list = "blacklist_from";
  103. }
  104. elseif ($_data['object_list'] == "wl") {
  105. $object_list = "whitelist_from";
  106. }
  107. $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($_data['object_from']))), '.'));
  108. if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $object_from))) {
  109. $_SESSION['return'] = array(
  110. 'type' => 'danger',
  111. 'msg' => sprintf($lang['danger']['policy_list_from_invalid'])
  112. );
  113. return false;
  114. }
  115. if ($object_list != "blacklist_from" && $object_list != "whitelist_from") {
  116. $_SESSION['return'] = array(
  117. 'type' => 'danger',
  118. 'msg' => sprintf($lang['danger']['access_denied'])
  119. );
  120. return false;
  121. }
  122. try {
  123. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
  124. WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
  125. AND `object` = :object
  126. AND `value` = :object_from");
  127. $stmt->execute(array(':object' => $object, ':object_from' => $object_from));
  128. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  129. if ($num_results != 0) {
  130. $_SESSION['return'] = array(
  131. 'type' => 'danger',
  132. 'msg' => sprintf($lang['danger']['policy_list_from_exists'])
  133. );
  134. return false;
  135. }
  136. }
  137. catch(PDOException $e) {
  138. $_SESSION['return'] = array(
  139. 'type' => 'danger',
  140. 'msg' => 'MySQL: '.$e
  141. );
  142. return false;
  143. }
  144. try {
  145. $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
  146. VALUES (:object, :object_list, :object_from)");
  147. $stmt->execute(array(
  148. ':object' => $object,
  149. ':object_list' => $object_list,
  150. ':object_from' => $object_from
  151. ));
  152. }
  153. catch (PDOException $e) {
  154. $_SESSION['return'] = array(
  155. 'type' => 'danger',
  156. 'msg' => 'MySQL: '.$e
  157. );
  158. return false;
  159. }
  160. $_SESSION['return'] = array(
  161. 'type' => 'success',
  162. 'msg' => sprintf($lang['success']['mailbox_modified'], $object)
  163. );
  164. break;
  165. }
  166. break;
  167. case 'delete':
  168. switch ($_scope) {
  169. case 'domain':
  170. if (!is_array($_data['prefid'])) {
  171. $prefids = array();
  172. $prefids[] = $_data['prefid'];
  173. }
  174. else {
  175. $prefids = $_data['prefid'];
  176. }
  177. foreach ($prefids as $prefid) {
  178. if (!is_numeric($prefid)) {
  179. $_SESSION['return'] = array(
  180. 'type' => 'danger',
  181. 'msg' => sprintf($lang['danger']['access_denied'])
  182. );
  183. return false;
  184. }
  185. try {
  186. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
  187. $stmt->execute(array(':prefid' => $prefid));
  188. $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
  189. }
  190. catch(PDOException $e) {
  191. $_SESSION['return'] = array(
  192. 'type' => 'danger',
  193. 'msg' => 'MySQL: '.$e
  194. );
  195. }
  196. if (is_valid_domain_name($object)) {
  197. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  198. $_SESSION['return'] = array(
  199. 'type' => 'danger',
  200. 'msg' => sprintf($lang['danger']['access_denied'])
  201. );
  202. return false;
  203. }
  204. $object = idn_to_ascii(strtolower(trim($object)));
  205. }
  206. else {
  207. $_SESSION['return'] = array(
  208. 'type' => 'danger',
  209. 'msg' => sprintf($lang['danger']['access_denied'])
  210. );
  211. return false;
  212. }
  213. try {
  214. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
  215. $stmt->execute(array(
  216. ':object' => $object,
  217. ':prefid' => $prefid
  218. ));
  219. }
  220. catch (PDOException $e) {
  221. $_SESSION['return'] = array(
  222. 'type' => 'danger',
  223. 'msg' => 'MySQL: '.$e
  224. );
  225. return false;
  226. }
  227. }
  228. $_SESSION['return'] = array(
  229. 'type' => 'success',
  230. 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', $prefids))
  231. );
  232. break;
  233. case 'mailbox':
  234. if (!is_array($_data['prefid'])) {
  235. $prefids = array();
  236. $prefids[] = $_data['prefid'];
  237. }
  238. else {
  239. $prefids = $_data['prefid'];
  240. }
  241. foreach ($prefids as $prefid) {
  242. if (!is_numeric($prefid)) {
  243. $_SESSION['return'] = array(
  244. 'type' => 'danger',
  245. 'msg' => sprintf($lang['danger']['access_denied'])
  246. );
  247. return false;
  248. }
  249. try {
  250. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
  251. $stmt->execute(array(':prefid' => $prefid));
  252. $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
  253. }
  254. catch(PDOException $e) {
  255. $_SESSION['return'] = array(
  256. 'type' => 'danger',
  257. 'msg' => 'MySQL: '.$e
  258. );
  259. }
  260. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  261. $_SESSION['return'] = array(
  262. 'type' => 'danger',
  263. 'msg' => sprintf($lang['danger']['access_denied'])
  264. );
  265. return false;
  266. }
  267. try {
  268. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
  269. $stmt->execute(array(
  270. ':object' => $object,
  271. ':prefid' => $prefid
  272. ));
  273. }
  274. catch (PDOException $e) {
  275. $_SESSION['return'] = array(
  276. 'type' => 'danger',
  277. 'msg' => 'MySQL: '.$e
  278. );
  279. return false;
  280. }
  281. }
  282. $_SESSION['return'] = array(
  283. 'type' => 'success',
  284. 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', $prefids))
  285. );
  286. break;
  287. }
  288. break;
  289. case 'get':
  290. switch ($_scope) {
  291. case 'domain':
  292. if (!is_valid_domain_name($_data)) {
  293. return false;
  294. }
  295. else {
  296. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
  297. return false;
  298. }
  299. $_data = idn_to_ascii(strtolower(trim($_data)));
  300. }
  301. try {
  302. // WHITELIST
  303. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
  304. $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
  305. $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  306. // BLACKLIST
  307. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
  308. $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
  309. $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  310. }
  311. catch(PDOException $e) {
  312. $_SESSION['return'] = array(
  313. 'type' => 'danger',
  314. 'msg' => 'MySQL: '.$e
  315. );
  316. }
  317. return $rows;
  318. break;
  319. case 'mailbox':
  320. if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
  321. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
  322. return false;
  323. }
  324. }
  325. else {
  326. $_data = $_SESSION['mailcow_cc_username'];
  327. }
  328. $domain = mailbox('get', 'mailbox_details', $_data)['domain'];
  329. if (empty($domain)) {
  330. return false;
  331. }
  332. try {
  333. // WHITELIST
  334. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` = :username OR `object` = :domain)");
  335. $stmt->execute(array(':username' => $_data, ':domain' => $domain));
  336. $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  337. // BLACKLIST
  338. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` = :username OR `object` = :domain)");
  339. $stmt->execute(array(':username' => $_data, ':domain' => $domain));
  340. $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  341. }
  342. catch(PDOException $e) {
  343. $_SESSION['return'] = array(
  344. 'type' => 'danger',
  345. 'msg' => 'MySQL: '.$e
  346. );
  347. }
  348. return $rows;
  349. break;
  350. }
  351. break;
  352. }
  353. }