functions.policy.inc.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  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. (array)$prefids = $_data['prefid'];
  171. foreach ($prefids as $prefid) {
  172. if (!is_numeric($prefid)) {
  173. $_SESSION['return'] = array(
  174. 'type' => 'danger',
  175. 'msg' => sprintf($lang['danger']['access_denied'])
  176. );
  177. return false;
  178. }
  179. try {
  180. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
  181. $stmt->execute(array(':prefid' => $prefid));
  182. $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
  183. }
  184. catch(PDOException $e) {
  185. $_SESSION['return'] = array(
  186. 'type' => 'danger',
  187. 'msg' => 'MySQL: '.$e
  188. );
  189. }
  190. if (is_valid_domain_name($object)) {
  191. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  192. $_SESSION['return'] = array(
  193. 'type' => 'danger',
  194. 'msg' => sprintf($lang['danger']['access_denied'])
  195. );
  196. return false;
  197. }
  198. $object = idn_to_ascii(strtolower(trim($object)));
  199. }
  200. else {
  201. $_SESSION['return'] = array(
  202. 'type' => 'danger',
  203. 'msg' => sprintf($lang['danger']['access_denied'])
  204. );
  205. return false;
  206. }
  207. try {
  208. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
  209. $stmt->execute(array(
  210. ':object' => $object,
  211. ':prefid' => $prefid
  212. ));
  213. }
  214. catch (PDOException $e) {
  215. $_SESSION['return'] = array(
  216. 'type' => 'danger',
  217. 'msg' => 'MySQL: '.$e
  218. );
  219. return false;
  220. }
  221. }
  222. $_SESSION['return'] = array(
  223. 'type' => 'success',
  224. 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', $prefids))
  225. );
  226. break;
  227. case 'mailbox':
  228. if (!is_array($_data['prefid'])) {
  229. $prefids = array();
  230. $prefids[] = $_data['prefid'];
  231. }
  232. else {
  233. $prefids = $_data['prefid'];
  234. }
  235. foreach ($prefids as $prefid) {
  236. if (!is_numeric($prefid)) {
  237. $_SESSION['return'] = array(
  238. 'type' => 'danger',
  239. 'msg' => sprintf($lang['danger']['access_denied'])
  240. );
  241. return false;
  242. }
  243. try {
  244. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
  245. $stmt->execute(array(':prefid' => $prefid));
  246. $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
  247. }
  248. catch(PDOException $e) {
  249. $_SESSION['return'] = array(
  250. 'type' => 'danger',
  251. 'msg' => 'MySQL: '.$e
  252. );
  253. }
  254. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  255. $_SESSION['return'] = array(
  256. 'type' => 'danger',
  257. 'msg' => sprintf($lang['danger']['access_denied'])
  258. );
  259. return false;
  260. }
  261. try {
  262. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
  263. $stmt->execute(array(
  264. ':object' => $object,
  265. ':prefid' => $prefid
  266. ));
  267. }
  268. catch (PDOException $e) {
  269. $_SESSION['return'] = array(
  270. 'type' => 'danger',
  271. 'msg' => 'MySQL: '.$e
  272. );
  273. return false;
  274. }
  275. }
  276. $_SESSION['return'] = array(
  277. 'type' => 'success',
  278. 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', $prefids))
  279. );
  280. break;
  281. }
  282. break;
  283. case 'get':
  284. switch ($_scope) {
  285. case 'domain':
  286. if (!is_valid_domain_name($_data)) {
  287. return false;
  288. }
  289. else {
  290. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
  291. return false;
  292. }
  293. $_data = idn_to_ascii(strtolower(trim($_data)));
  294. }
  295. try {
  296. // WHITELIST
  297. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
  298. $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
  299. $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  300. // BLACKLIST
  301. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
  302. $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
  303. $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  304. }
  305. catch(PDOException $e) {
  306. $_SESSION['return'] = array(
  307. 'type' => 'danger',
  308. 'msg' => 'MySQL: '.$e
  309. );
  310. }
  311. return $rows;
  312. break;
  313. case 'mailbox':
  314. if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
  315. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
  316. return false;
  317. }
  318. }
  319. else {
  320. $_data = $_SESSION['mailcow_cc_username'];
  321. }
  322. $domain = mailbox('get', 'mailbox_details', $_data)['domain'];
  323. if (empty($domain)) {
  324. return false;
  325. }
  326. try {
  327. // WHITELIST
  328. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` = :username OR `object` = :domain)");
  329. $stmt->execute(array(':username' => $_data, ':domain' => $domain));
  330. $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  331. // BLACKLIST
  332. $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` = :username OR `object` = :domain)");
  333. $stmt->execute(array(':username' => $_data, ':domain' => $domain));
  334. $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
  335. }
  336. catch(PDOException $e) {
  337. $_SESSION['return'] = array(
  338. 'type' => 'danger',
  339. 'msg' => 'MySQL: '.$e
  340. );
  341. }
  342. return $rows;
  343. break;
  344. }
  345. break;
  346. }
  347. }