mailbox.inc.php 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990
  1. <?php
  2. function mailbox_add_domain($postarray) {
  3. // Array elements
  4. // domain string
  5. // description string
  6. // aliases int
  7. // mailboxes int
  8. // maxquota int
  9. // quota int
  10. // active int
  11. // relay_all_recipients int
  12. // backupmx int
  13. global $pdo;
  14. global $lang;
  15. if ($_SESSION['mailcow_cc_role'] != "admin") {
  16. $_SESSION['return'] = array(
  17. 'type' => 'danger',
  18. 'msg' => sprintf($lang['danger']['access_denied'])
  19. );
  20. return false;
  21. }
  22. $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
  23. $description = $postarray['description'];
  24. $aliases = $postarray['aliases'];
  25. $mailboxes = $postarray['mailboxes'];
  26. $maxquota = $postarray['maxquota'];
  27. $quota = $postarray['quota'];
  28. if ($maxquota > $quota) {
  29. $_SESSION['return'] = array(
  30. 'type' => 'danger',
  31. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
  32. );
  33. return false;
  34. }
  35. isset($postarray['active']) ? $active = '1' : $active = '0';
  36. isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
  37. isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
  38. isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
  39. if (!is_valid_domain_name($domain)) {
  40. $_SESSION['return'] = array(
  41. 'type' => 'danger',
  42. 'msg' => sprintf($lang['danger']['domain_invalid'])
  43. );
  44. return false;
  45. }
  46. foreach (array($quota, $maxquota, $mailboxes, $aliases) as $data) {
  47. if (!is_numeric($data)) {
  48. $_SESSION['return'] = array(
  49. 'type' => 'danger',
  50. 'msg' => sprintf($lang['danger']['object_is_not_numeric'], htmlspecialchars($data))
  51. );
  52. return false;
  53. }
  54. }
  55. try {
  56. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  57. WHERE `domain` = :domain");
  58. $stmt->execute(array(':domain' => $domain));
  59. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  60. $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
  61. WHERE `alias_domain` = :domain");
  62. $stmt->execute(array(':domain' => $domain));
  63. $num_results = $num_results + count($stmt->fetchAll(PDO::FETCH_ASSOC));
  64. }
  65. catch(PDOException $e) {
  66. $_SESSION['return'] = array(
  67. 'type' => 'danger',
  68. 'msg' => 'MySQL: '.$e
  69. );
  70. return false;
  71. }
  72. if ($num_results != 0) {
  73. $_SESSION['return'] = array(
  74. 'type' => 'danger',
  75. 'msg' => sprintf($lang['danger']['domain_exists'], htmlspecialchars($domain))
  76. );
  77. return false;
  78. }
  79. try {
  80. $stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `created`, `modified`, `active`, `relay_all_recipients`)
  81. VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :created, :modified, :active, :relay_all_recipients)");
  82. $stmt->execute(array(
  83. ':domain' => $domain,
  84. ':description' => $description,
  85. ':aliases' => $aliases,
  86. ':mailboxes' => $mailboxes,
  87. ':maxquota' => $maxquota,
  88. ':quota' => $quota,
  89. ':backupmx' => $backupmx,
  90. ':active' => $active,
  91. ':created' => date('Y-m-d H:i:s'),
  92. ':modified' => date('Y-m-d H:i:s'),
  93. ':relay_all_recipients' => $relay_all_recipients
  94. ));
  95. $_SESSION['return'] = array(
  96. 'type' => 'success',
  97. 'msg' => sprintf($lang['success']['domain_added'], htmlspecialchars($domain))
  98. );
  99. }
  100. catch (PDOException $e) {
  101. mailbox_delete_domain(array('domain' => $domain));
  102. $_SESSION['return'] = array(
  103. 'type' => 'danger',
  104. 'msg' => 'MySQL: '.$e
  105. );
  106. return false;
  107. }
  108. }
  109. function mailbox_add_alias($postarray) {
  110. // Array elements
  111. // address string (separated by " ", "," ";" "\n") - email address or domain
  112. // goto string (separated by " ", "," ";" "\n")
  113. // active int
  114. global $lang;
  115. global $pdo;
  116. $addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['address']));
  117. $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
  118. isset($postarray['active']) ? $active = '1' : $active = '0';
  119. if (empty($addresses[0])) {
  120. $_SESSION['return'] = array(
  121. 'type' => 'danger',
  122. 'msg' => sprintf($lang['danger']['alias_empty'])
  123. );
  124. return false;
  125. }
  126. if (empty($gotos[0])) {
  127. $_SESSION['return'] = array(
  128. 'type' => 'danger',
  129. 'msg' => sprintf($lang['danger']['goto_empty'])
  130. );
  131. return false;
  132. }
  133. foreach ($addresses as $address) {
  134. if (empty($address)) {
  135. continue;
  136. }
  137. $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
  138. $local_part = strstr($address, '@', true);
  139. $address = $local_part.'@'.$domain;
  140. try {
  141. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  142. WHERE `domain`= :domain1 OR `domain` = (SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain2)");
  143. $stmt->execute(array(':domain1' => $domain, ':domain2' => $domain));
  144. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  145. if ($num_results == 0) {
  146. $_SESSION['return'] = array(
  147. 'type' => 'danger',
  148. 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
  149. );
  150. return false;
  151. }
  152. $stmt = $pdo->prepare("SELECT `address` FROM `alias`
  153. WHERE `address`= :address");
  154. $stmt->execute(array(':address' => $address));
  155. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  156. if ($num_results != 0) {
  157. $_SESSION['return'] = array(
  158. 'type' => 'danger',
  159. 'msg' => sprintf($lang['danger']['is_alias_or_mailbox'], htmlspecialchars($address))
  160. );
  161. return false;
  162. }
  163. $stmt = $pdo->prepare("SELECT `address` FROM `spamalias`
  164. WHERE `address`= :address");
  165. $stmt->execute(array(':address' => $address));
  166. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  167. if ($num_results != 0) {
  168. $_SESSION['return'] = array(
  169. 'type' => 'danger',
  170. 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($address))
  171. );
  172. return false;
  173. }
  174. }
  175. catch(PDOException $e) {
  176. $_SESSION['return'] = array(
  177. 'type' => 'danger',
  178. 'msg' => 'MySQL: '.$e
  179. );
  180. return false;
  181. }
  182. if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
  183. $_SESSION['return'] = array(
  184. 'type' => 'danger',
  185. 'msg' => sprintf($lang['danger']['alias_invalid'])
  186. );
  187. return false;
  188. }
  189. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  190. $_SESSION['return'] = array(
  191. 'type' => 'danger',
  192. 'msg' => sprintf($lang['danger']['access_denied'])
  193. );
  194. return false;
  195. }
  196. foreach ($gotos as &$goto) {
  197. if (empty($goto)) {
  198. continue;
  199. }
  200. $goto_domain = idn_to_ascii(substr(strstr($goto, '@'), 1));
  201. $goto_local_part = strstr($goto, '@', true);
  202. $goto = $goto_local_part.'@'.$goto_domain;
  203. if (!filter_var($goto, FILTER_VALIDATE_EMAIL) === true) {
  204. $_SESSION['return'] = array(
  205. 'type' => 'danger',
  206. 'msg' => sprintf($lang['danger']['goto_invalid'])
  207. );
  208. return false;
  209. }
  210. if ($goto == $address) {
  211. $_SESSION['return'] = array(
  212. 'type' => 'danger',
  213. 'msg' => sprintf($lang['danger']['alias_goto_identical'])
  214. );
  215. return false;
  216. }
  217. }
  218. $gotos = array_filter($gotos);
  219. $goto = implode(",", $gotos);
  220. try {
  221. $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
  222. VALUES (:address, :goto, :domain, :created, :modified, :active)");
  223. if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
  224. $stmt->execute(array(
  225. ':address' => '@'.$domain,
  226. ':goto' => $goto,
  227. ':domain' => $domain,
  228. ':created' => date('Y-m-d H:i:s'),
  229. ':modified' => date('Y-m-d H:i:s'),
  230. ':active' => $active
  231. ));
  232. }
  233. else {
  234. $stmt->execute(array(
  235. ':address' => $address,
  236. ':goto' => $goto,
  237. ':domain' => $domain,
  238. ':created' => date('Y-m-d H:i:s'),
  239. ':modified' => date('Y-m-d H:i:s'),
  240. ':active' => $active
  241. ));
  242. }
  243. $_SESSION['return'] = array(
  244. 'type' => 'success',
  245. 'msg' => sprintf($lang['success']['alias_added'])
  246. );
  247. }
  248. catch (PDOException $e) {
  249. mailbox_delete_alias(array('address' => $address));
  250. $_SESSION['return'] = array(
  251. 'type' => 'danger',
  252. 'msg' => 'MySQL: '.$e
  253. );
  254. return false;
  255. }
  256. }
  257. $_SESSION['return'] = array(
  258. 'type' => 'success',
  259. 'msg' => sprintf($lang['success']['alias_added'])
  260. );
  261. }
  262. function mailbox_add_alias_domain($postarray) {
  263. // Array elements
  264. // active int
  265. // alias_domain string
  266. // target_domain string
  267. global $lang;
  268. global $pdo;
  269. isset($postarray['active']) ? $active = '1' : $active = '0';
  270. $alias_domain = idn_to_ascii(strtolower(trim($postarray['alias_domain'])));
  271. $target_domain = idn_to_ascii(strtolower(trim($postarray['target_domain'])));
  272. if (!is_valid_domain_name($alias_domain)) {
  273. $_SESSION['return'] = array(
  274. 'type' => 'danger',
  275. 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
  276. );
  277. return false;
  278. }
  279. if (!is_valid_domain_name($target_domain)) {
  280. $_SESSION['return'] = array(
  281. 'type' => 'danger',
  282. 'msg' => sprintf($lang['danger']['target_domain_invalid'])
  283. );
  284. return false;
  285. }
  286. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $target_domain)) {
  287. $_SESSION['return'] = array(
  288. 'type' => 'danger',
  289. 'msg' => sprintf($lang['danger']['access_denied'])
  290. );
  291. return false;
  292. }
  293. if ($alias_domain == $target_domain) {
  294. $_SESSION['return'] = array(
  295. 'type' => 'danger',
  296. 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
  297. );
  298. return false;
  299. }
  300. try {
  301. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  302. WHERE `domain`= :target_domain");
  303. $stmt->execute(array(':target_domain' => $target_domain));
  304. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  305. if ($num_results == 0) {
  306. $_SESSION['return'] = array(
  307. 'type' => 'danger',
  308. 'msg' => sprintf($lang['danger']['targetd_not_found'])
  309. );
  310. return false;
  311. }
  312. $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain
  313. UNION
  314. SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain_in_domain");
  315. $stmt->execute(array(':alias_domain' => $alias_domain, ':alias_domain_in_domain' => $alias_domain));
  316. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  317. if ($num_results != 0) {
  318. $_SESSION['return'] = array(
  319. 'type' => 'danger',
  320. 'msg' => sprintf($lang['danger']['aliasd_exists'])
  321. );
  322. return false;
  323. }
  324. }
  325. catch(PDOException $e) {
  326. $_SESSION['return'] = array(
  327. 'type' => 'danger',
  328. 'msg' => 'MySQL: '.$e
  329. );
  330. return false;
  331. }
  332. try {
  333. $stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `created`, `modified`, `active`)
  334. VALUES (:alias_domain, :target_domain, :created, :modified, :active)");
  335. $stmt->execute(array(
  336. ':alias_domain' => $alias_domain,
  337. ':target_domain' => $target_domain,
  338. ':created' => date('Y-m-d H:i:s'),
  339. ':modified' => date('Y-m-d H:i:s'),
  340. ':active' => $active
  341. ));
  342. $_SESSION['return'] = array(
  343. 'type' => 'success',
  344. 'msg' => sprintf($lang['success']['aliasd_added'], htmlspecialchars($alias_domain))
  345. );
  346. }
  347. catch (PDOException $e) {
  348. mailbox_delete_alias_domain(array('alias_domain' => $alias_domain));
  349. $_SESSION['return'] = array(
  350. 'type' => 'danger',
  351. 'msg' => 'MySQL: '.$e
  352. );
  353. return false;
  354. }
  355. }
  356. function mailbox_add_mailbox($postarray) {
  357. // Array elements
  358. // active int
  359. // local_part string
  360. // domain string
  361. // name string (username if empty)
  362. // password string
  363. // password2 string
  364. // quota int (MiB)
  365. // active int
  366. global $pdo;
  367. global $lang;
  368. $local_part = strtolower(trim($postarray['local_part']));
  369. $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
  370. $username = $local_part . '@' . $domain;
  371. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  372. $_SESSION['return'] = array(
  373. 'type' => 'danger',
  374. 'msg' => sprintf($lang['danger']['mailbox_invalid'])
  375. );
  376. return false;
  377. }
  378. if (empty($postarray['local_part'])) {
  379. $_SESSION['return'] = array(
  380. 'type' => 'danger',
  381. 'msg' => sprintf($lang['danger']['mailbox_invalid'])
  382. );
  383. return false;
  384. }
  385. $password = $postarray['password'];
  386. $password2 = $postarray['password2'];
  387. $name = $postarray['name'];
  388. $quota_m = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
  389. if (empty($name)) {
  390. $name = $local_part;
  391. }
  392. isset($postarray['active']) ? $active = '1' : $active = '0';
  393. $quota_b = ($quota_m * 1048576);
  394. $maildir = $domain."/".$local_part."/";
  395. if (!is_valid_domain_name($domain)) {
  396. $_SESSION['return'] = array(
  397. 'type' => 'danger',
  398. 'msg' => sprintf($lang['danger']['domain_invalid'])
  399. );
  400. return false;
  401. }
  402. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  403. $_SESSION['return'] = array(
  404. 'type' => 'danger',
  405. 'msg' => sprintf($lang['danger']['access_denied'])
  406. );
  407. return false;
  408. }
  409. try {
  410. $stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` FROM `domain`
  411. WHERE `domain` = :domain");
  412. $stmt->execute(array(':domain' => $domain));
  413. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  414. $stmt = $pdo->prepare("SELECT
  415. COUNT(*) as count,
  416. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota`
  417. FROM `mailbox`
  418. WHERE `domain` = :domain");
  419. $stmt->execute(array(':domain' => $domain));
  420. $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
  421. $stmt = $pdo->prepare("SELECT `local_part` FROM `mailbox` WHERE `local_part` = :local_part and `domain`= :domain");
  422. $stmt->execute(array(':local_part' => $local_part, ':domain' => $domain));
  423. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  424. if ($num_results != 0) {
  425. $_SESSION['return'] = array(
  426. 'type' => 'danger',
  427. 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
  428. );
  429. return false;
  430. }
  431. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :username");
  432. $stmt->execute(array(':username' => $username));
  433. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  434. if ($num_results != 0) {
  435. $_SESSION['return'] = array(
  436. 'type' => 'danger',
  437. 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($username))
  438. );
  439. return false;
  440. }
  441. $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :username");
  442. $stmt->execute(array(':username' => $username));
  443. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  444. if ($num_results != 0) {
  445. $_SESSION['return'] = array(
  446. 'type' => 'danger',
  447. 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($username))
  448. );
  449. return false;
  450. }
  451. $stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain");
  452. $stmt->execute(array(':domain' => $domain));
  453. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  454. if ($num_results == 0) {
  455. $_SESSION['return'] = array(
  456. 'type' => 'danger',
  457. 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
  458. );
  459. return false;
  460. }
  461. }
  462. catch(PDOException $e) {
  463. $_SESSION['return'] = array(
  464. 'type' => 'danger',
  465. 'msg' => 'MySQL: '.$e
  466. );
  467. return false;
  468. }
  469. if (!is_numeric($quota_m) || $quota_m == "0") {
  470. $_SESSION['return'] = array(
  471. 'type' => 'danger',
  472. 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'])
  473. );
  474. return false;
  475. }
  476. if (!empty($password) && !empty($password2)) {
  477. if ($password != $password2) {
  478. $_SESSION['return'] = array(
  479. 'type' => 'danger',
  480. 'msg' => sprintf($lang['danger']['password_mismatch'])
  481. );
  482. return false;
  483. }
  484. $password_hashed = hash_password($password);
  485. }
  486. else {
  487. $_SESSION['return'] = array(
  488. 'type' => 'danger',
  489. 'msg' => sprintf($lang['danger']['password_empty'])
  490. );
  491. return false;
  492. }
  493. if ($MailboxData['count'] >= $DomainData['mailboxes']) {
  494. $_SESSION['return'] = array(
  495. 'type' => 'danger',
  496. 'msg' => sprintf($lang['danger']['max_mailbox_exceeded'], $MailboxData['count'], $DomainData['mailboxes'])
  497. );
  498. return false;
  499. }
  500. if ($quota_m > $DomainData['maxquota']) {
  501. $_SESSION['return'] = array(
  502. 'type' => 'danger',
  503. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
  504. );
  505. return false;
  506. }
  507. if (($MailboxData['quota'] + $quota_m) > $DomainData['quota']) {
  508. $quota_left_m = ($DomainData['quota'] - $MailboxData['quota']);
  509. $_SESSION['return'] = array(
  510. 'type' => 'danger',
  511. 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
  512. );
  513. return false;
  514. }
  515. try {
  516. $stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`)
  517. VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :created, :modified, :active)");
  518. $stmt->execute(array(
  519. ':username' => $username,
  520. ':password_hashed' => $password_hashed,
  521. ':name' => $name,
  522. ':maildir' => $maildir,
  523. ':quota_b' => $quota_b,
  524. ':local_part' => $local_part,
  525. ':domain' => $domain,
  526. ':created' => date('Y-m-d H:i:s'),
  527. ':modified' => date('Y-m-d H:i:s'),
  528. ':active' => $active
  529. ));
  530. $stmt = $pdo->prepare("INSERT INTO `quota2` (`username`, `bytes`, `messages`)
  531. VALUES (:username, '0', '0')");
  532. $stmt->execute(array(':username' => $username));
  533. $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
  534. VALUES (:username1, :username2, :domain, :created, :modified, :active)");
  535. $stmt->execute(array(
  536. ':username1' => $username,
  537. ':username2' => $username,
  538. ':domain' => $domain,
  539. ':created' => date('Y-m-d H:i:s'),
  540. ':modified' => date('Y-m-d H:i:s'),
  541. ':active' => $active
  542. ));
  543. $_SESSION['return'] = array(
  544. 'type' => 'success',
  545. 'msg' => sprintf($lang['success']['mailbox_added'], htmlspecialchars($username))
  546. );
  547. }
  548. catch (PDOException $e) {
  549. mailbox_delete_mailbox(array('address' => $username));
  550. $_SESSION['return'] = array(
  551. 'type' => 'danger',
  552. 'msg' => 'MySQL: '.$e
  553. );
  554. return false;
  555. }
  556. }
  557. function mailbox_edit_alias_domain($postarray) {
  558. // Array elements
  559. // active int
  560. // alias_domain_now string
  561. // alias_domain string
  562. global $lang;
  563. global $pdo;
  564. isset($postarray['active']) ? $active = '1' : $active = '0';
  565. $alias_domain = idn_to_ascii(strtolower(trim($postarray['alias_domain'])));
  566. $alias_domain_now = strtolower(trim($postarray['alias_domain_now']));
  567. if (!is_valid_domain_name($alias_domain)) {
  568. $_SESSION['return'] = array(
  569. 'type' => 'danger',
  570. 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
  571. );
  572. return false;
  573. }
  574. if (!is_valid_domain_name($alias_domain_now)) {
  575. $_SESSION['return'] = array(
  576. 'type' => 'danger',
  577. 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
  578. );
  579. return false;
  580. }
  581. try {
  582. $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
  583. WHERE `alias_domain`= :alias_domain_now");
  584. $stmt->execute(array(':alias_domain_now' => $alias_domain_now));
  585. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  586. }
  587. catch(PDOException $e) {
  588. $_SESSION['return'] = array(
  589. 'type' => 'danger',
  590. 'msg' => 'MySQL: '.$e
  591. );
  592. return false;
  593. }
  594. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
  595. $_SESSION['return'] = array(
  596. 'type' => 'danger',
  597. 'msg' => sprintf($lang['danger']['access_denied'])
  598. );
  599. return false;
  600. }
  601. try {
  602. $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
  603. WHERE `target_domain`= :alias_domain");
  604. $stmt->execute(array(':alias_domain' => $alias_domain));
  605. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  606. }
  607. catch(PDOException $e) {
  608. $_SESSION['return'] = array(
  609. 'type' => 'danger',
  610. 'msg' => 'MySQL: '.$e
  611. );
  612. return false;
  613. }
  614. if ($num_results != 0) {
  615. $_SESSION['return'] = array(
  616. 'type' => 'danger',
  617. 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
  618. );
  619. return false;
  620. }
  621. try {
  622. $stmt = $pdo->prepare("UPDATE `alias_domain` SET
  623. `alias_domain` = :alias_domain,
  624. `active` = :active,
  625. `modified` = :modified,
  626. WHERE `alias_domain` = :alias_domain_now");
  627. $stmt->execute(array(
  628. ':alias_domain' => $alias_domain,
  629. ':modified' => date('Y-m-d H:i:s'),
  630. ':alias_domain_now' => $alias_domain_now,
  631. ':active' => $active
  632. ));
  633. }
  634. catch (PDOException $e) {
  635. $_SESSION['return'] = array(
  636. 'type' => 'danger',
  637. 'msg' => 'MySQL: '.$e
  638. );
  639. return false;
  640. }
  641. $_SESSION['return'] = array(
  642. 'type' => 'success',
  643. 'msg' => sprintf($lang['success']['aliasd_modified'], htmlspecialchars($alias_domain))
  644. );
  645. }
  646. function mailbox_edit_alias($postarray) {
  647. // Array elements
  648. // address string
  649. // goto string (separated by " ", "," ";" "\n") - email address or domain
  650. // active int
  651. global $lang;
  652. global $pdo;
  653. $address = $postarray['address'];
  654. $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
  655. $local_part = strstr($address, '@', true);
  656. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  657. $_SESSION['return'] = array(
  658. 'type' => 'danger',
  659. 'msg' => sprintf($lang['danger']['access_denied'])
  660. );
  661. return false;
  662. }
  663. if (empty($postarray['goto'])) {
  664. $_SESSION['return'] = array(
  665. 'type' => 'danger',
  666. 'msg' => sprintf($lang['danger']['goto_empty'])
  667. );
  668. return false;
  669. }
  670. $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
  671. foreach ($gotos as &$goto) {
  672. if (empty($goto)) {
  673. continue;
  674. }
  675. if (!filter_var($goto, FILTER_VALIDATE_EMAIL)) {
  676. $_SESSION['return'] = array(
  677. 'type' => 'danger',
  678. 'msg' =>sprintf($lang['danger']['goto_invalid'])
  679. );
  680. return false;
  681. }
  682. if ($goto == $address) {
  683. $_SESSION['return'] = array(
  684. 'type' => 'danger',
  685. 'msg' => sprintf($lang['danger']['alias_goto_identical'])
  686. );
  687. return false;
  688. }
  689. }
  690. $gotos = array_filter($gotos);
  691. $goto = implode(",", $gotos);
  692. isset($postarray['active']) ? $active = '1' : $active = '0';
  693. if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
  694. $_SESSION['return'] = array(
  695. 'type' => 'danger',
  696. 'msg' => sprintf($lang['danger']['alias_invalid'])
  697. );
  698. return false;
  699. }
  700. try {
  701. $stmt = $pdo->prepare("UPDATE `alias` SET
  702. `goto` = :goto,
  703. `active`= :active,
  704. `modified` = :modified,
  705. WHERE `address` = :address");
  706. $stmt->execute(array(
  707. ':goto' => $goto,
  708. ':active' => $active,
  709. ':address' => $address,
  710. ':modified' => date('Y-m-d H:i:s'),
  711. ));
  712. $_SESSION['return'] = array(
  713. 'type' => 'success',
  714. 'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars($address))
  715. );
  716. }
  717. catch (PDOException $e) {
  718. $_SESSION['return'] = array(
  719. 'type' => 'danger',
  720. 'msg' => 'MySQL: '.$e
  721. );
  722. return false;
  723. }
  724. }
  725. function mailbox_edit_domain($postarray) {
  726. // Array elements
  727. // domain string
  728. // description string
  729. // active int
  730. // relay_all_recipients int
  731. // backupmx int
  732. // aliases float
  733. // mailboxes float
  734. // maxquota float
  735. // quota float (Byte)
  736. // active int
  737. global $lang;
  738. global $pdo;
  739. $domain = idn_to_ascii($postarray['domain']);
  740. if (!is_valid_domain_name($domain)) {
  741. $_SESSION['return'] = array(
  742. 'type' => 'danger',
  743. 'msg' => sprintf($lang['danger']['domain_invalid'])
  744. );
  745. return false;
  746. }
  747. if ($_SESSION['mailcow_cc_role'] == "domainadmin" && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  748. $description = $postarray['description'];
  749. isset($postarray['active']) ? $active = '1' : $active = '0';
  750. try {
  751. $stmt = $pdo->prepare("UPDATE `domain` SET
  752. `modified`= :modified,
  753. `description` = :description
  754. WHERE `domain` = :domain");
  755. $stmt->execute(array(
  756. ':modified' => date('Y-m-d H:i:s'),
  757. ':description' => $description,
  758. ':domain' => $domain
  759. ));
  760. $_SESSION['return'] = array(
  761. 'type' => 'success',
  762. 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
  763. );
  764. }
  765. catch (PDOException $e) {
  766. $_SESSION['return'] = array(
  767. 'type' => 'danger',
  768. 'msg' => 'MySQL: '.$e
  769. );
  770. return false;
  771. }
  772. }
  773. elseif ($_SESSION['mailcow_cc_role'] == "admin") {
  774. $description = $postarray['description'];
  775. isset($postarray['active']) ? $active = '1' : $active = '0';
  776. $aliases = filter_var($postarray['aliases'], FILTER_SANITIZE_NUMBER_FLOAT);
  777. $mailboxes = filter_var($postarray['mailboxes'], FILTER_SANITIZE_NUMBER_FLOAT);
  778. $maxquota = filter_var($postarray['maxquota'], FILTER_SANITIZE_NUMBER_FLOAT);
  779. $quota = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
  780. isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
  781. isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
  782. isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
  783. try {
  784. // GET MAILBOX DATA
  785. $stmt = $pdo->prepare("SELECT
  786. COUNT(*) AS count,
  787. MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `maxquota`,
  788. COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota`
  789. FROM `mailbox`
  790. WHERE domain= :domain");
  791. $stmt->execute(array(':domain' => $domain));
  792. $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
  793. // GET ALIAS DATA
  794. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
  795. WHERE domain = :domain
  796. AND address NOT IN (
  797. SELECT `username` FROM `mailbox`
  798. )");
  799. $stmt->execute(array(':domain' => $domain));
  800. $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
  801. }
  802. catch(PDOException $e) {
  803. $_SESSION['return'] = array(
  804. 'type' => 'danger',
  805. 'msg' => 'MySQL: '.$e
  806. );
  807. return false;
  808. }
  809. if ($maxquota > $quota) {
  810. $_SESSION['return'] = array(
  811. 'type' => 'danger',
  812. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
  813. );
  814. return false;
  815. }
  816. if ($MailboxData['maxquota'] > $maxquota) {
  817. echo $MailboxData['maxquota'];
  818. die();
  819. $_SESSION['return'] = array(
  820. 'type' => 'danger',
  821. 'msg' => sprintf($lang['danger']['max_quota_in_use'], $MailboxData['maxquota'])
  822. );
  823. return false;
  824. }
  825. if ($MailboxData['quota'] > $quota) {
  826. $_SESSION['return'] = array(
  827. 'type' => 'danger',
  828. 'msg' => sprintf($lang['danger']['domain_quota_m_in_use'], $MailboxData['quota'])
  829. );
  830. return false;
  831. }
  832. if ($MailboxData['count'] > $mailboxes) {
  833. $_SESSION['return'] = array(
  834. 'type' => 'danger',
  835. 'msg' => sprintf($lang['danger']['mailboxes_in_use'], $MailboxData['count'])
  836. );
  837. return false;
  838. }
  839. if ($AliasData['count'] > $aliases) {
  840. $_SESSION['return'] = array(
  841. 'type' => 'danger',
  842. 'msg' => sprintf($lang['danger']['aliases_in_use'], $AliasData['count'])
  843. );
  844. return false;
  845. }
  846. try {
  847. $stmt = $pdo->prepare("UPDATE `domain` SET
  848. `modified`= :modified,
  849. `relay_all_recipients` = :relay_all_recipients,
  850. `backupmx` = :backupmx,
  851. `active` = :active,
  852. `quota` = :quota,
  853. `maxquota` = :maxquota,
  854. `modified` = :modified,
  855. `mailboxes` = :mailboxes,
  856. `aliases` = :aliases,
  857. `description` = :description
  858. WHERE `domain` = :domain");
  859. $stmt->execute(array(
  860. ':relay_all_recipients' => $relay_all_recipients,
  861. ':backupmx' => $backupmx,
  862. ':active' => $active,
  863. ':quota' => $quota,
  864. ':maxquota' => $maxquota,
  865. ':modified' => date('Y-m-d H:i:s'),
  866. ':mailboxes' => $mailboxes,
  867. ':aliases' => $aliases,
  868. ':modified' => date('Y-m-d H:i:s'),
  869. ':description' => $description,
  870. ':domain' => $domain
  871. ));
  872. $_SESSION['return'] = array(
  873. 'type' => 'success',
  874. 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
  875. );
  876. }
  877. catch (PDOException $e) {
  878. $_SESSION['return'] = array(
  879. 'type' => 'danger',
  880. 'msg' => 'MySQL: '.$e
  881. );
  882. return false;
  883. }
  884. }
  885. }
  886. function mailbox_edit_mailbox($postarray) {
  887. global $lang;
  888. global $pdo;
  889. isset($postarray['active']) ? $active = '1' : $active = '0';
  890. if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
  891. $_SESSION['return'] = array(
  892. 'type' => 'danger',
  893. 'msg' => sprintf($lang['danger']['username_invalid'])
  894. );
  895. return false;
  896. }
  897. $quota_m = $postarray['quota'];
  898. $quota_b = $quota_m*1048576;
  899. $username = $postarray['username'];
  900. $name = $postarray['name'];
  901. $password = $postarray['password'];
  902. $password2 = $postarray['password2'];
  903. try {
  904. $stmt = $pdo->prepare("SELECT `domain`
  905. FROM `mailbox`
  906. WHERE username = :username");
  907. $stmt->execute(array(':username' => $username));
  908. $MailboxData1 = $stmt->fetch(PDO::FETCH_ASSOC);
  909. $stmt = $pdo->prepare("SELECT
  910. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_now`
  911. FROM `mailbox`
  912. WHERE `username` = :username");
  913. $stmt->execute(array(':username' => $username));
  914. $MailboxData2 = $stmt->fetch(PDO::FETCH_ASSOC);
  915. $stmt = $pdo->prepare("SELECT
  916. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_in_use`
  917. FROM `mailbox`
  918. WHERE `domain` = :domain");
  919. $stmt->execute(array(':domain' => $MailboxData1['domain']));
  920. $MailboxData3 = $stmt->fetch(PDO::FETCH_ASSOC);
  921. $stmt = $pdo->prepare("SELECT `quota`, `maxquota`
  922. FROM `domain`
  923. WHERE `domain` = :domain");
  924. $stmt->execute(array(':domain' => $MailboxData1['domain']));
  925. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  926. }
  927. catch(PDOException $e) {
  928. $_SESSION['return'] = array(
  929. 'type' => 'danger',
  930. 'msg' => 'MySQL: '.$e
  931. );
  932. return false;
  933. }
  934. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $MailboxData1['domain'])) {
  935. $_SESSION['return'] = array(
  936. 'type' => 'danger',
  937. 'msg' => sprintf($lang['danger']['access_denied'])
  938. );
  939. return false;
  940. }
  941. if (!is_numeric($quota_m) || $quota_m == "0") {
  942. $_SESSION['return'] = array(
  943. 'type' => 'danger',
  944. 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'], htmlspecialchars($quota_m))
  945. );
  946. return false;
  947. }
  948. if ($quota_m > $DomainData['maxquota']) {
  949. $_SESSION['return'] = array(
  950. 'type' => 'danger',
  951. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
  952. );
  953. return false;
  954. }
  955. if (($MailboxData3['quota_m_in_use'] - $MailboxData2['quota_m_now'] + $quota_m) > $DomainData['quota']) {
  956. $quota_left_m = ($DomainData['quota'] - $MailboxData3['quota_m_in_use'] + $MailboxData2['quota_m_now']);
  957. $_SESSION['return'] = array(
  958. 'type' => 'danger',
  959. 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
  960. );
  961. return false;
  962. }
  963. // Get sender_acl items set by admin
  964. $sender_acl_admin = array_merge(
  965. mailbox_get_sender_acl_handles($username)['sender_acl_domains']['ro'],
  966. mailbox_get_sender_acl_handles($username)['sender_acl_addresses']['ro']
  967. );
  968. // Get sender_acl items from POST array
  969. (isset($postarray['sender_acl'])) ? $sender_acl_domain_admin = $postarray['sender_acl'] : $sender_acl_domain_admin = array();
  970. if (!empty($sender_acl_domain_admin) || !empty($sender_acl_admin)) {
  971. // Check items in POST array
  972. foreach ($sender_acl_domain_admin as $sender_acl) {
  973. if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name(ltrim($sender_acl, '@'))) {
  974. $_SESSION['return'] = array(
  975. 'type' => 'danger',
  976. 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
  977. );
  978. return false;
  979. }
  980. if (is_valid_domain_name(ltrim($sender_acl, '@'))) {
  981. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], ltrim($sender_acl, '@'))) {
  982. $_SESSION['return'] = array(
  983. 'type' => 'danger',
  984. 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
  985. );
  986. return false;
  987. }
  988. }
  989. if (filter_var($sender_acl, FILTER_VALIDATE_EMAIL)) {
  990. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $sender_acl)) {
  991. $_SESSION['return'] = array(
  992. 'type' => 'danger',
  993. 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
  994. );
  995. return false;
  996. }
  997. }
  998. }
  999. // Merge both arrays
  1000. $sender_acl_merged = array_merge($sender_acl_domain_admin, $sender_acl_admin);
  1001. try {
  1002. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  1003. $stmt->execute(array(
  1004. ':username' => $username
  1005. ));
  1006. }
  1007. catch (PDOException $e) {
  1008. $_SESSION['return'] = array(
  1009. 'type' => 'danger',
  1010. 'msg' => 'MySQL: '.$e
  1011. );
  1012. return false;
  1013. }
  1014. foreach ($sender_acl_merged as $sender_acl) {
  1015. $domain = ltrim($sender_acl, '@');
  1016. if (is_valid_domain_name($domain)) {
  1017. $sender_acl = '@' . $domain;
  1018. }
  1019. try {
  1020. $stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`)
  1021. VALUES (:sender_acl, :username)");
  1022. $stmt->execute(array(
  1023. ':sender_acl' => $sender_acl,
  1024. ':username' => $username
  1025. ));
  1026. }
  1027. catch (PDOException $e) {
  1028. $_SESSION['return'] = array(
  1029. 'type' => 'danger',
  1030. 'msg' => 'MySQL: '.$e
  1031. );
  1032. return false;
  1033. }
  1034. }
  1035. }
  1036. else {
  1037. try {
  1038. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  1039. $stmt->execute(array(
  1040. ':username' => $username
  1041. ));
  1042. }
  1043. catch (PDOException $e) {
  1044. $_SESSION['return'] = array(
  1045. 'type' => 'danger',
  1046. 'msg' => 'MySQL: '.$e
  1047. );
  1048. return false;
  1049. }
  1050. }
  1051. if (!empty($password) && !empty($password2)) {
  1052. if ($password != $password2) {
  1053. $_SESSION['return'] = array(
  1054. 'type' => 'danger',
  1055. 'msg' => sprintf($lang['danger']['password_mismatch'])
  1056. );
  1057. return false;
  1058. }
  1059. $password_hashed = hash_password($password);
  1060. try {
  1061. $stmt = $pdo->prepare("UPDATE `alias` SET
  1062. `modified` = :modified,
  1063. `active` = :active
  1064. WHERE `address` = :address");
  1065. $stmt->execute(array(
  1066. ':address' => $username,
  1067. ':modified' => date('Y-m-d H:i:s'),
  1068. ':active' => $active
  1069. ));
  1070. $stmt = $pdo->prepare("UPDATE `mailbox` SET
  1071. `modified` = :modified,
  1072. `active` = :active,
  1073. `password` = :password_hashed,
  1074. `name`= :name,
  1075. `quota` = :quota_b
  1076. WHERE `username` = :username");
  1077. $stmt->execute(array(
  1078. ':modified' => date('Y-m-d H:i:s'),
  1079. ':password_hashed' => $password_hashed,
  1080. ':active' => $active,
  1081. ':name' => $name,
  1082. ':quota_b' => $quota_b,
  1083. ':username' => $username
  1084. ));
  1085. $_SESSION['return'] = array(
  1086. 'type' => 'success',
  1087. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  1088. );
  1089. return true;
  1090. }
  1091. catch (PDOException $e) {
  1092. $_SESSION['return'] = array(
  1093. 'type' => 'danger',
  1094. 'msg' => 'MySQL: '.$e
  1095. );
  1096. return false;
  1097. }
  1098. }
  1099. try {
  1100. $stmt = $pdo->prepare("UPDATE `alias` SET
  1101. `modified` = :modified,
  1102. `active` = :active
  1103. WHERE `address` = :address");
  1104. $stmt->execute(array(
  1105. ':address' => $username,
  1106. ':modified' => date('Y-m-d H:i:s'),
  1107. ':active' => $active
  1108. ));
  1109. $stmt = $pdo->prepare("UPDATE `mailbox` SET
  1110. `modified` = :modified,
  1111. `active` = :active,
  1112. `name`= :name,
  1113. `quota` = :quota_b
  1114. WHERE `username` = :username");
  1115. $stmt->execute(array(
  1116. ':active' => $active,
  1117. ':modified' => date('Y-m-d H:i:s'),
  1118. ':name' => $name,
  1119. ':quota_b' => $quota_b,
  1120. ':username' => $username
  1121. ));
  1122. $_SESSION['return'] = array(
  1123. 'type' => 'success',
  1124. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  1125. );
  1126. return true;
  1127. }
  1128. catch (PDOException $e) {
  1129. $_SESSION['return'] = array(
  1130. 'type' => 'danger',
  1131. 'msg' => 'MySQL: '.$e
  1132. );
  1133. return false;
  1134. }
  1135. }
  1136. function mailbox_get_mailboxes($domain = null) {
  1137. global $lang;
  1138. global $pdo;
  1139. $mailboxes = array();
  1140. if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1141. $_SESSION['return'] = array(
  1142. 'type' => 'danger',
  1143. 'msg' => sprintf($lang['danger']['access_denied'])
  1144. );
  1145. return false;
  1146. }
  1147. elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1148. try {
  1149. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` != 'ALL' AND `domain` = :domain");
  1150. $stmt->execute(array(
  1151. ':domain' => $domain,
  1152. ));
  1153. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1154. while($row = array_shift($rows)) {
  1155. $mailboxes[] = $row['username'];
  1156. }
  1157. }
  1158. catch (PDOException $e) {
  1159. $_SESSION['return'] = array(
  1160. 'type' => 'danger',
  1161. 'msg' => 'MySQL: '.$e
  1162. );
  1163. return false;
  1164. }
  1165. }
  1166. else {
  1167. try {
  1168. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role");
  1169. $stmt->execute(array(
  1170. ':username' => $_SESSION['mailcow_cc_username'],
  1171. ':role' => $_SESSION['mailcow_cc_role'],
  1172. ));
  1173. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1174. while($row = array_shift($rows)) {
  1175. $mailboxes[] = $row['username'];
  1176. }
  1177. }
  1178. catch (PDOException $e) {
  1179. $_SESSION['return'] = array(
  1180. 'type' => 'danger',
  1181. 'msg' => 'MySQL: '.$e
  1182. );
  1183. return false;
  1184. }
  1185. }
  1186. return $mailboxes;
  1187. }
  1188. function mailbox_get_alias_domains($domain = null) {
  1189. // Get all domains assigned to mailcow_cc_username or domain, if set
  1190. // Domain admin needs to be active
  1191. // Domain does not need to be active
  1192. global $lang;
  1193. global $pdo;
  1194. $aliasdomains = array();
  1195. if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1196. $_SESSION['return'] = array(
  1197. 'type' => 'danger',
  1198. 'msg' => sprintf($lang['danger']['access_denied'])
  1199. );
  1200. return false;
  1201. }
  1202. elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1203. try {
  1204. $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain");
  1205. $stmt->execute(array(
  1206. ':domain' => $domain,
  1207. ));
  1208. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1209. while($row = array_shift($rows)) {
  1210. $aliasdomains[] = $row['alias_domain'];
  1211. }
  1212. }
  1213. catch (PDOException $e) {
  1214. $_SESSION['return'] = array(
  1215. 'type' => 'danger',
  1216. 'msg' => 'MySQL: '.$e
  1217. );
  1218. return false;
  1219. }
  1220. }
  1221. else {
  1222. try {
  1223. $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");
  1224. $stmt->execute(array(
  1225. ':username' => $_SESSION['mailcow_cc_username'],
  1226. ':role' => $_SESSION['mailcow_cc_role'],
  1227. ));
  1228. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1229. while($row = array_shift($rows)) {
  1230. $aliasdomains[] = $row['alias_domain'];
  1231. }
  1232. }
  1233. catch (PDOException $e) {
  1234. $_SESSION['return'] = array(
  1235. 'type' => 'danger',
  1236. 'msg' => 'MySQL: '.$e
  1237. );
  1238. return false;
  1239. }
  1240. }
  1241. return $aliasdomains;
  1242. }
  1243. function mailbox_get_aliases($domain) {
  1244. global $lang;
  1245. global $pdo;
  1246. $aliases = array();
  1247. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1248. $_SESSION['return'] = array(
  1249. 'type' => 'danger',
  1250. 'msg' => sprintf($lang['danger']['access_denied'])
  1251. );
  1252. return false;
  1253. }
  1254. try {
  1255. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
  1256. $stmt->execute(array(
  1257. ':domain' => $domain,
  1258. ));
  1259. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1260. while($row = array_shift($rows)) {
  1261. $aliases[] = $row['address'];
  1262. }
  1263. }
  1264. catch (PDOException $e) {
  1265. $_SESSION['return'] = array(
  1266. 'type' => 'danger',
  1267. 'msg' => 'MySQL: '.$e
  1268. );
  1269. return false;
  1270. }
  1271. return $aliases;
  1272. }
  1273. function mailbox_get_alias_details($address) {
  1274. global $lang;
  1275. global $pdo;
  1276. $aliasdata = array();
  1277. try {
  1278. $stmt = $pdo->prepare("SELECT
  1279. `domain`,
  1280. `goto`,
  1281. `address`,
  1282. `active` as `active_int`,
  1283. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1284. `created`,
  1285. `modified`
  1286. FROM `alias`
  1287. WHERE `address` = :address AND `address` != `goto`");
  1288. $stmt->execute(array(
  1289. ':address' => $address,
  1290. ));
  1291. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1292. $aliasdata['domain'] = $row['domain'];
  1293. $aliasdata['goto'] = $row['goto'];
  1294. $aliasdata['address'] = $row['address'];
  1295. (!filter_var($aliasdata['address'], FILTER_VALIDATE_EMAIL)) ? $aliasdata['is_catch_all'] = 1 : $aliasdata['is_catch_all'] = 0;
  1296. $aliasdata['active'] = $row['active'];
  1297. $aliasdata['active_int'] = $row['active_int'];
  1298. $aliasdata['created'] = $row['created'];
  1299. $aliasdata['modified'] = $row['modified'];
  1300. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdata['domain'])) {
  1301. $_SESSION['return'] = array(
  1302. 'type' => 'danger',
  1303. 'msg' => sprintf($lang['danger']['access_denied'])
  1304. );
  1305. return false;
  1306. }
  1307. }
  1308. catch (PDOException $e) {
  1309. $_SESSION['return'] = array(
  1310. 'type' => 'danger',
  1311. 'msg' => 'MySQL: '.$e
  1312. );
  1313. return false;
  1314. }
  1315. return $aliasdata;
  1316. }
  1317. function mailbox_get_alias_domain_details($aliasdomain) {
  1318. global $lang;
  1319. global $pdo;
  1320. $aliasdomaindata = array();
  1321. try {
  1322. $stmt = $pdo->prepare("SELECT
  1323. `alias_domain`,
  1324. `target_domain`,
  1325. `active` AS `active_int`,
  1326. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1327. `created`,
  1328. `modified`
  1329. FROM `alias_domain`
  1330. WHERE `alias_domain` = :aliasdomain");
  1331. $stmt->execute(array(
  1332. ':aliasdomain' => $aliasdomain,
  1333. ));
  1334. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1335. $aliasdomaindata['alias_domain'] = $row['alias_domain'];
  1336. $aliasdomaindata['target_domain'] = $row['target_domain'];
  1337. $aliasdomaindata['active'] = $row['active'];
  1338. $aliasdomaindata['active_int'] = $row['active_int'];
  1339. $aliasdomaindata['created'] = $row['created'];
  1340. $aliasdomaindata['modified'] = $row['modified'];
  1341. }
  1342. catch (PDOException $e) {
  1343. $_SESSION['return'] = array(
  1344. 'type' => 'danger',
  1345. 'msg' => 'MySQL: '.$e
  1346. );
  1347. return false;
  1348. }
  1349. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdomaindata['target_domain'])) {
  1350. $_SESSION['return'] = array(
  1351. 'type' => 'danger',
  1352. 'msg' => sprintf($lang['danger']['access_denied'])
  1353. );
  1354. return false;
  1355. }
  1356. return $aliasdomaindata;
  1357. }
  1358. function mailbox_get_domains() {
  1359. // Get all domains assigned to mailcow_cc_username
  1360. // Domain admin needs to be active
  1361. // Domain does not need to be active
  1362. global $lang;
  1363. global $pdo;
  1364. try {
  1365. $domains = array();
  1366. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  1367. WHERE (`domain` IN (
  1368. SELECT `domain` from `domain_admins`
  1369. WHERE (`active`='1' AND `username` = :username))
  1370. )
  1371. OR ('admin'= :role)
  1372. AND `domain` != 'ALL'");
  1373. $stmt->execute(array(
  1374. ':username' => $_SESSION['mailcow_cc_username'],
  1375. ':role' => $_SESSION['mailcow_cc_role'],
  1376. ));
  1377. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1378. while($row = array_shift($rows)) {
  1379. $domains[] = $row['domain'];
  1380. }
  1381. }
  1382. catch (PDOException $e) {
  1383. $_SESSION['return'] = array(
  1384. 'type' => 'danger',
  1385. 'msg' => 'MySQL: '.$e
  1386. );
  1387. return false;
  1388. }
  1389. return $domains;
  1390. }
  1391. function mailbox_get_domain_details($domain) {
  1392. global $lang;
  1393. global $pdo;
  1394. $domaindata = array();
  1395. $domain = idn_to_ascii(strtolower(trim($domain)));
  1396. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1397. $_SESSION['return'] = array(
  1398. 'type' => 'danger',
  1399. 'msg' => sprintf($lang['danger']['access_denied'])
  1400. );
  1401. return false;
  1402. }
  1403. try {
  1404. $stmt = $pdo->prepare("SELECT
  1405. `domain`,
  1406. `description`,
  1407. `aliases`,
  1408. `mailboxes`,
  1409. `maxquota`,
  1410. `quota`,
  1411. `relay_all_recipients` as `relay_all_recipients_int`,
  1412. `backupmx` as `backupmx_int`,
  1413. `active` as `active_int`,
  1414. CASE `relay_all_recipients` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `relay_all_recipients`,
  1415. CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
  1416. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
  1417. FROM `domain` WHERE `domain`= :domain");
  1418. $stmt->execute(array(
  1419. ':domain' => $domain,
  1420. ));
  1421. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1422. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `domain` = :domain");
  1423. $stmt->execute(array(':domain' => $row['domain']));
  1424. $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
  1425. $domaindata['max_new_mailbox_quota'] = ($row['quota'] * 1048576) - $MailboxDataDomain['in_use'];
  1426. if ($domaindata['max_new_mailbox_quota'] > ($row['maxquota'] * 1048576)) {
  1427. $domaindata['max_new_mailbox_quota'] = ($row['maxquota'] * 1048576);
  1428. }
  1429. $domaindata['quota_used_in_domain'] = $MailboxDataDomain['in_use'];
  1430. $domaindata['mboxes_in_domain'] = $MailboxDataDomain['count'];
  1431. $domaindata['mboxes_left'] = $row['mailboxes'] - $MailboxDataDomain['count'];
  1432. $domaindata['domain_name'] = $row['domain'];
  1433. $domaindata['description'] = $row['description'];
  1434. $domaindata['max_num_aliases_for_domain'] = $row['aliases'];
  1435. $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes'];
  1436. $domaindata['max_quota_for_mbox'] = $row['maxquota'] * 1048576;
  1437. $domaindata['max_quota_for_domain'] = $row['quota'] * 1048576;
  1438. $domaindata['backupmx'] = $row['backupmx'];
  1439. $domaindata['backupmx_int'] = $row['backupmx_int'];
  1440. $domaindata['active'] = $row['active'];
  1441. $domaindata['active_int'] = $row['active_int'];
  1442. $domaindata['relay_all_recipients'] = $row['relay_all_recipients'];
  1443. $domaindata['relay_all_recipients_int'] = $row['relay_all_recipients_int'];
  1444. $stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias`
  1445. WHERE `domain`= :domain
  1446. AND `address` NOT IN (
  1447. SELECT `username` FROM `mailbox`
  1448. )");
  1449. $stmt->execute(array(
  1450. ':domain' => $domain,
  1451. ));
  1452. $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
  1453. (isset($AliasData['alias_count'])) ? $domaindata['aliases_in_domain'] = $AliasData['alias_count'] : $domaindata['aliases_in_domain'] = "0";
  1454. }
  1455. catch (PDOException $e) {
  1456. $_SESSION['return'] = array(
  1457. 'type' => 'danger',
  1458. 'msg' => 'MySQL: '.$e
  1459. );
  1460. return false;
  1461. }
  1462. return $domaindata;
  1463. }
  1464. function mailbox_get_mailbox_details($mailbox) {
  1465. global $lang;
  1466. global $pdo;
  1467. $mailboxdata = array();
  1468. try {
  1469. $stmt = $pdo->prepare("SELECT
  1470. `domain`.`backupmx`,
  1471. `mailbox`.`username`,
  1472. `mailbox`.`name`,
  1473. `mailbox`.`active` AS `active_int`,
  1474. CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1475. `mailbox`.`domain`,
  1476. `mailbox`.`quota`,
  1477. `quota2`.`bytes`,
  1478. `quota2`.`messages`
  1479. FROM `mailbox`, `quota2`, `domain`
  1480. WHERE `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox");
  1481. $stmt->execute(array(
  1482. ':mailbox' => $mailbox,
  1483. ));
  1484. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1485. $stmt = $pdo->prepare("SELECT `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain");
  1486. $stmt->execute(array(':domain' => $row['domain']));
  1487. $DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC);
  1488. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `domain` = :domain AND `username` != :username");
  1489. $stmt->execute(array(':domain' => $row['domain'], ':username' => $row['username']));
  1490. $MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC);
  1491. $mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use'];
  1492. if ($mailboxdata['max_new_quota'] > ($DomainQuota['maxquota'] * 1048576)) {
  1493. $mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
  1494. }
  1495. $mailboxdata['username'] = $row['username'];
  1496. $mailboxdata['is_relayed'] = $row['backupmx'];
  1497. $mailboxdata['name'] = $row['name'];
  1498. $mailboxdata['active'] = $row['active'];
  1499. $mailboxdata['active_int'] = $row['active_int'];
  1500. $mailboxdata['domain'] = $row['domain'];
  1501. $mailboxdata['quota'] = $row['quota'];
  1502. $mailboxdata['quota_used'] = intval($row['bytes']);
  1503. $mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
  1504. $mailboxdata['messages'] = $row['messages'];
  1505. if ($mailboxdata['percent_in_use'] >= 90) {
  1506. $mailboxdata['percent_class'] = "danger";
  1507. }
  1508. elseif ($mailboxdata['percent_in_use'] >= 75) {
  1509. $mailboxdata['percent_class'] = "warning";
  1510. }
  1511. else {
  1512. $mailboxdata['percent_class'] = "success";
  1513. }
  1514. }
  1515. catch (PDOException $e) {
  1516. $_SESSION['return'] = array(
  1517. 'type' => 'danger',
  1518. 'msg' => 'MySQL: '.$e
  1519. );
  1520. return false;
  1521. }
  1522. if (!isset($mailboxdata['domain']) ||
  1523. (isset($mailboxdata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailboxdata['domain']))) {
  1524. $_SESSION['return'] = array(
  1525. 'type' => 'danger',
  1526. 'msg' => sprintf($lang['danger']['access_denied'])
  1527. );
  1528. return false;
  1529. }
  1530. return $mailboxdata;
  1531. }
  1532. function mailbox_delete_domain($postarray) {
  1533. global $lang;
  1534. global $pdo;
  1535. $domain = $postarray['domain'];
  1536. if ($_SESSION['mailcow_cc_role'] != "admin") {
  1537. $_SESSION['return'] = array(
  1538. 'type' => 'danger',
  1539. 'msg' => sprintf($lang['danger']['access_denied'])
  1540. );
  1541. return false;
  1542. }
  1543. if (!is_valid_domain_name($domain)) {
  1544. $_SESSION['return'] = array(
  1545. 'type' => 'danger',
  1546. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1547. );
  1548. return false;
  1549. }
  1550. $domain = strtolower(trim($domain));
  1551. try {
  1552. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
  1553. WHERE `domain` = :domain");
  1554. $stmt->execute(array(':domain' => $domain));
  1555. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  1556. }
  1557. catch(PDOException $e) {
  1558. $_SESSION['return'] = array(
  1559. 'type' => 'danger',
  1560. 'msg' => 'MySQL: '.$e
  1561. );
  1562. return false;
  1563. }
  1564. if ($num_results != 0 || !empty($num_results)) {
  1565. $_SESSION['return'] = array(
  1566. 'type' => 'danger',
  1567. 'msg' => sprintf($lang['danger']['domain_not_empty'])
  1568. );
  1569. return false;
  1570. }
  1571. try {
  1572. $stmt = $pdo->prepare("DELETE FROM `domain` WHERE `domain` = :domain");
  1573. $stmt->execute(array(
  1574. ':domain' => $domain,
  1575. ));
  1576. $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `domain` = :domain");
  1577. $stmt->execute(array(
  1578. ':domain' => $domain,
  1579. ));
  1580. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :domain");
  1581. $stmt->execute(array(
  1582. ':domain' => $domain,
  1583. ));
  1584. $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `target_domain` = :domain");
  1585. $stmt->execute(array(
  1586. ':domain' => $domain,
  1587. ));
  1588. $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `domain` = :domain");
  1589. $stmt->execute(array(
  1590. ':domain' => $domain,
  1591. ));
  1592. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` LIKE :domain");
  1593. $stmt->execute(array(
  1594. ':domain' => '%@'.$domain,
  1595. ));
  1596. $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :domain");
  1597. $stmt->execute(array(
  1598. ':domain' => '%@'.$domain,
  1599. ));
  1600. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `address` = :domain");
  1601. $stmt->execute(array(
  1602. ':domain' => '%@'.$domain,
  1603. ));
  1604. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :domain");
  1605. $stmt->execute(array(
  1606. ':domain' => '%@'.$domain,
  1607. ));
  1608. }
  1609. catch (PDOException $e) {
  1610. $_SESSION['return'] = array(
  1611. 'type' => 'danger',
  1612. 'msg' => 'MySQL: '.$e
  1613. );
  1614. return false;
  1615. }
  1616. $_SESSION['return'] = array(
  1617. 'type' => 'success',
  1618. 'msg' => sprintf($lang['success']['domain_removed'], htmlspecialchars($domain))
  1619. );
  1620. return true;
  1621. }
  1622. function mailbox_delete_alias($postarray) {
  1623. global $lang;
  1624. global $pdo;
  1625. $address = $postarray['address'];
  1626. $local_part = strstr($address, '@', true);
  1627. $domain = mailbox_get_alias_details($address)['domain'];
  1628. try {
  1629. $stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :address");
  1630. $stmt->execute(array(':address' => $address));
  1631. $gotos = $stmt->fetch(PDO::FETCH_ASSOC);
  1632. }
  1633. catch(PDOException $e) {
  1634. $_SESSION['return'] = array(
  1635. 'type' => 'danger',
  1636. 'msg' => 'MySQL: '.$e
  1637. );
  1638. return false;
  1639. }
  1640. $goto_array = explode(',', $gotos['goto']);
  1641. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1642. $_SESSION['return'] = array(
  1643. 'type' => 'danger',
  1644. 'msg' => sprintf($lang['danger']['access_denied'])
  1645. );
  1646. return false;
  1647. }
  1648. try {
  1649. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `address` = :address AND `address` NOT IN (SELECT `username` FROM `mailbox`)");
  1650. $stmt->execute(array(
  1651. ':address' => $address
  1652. ));
  1653. }
  1654. catch (PDOException $e) {
  1655. $_SESSION['return'] = array(
  1656. 'type' => 'danger',
  1657. 'msg' => 'MySQL: '.$e
  1658. );
  1659. return false;
  1660. }
  1661. $_SESSION['return'] = array(
  1662. 'type' => 'success',
  1663. 'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars($address))
  1664. );
  1665. }
  1666. function mailbox_delete_alias_domain($postarray) {
  1667. global $lang;
  1668. global $pdo;
  1669. if (!is_valid_domain_name($postarray['alias_domain'])) {
  1670. $_SESSION['return'] = array(
  1671. 'type' => 'danger',
  1672. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1673. );
  1674. return false;
  1675. }
  1676. $alias_domain = $postarray['alias_domain'];
  1677. try {
  1678. $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
  1679. WHERE `alias_domain`= :alias_domain");
  1680. $stmt->execute(array(':alias_domain' => $alias_domain));
  1681. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  1682. }
  1683. catch(PDOException $e) {
  1684. $_SESSION['return'] = array(
  1685. 'type' => 'danger',
  1686. 'msg' => 'MySQL: '.$e
  1687. );
  1688. return false;
  1689. }
  1690. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
  1691. $_SESSION['return'] = array(
  1692. 'type' => 'danger',
  1693. 'msg' => sprintf($lang['danger']['access_denied'])
  1694. );
  1695. return false;
  1696. }
  1697. try {
  1698. $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `alias_domain` = :alias_domain");
  1699. $stmt->execute(array(
  1700. ':alias_domain' => $alias_domain,
  1701. ));
  1702. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :alias_domain");
  1703. $stmt->execute(array(
  1704. ':alias_domain' => $alias_domain,
  1705. ));
  1706. }
  1707. catch (PDOException $e) {
  1708. $_SESSION['return'] = array(
  1709. 'type' => 'danger',
  1710. 'msg' => 'MySQL: '.$e
  1711. );
  1712. return false;
  1713. }
  1714. $_SESSION['return'] = array(
  1715. 'type' => 'success',
  1716. 'msg' => sprintf($lang['success']['alias_domain_removed'], htmlspecialchars($alias_domain))
  1717. );
  1718. }
  1719. function mailbox_delete_mailbox($postarray) {
  1720. global $lang;
  1721. global $pdo;
  1722. $username = $postarray['username'];
  1723. $domain = mailbox_get_mailbox_details($username)['domain'];
  1724. if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
  1725. $_SESSION['return'] = array(
  1726. 'type' => 'danger',
  1727. 'msg' => sprintf($lang['danger']['access_denied'])
  1728. );
  1729. return false;
  1730. }
  1731. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1732. $_SESSION['return'] = array(
  1733. 'type' => 'danger',
  1734. 'msg' => sprintf($lang['danger']['access_denied'])
  1735. );
  1736. return false;
  1737. }
  1738. try {
  1739. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `goto` = :username");
  1740. $stmt->execute(array(
  1741. ':username' => $username
  1742. ));
  1743. $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :username");
  1744. $stmt->execute(array(
  1745. ':username' => $username
  1746. ));
  1747. $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
  1748. $stmt->execute(array(
  1749. ':username' => $username
  1750. ));
  1751. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  1752. $stmt->execute(array(
  1753. ':username' => $username
  1754. ));
  1755. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
  1756. $stmt->execute(array(
  1757. ':username' => $username
  1758. ));
  1759. $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username");
  1760. $stmt->execute(array(
  1761. ':username' => $username
  1762. ));
  1763. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username");
  1764. $stmt->execute(array(
  1765. ':username' => $username
  1766. ));
  1767. $stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
  1768. WHERE `goto` LIKE :username");
  1769. $stmt->execute(array(':username' => '%'.$username.'%'));
  1770. $GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1771. foreach ($GotoData as $gotos) {
  1772. $goto_exploded = explode(',', $gotos['goto']);
  1773. if (($key = array_search($username, $goto_exploded)) !== false) {
  1774. unset($goto_exploded[$key]);
  1775. }
  1776. $gotos_rebuild = implode(',', $goto_exploded);
  1777. $stmt = $pdo->prepare("UPDATE `alias` SET
  1778. `goto` = :goto,
  1779. `modified` = :modified,
  1780. WHERE `address` = :address");
  1781. $stmt->execute(array(
  1782. ':goto' => $gotos_rebuild,
  1783. ':modified' => date('Y-m-d H:i:s'),
  1784. ':address' => $gotos['address']
  1785. ));
  1786. }
  1787. }
  1788. catch (PDOException $e) {
  1789. $_SESSION['return'] = array(
  1790. 'type' => 'danger',
  1791. 'msg' => 'MySQL: '.$e
  1792. );
  1793. return false;
  1794. }
  1795. $_SESSION['return'] = array(
  1796. 'type' => 'success',
  1797. 'msg' => sprintf($lang['success']['mailbox_removed'], htmlspecialchars($username))
  1798. );
  1799. }
  1800. function mailbox_get_sender_acl_handles($mailbox) {
  1801. global $pdo;
  1802. global $lang;
  1803. if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
  1804. $_SESSION['return'] = array(
  1805. 'type' => 'danger',
  1806. 'msg' => sprintf($lang['danger']['access_denied'])
  1807. );
  1808. return false;
  1809. }
  1810. $data['sender_acl_domains']['ro'] = array();
  1811. $data['sender_acl_domains']['rw'] = array();
  1812. $data['sender_acl_domains']['selectable'] = array();
  1813. $data['sender_acl_addresses']['ro'] = array();
  1814. $data['sender_acl_addresses']['rw'] = array();
  1815. $data['sender_acl_addresses']['selectable'] = array();
  1816. $data['fixed_sender_aliases'] = array();
  1817. try {
  1818. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :goto AND `address` NOT LIKE '@%'");
  1819. $stmt->execute(array(':goto' => $mailbox));
  1820. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1821. while ($row = array_shift($rows)) {
  1822. $data['fixed_sender_aliases'][] = $row['address'];
  1823. }
  1824. // Return array $data['sender_acl_domains/addresses']['ro'] with read-only objects
  1825. // Return array $data['sender_acl_domains/addresses']['rw'] with read-write objects (can be deleted)
  1826. $stmt = $pdo->prepare("SELECT REPLACE(`send_as`, '@', '') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` LIKE '@%'");
  1827. $stmt->execute(array(':logged_in_as' => $mailbox));
  1828. $domain_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1829. while ($domain_row = array_shift($domain_rows)) {
  1830. if (is_valid_domain_name($domain_row['send_as']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
  1831. $data['sender_acl_domains']['ro'][] = $domain_row['send_as'];
  1832. continue;
  1833. }
  1834. if (is_valid_domain_name($domain_row['send_as']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
  1835. $data['sender_acl_domains']['rw'][] = $domain_row['send_as'];
  1836. continue;
  1837. }
  1838. }
  1839. $stmt = $pdo->prepare("SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` NOT LIKE '@%'");
  1840. $stmt->execute(array(':logged_in_as' => $mailbox));
  1841. $address_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1842. while ($address_row = array_shift($address_rows)) {
  1843. if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && !hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
  1844. $data['sender_acl_addresses']['ro'][] = $address_row['send_as'];
  1845. continue;
  1846. }
  1847. if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
  1848. $data['sender_acl_addresses']['rw'][] = $address_row['send_as'];
  1849. continue;
  1850. }
  1851. }
  1852. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  1853. WHERE `domain` NOT IN (
  1854. SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
  1855. WHERE `logged_in_as` = :logged_in_as
  1856. AND `send_as` LIKE '@%')");
  1857. $stmt->execute(array(
  1858. ':logged_in_as' => $mailbox,
  1859. ));
  1860. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1861. while ($row = array_shift($rows)) {
  1862. if (is_valid_domain_name($row['domain']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['domain'])) {
  1863. $data['sender_acl_domains']['selectable'][] = $row['domain'];
  1864. }
  1865. }
  1866. $stmt = $pdo->prepare("SELECT `address` FROM `alias`
  1867. WHERE `goto` != :goto
  1868. AND `address` NOT IN (
  1869. SELECT `send_as` FROM `sender_acl`
  1870. WHERE `logged_in_as` = :logged_in_as
  1871. AND `send_as` NOT LIKE '@%')");
  1872. $stmt->execute(array(
  1873. ':logged_in_as' => $mailbox,
  1874. ':goto' => $mailbox
  1875. ));
  1876. while ($row = array_shift($rows)) {
  1877. if (filter_var($row['address'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['address'])) {
  1878. $data['sender_acl_addresses']['selectable'][] = $row['address'];
  1879. }
  1880. }
  1881. }
  1882. catch(PDOException $e) {
  1883. $_SESSION['return'] = array(
  1884. 'type' => 'danger',
  1885. 'msg' => 'MySQL: '.$e
  1886. );
  1887. return false;
  1888. }
  1889. return $data;
  1890. }