mailbox.inc.php 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974
  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 `alias_domain` = :alias_domain, `active` = :active WHERE `alias_domain` = :alias_domain_now");
  623. $stmt->execute(array(
  624. ':alias_domain' => $alias_domain,
  625. ':alias_domain_now' => $alias_domain_now,
  626. ':active' => $active
  627. ));
  628. }
  629. catch (PDOException $e) {
  630. $_SESSION['return'] = array(
  631. 'type' => 'danger',
  632. 'msg' => 'MySQL: '.$e
  633. );
  634. return false;
  635. }
  636. $_SESSION['return'] = array(
  637. 'type' => 'success',
  638. 'msg' => sprintf($lang['success']['aliasd_modified'], htmlspecialchars($alias_domain))
  639. );
  640. }
  641. function mailbox_edit_alias($postarray) {
  642. // Array elements
  643. // address string
  644. // goto string (separated by " ", "," ";" "\n") - email address or domain
  645. // active int
  646. global $lang;
  647. global $pdo;
  648. $address = $postarray['address'];
  649. $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
  650. $local_part = strstr($address, '@', true);
  651. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  652. $_SESSION['return'] = array(
  653. 'type' => 'danger',
  654. 'msg' => sprintf($lang['danger']['access_denied'])
  655. );
  656. return false;
  657. }
  658. if (empty($postarray['goto'])) {
  659. $_SESSION['return'] = array(
  660. 'type' => 'danger',
  661. 'msg' => sprintf($lang['danger']['goto_empty'])
  662. );
  663. return false;
  664. }
  665. $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
  666. foreach ($gotos as &$goto) {
  667. if (empty($goto)) {
  668. continue;
  669. }
  670. if (!filter_var($goto, FILTER_VALIDATE_EMAIL)) {
  671. $_SESSION['return'] = array(
  672. 'type' => 'danger',
  673. 'msg' =>sprintf($lang['danger']['goto_invalid'])
  674. );
  675. return false;
  676. }
  677. if ($goto == $address) {
  678. $_SESSION['return'] = array(
  679. 'type' => 'danger',
  680. 'msg' => sprintf($lang['danger']['alias_goto_identical'])
  681. );
  682. return false;
  683. }
  684. }
  685. $gotos = array_filter($gotos);
  686. $goto = implode(",", $gotos);
  687. isset($postarray['active']) ? $active = '1' : $active = '0';
  688. if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
  689. $_SESSION['return'] = array(
  690. 'type' => 'danger',
  691. 'msg' => sprintf($lang['danger']['alias_invalid'])
  692. );
  693. return false;
  694. }
  695. try {
  696. $stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto, `active`= :active WHERE `address` = :address");
  697. $stmt->execute(array(
  698. ':goto' => $goto,
  699. ':active' => $active,
  700. ':address' => $address
  701. ));
  702. $_SESSION['return'] = array(
  703. 'type' => 'success',
  704. 'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars($address))
  705. );
  706. }
  707. catch (PDOException $e) {
  708. $_SESSION['return'] = array(
  709. 'type' => 'danger',
  710. 'msg' => 'MySQL: '.$e
  711. );
  712. return false;
  713. }
  714. }
  715. function mailbox_edit_domain($postarray) {
  716. // Array elements
  717. // domain string
  718. // description string
  719. // active int
  720. // relay_all_recipients int
  721. // backupmx int
  722. // aliases float
  723. // mailboxes float
  724. // maxquota float
  725. // quota float (Byte)
  726. // active int
  727. global $lang;
  728. global $pdo;
  729. $domain = idn_to_ascii($postarray['domain']);
  730. if (!is_valid_domain_name($domain)) {
  731. $_SESSION['return'] = array(
  732. 'type' => 'danger',
  733. 'msg' => sprintf($lang['danger']['domain_invalid'])
  734. );
  735. return false;
  736. }
  737. if ($_SESSION['mailcow_cc_role'] == "domainadmin" && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  738. $description = $postarray['description'];
  739. isset($postarray['active']) ? $active = '1' : $active = '0';
  740. try {
  741. $stmt = $pdo->prepare("UPDATE `domain` SET
  742. `modified`= :modified,
  743. `description` = :description
  744. WHERE `domain` = :domain");
  745. $stmt->execute(array(
  746. ':modified' => date('Y-m-d H:i:s'),
  747. ':description' => $description,
  748. ':domain' => $domain
  749. ));
  750. $_SESSION['return'] = array(
  751. 'type' => 'success',
  752. 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
  753. );
  754. }
  755. catch (PDOException $e) {
  756. $_SESSION['return'] = array(
  757. 'type' => 'danger',
  758. 'msg' => 'MySQL: '.$e
  759. );
  760. return false;
  761. }
  762. }
  763. elseif ($_SESSION['mailcow_cc_role'] == "admin") {
  764. $description = $postarray['description'];
  765. isset($postarray['active']) ? $active = '1' : $active = '0';
  766. $aliases = filter_var($postarray['aliases'], FILTER_SANITIZE_NUMBER_FLOAT);
  767. $mailboxes = filter_var($postarray['mailboxes'], FILTER_SANITIZE_NUMBER_FLOAT);
  768. $maxquota = filter_var($postarray['maxquota'], FILTER_SANITIZE_NUMBER_FLOAT);
  769. $quota = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
  770. isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
  771. isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
  772. isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
  773. try {
  774. // GET MAILBOX DATA
  775. $stmt = $pdo->prepare("SELECT
  776. COUNT(*) AS count,
  777. MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `maxquota`,
  778. COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota`
  779. FROM `mailbox`
  780. WHERE domain= :domain");
  781. $stmt->execute(array(':domain' => $domain));
  782. $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
  783. // GET ALIAS DATA
  784. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
  785. WHERE domain = :domain
  786. AND address NOT IN (
  787. SELECT `username` FROM `mailbox`
  788. )");
  789. $stmt->execute(array(':domain' => $domain));
  790. $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
  791. }
  792. catch(PDOException $e) {
  793. $_SESSION['return'] = array(
  794. 'type' => 'danger',
  795. 'msg' => 'MySQL: '.$e
  796. );
  797. return false;
  798. }
  799. if ($maxquota > $quota) {
  800. $_SESSION['return'] = array(
  801. 'type' => 'danger',
  802. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
  803. );
  804. return false;
  805. }
  806. if ($MailboxData['maxquota'] > $maxquota) {
  807. echo $MailboxData['maxquota'];
  808. die();
  809. $_SESSION['return'] = array(
  810. 'type' => 'danger',
  811. 'msg' => sprintf($lang['danger']['max_quota_in_use'], $MailboxData['maxquota'])
  812. );
  813. return false;
  814. }
  815. if ($MailboxData['quota'] > $quota) {
  816. $_SESSION['return'] = array(
  817. 'type' => 'danger',
  818. 'msg' => sprintf($lang['danger']['domain_quota_m_in_use'], $MailboxData['quota'])
  819. );
  820. return false;
  821. }
  822. if ($MailboxData['count'] > $mailboxes) {
  823. $_SESSION['return'] = array(
  824. 'type' => 'danger',
  825. 'msg' => sprintf($lang['danger']['mailboxes_in_use'], $MailboxData['count'])
  826. );
  827. return false;
  828. }
  829. if ($AliasData['count'] > $aliases) {
  830. $_SESSION['return'] = array(
  831. 'type' => 'danger',
  832. 'msg' => sprintf($lang['danger']['aliases_in_use'], $AliasData['count'])
  833. );
  834. return false;
  835. }
  836. try {
  837. $stmt = $pdo->prepare("UPDATE `domain` SET
  838. `modified`= :modified,
  839. `relay_all_recipients` = :relay_all_recipients,
  840. `backupmx` = :backupmx,
  841. `active` = :active,
  842. `quota` = :quota,
  843. `maxquota` = :maxquota,
  844. `mailboxes` = :mailboxes,
  845. `aliases` = :aliases,
  846. `description` = :description
  847. WHERE `domain` = :domain");
  848. $stmt->execute(array(
  849. ':relay_all_recipients' => $relay_all_recipients,
  850. ':backupmx' => $backupmx,
  851. ':active' => $active,
  852. ':quota' => $quota,
  853. ':maxquota' => $maxquota,
  854. ':mailboxes' => $mailboxes,
  855. ':aliases' => $aliases,
  856. ':modified' => date('Y-m-d H:i:s'),
  857. ':description' => $description,
  858. ':domain' => $domain
  859. ));
  860. $_SESSION['return'] = array(
  861. 'type' => 'success',
  862. 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
  863. );
  864. }
  865. catch (PDOException $e) {
  866. $_SESSION['return'] = array(
  867. 'type' => 'danger',
  868. 'msg' => 'MySQL: '.$e
  869. );
  870. return false;
  871. }
  872. }
  873. }
  874. function mailbox_edit_mailbox($postarray) {
  875. global $lang;
  876. global $pdo;
  877. isset($postarray['active']) ? $active = '1' : $active = '0';
  878. if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
  879. $_SESSION['return'] = array(
  880. 'type' => 'danger',
  881. 'msg' => sprintf($lang['danger']['username_invalid'])
  882. );
  883. return false;
  884. }
  885. $quota_m = $postarray['quota'];
  886. $quota_b = $quota_m*1048576;
  887. $username = $postarray['username'];
  888. $name = $postarray['name'];
  889. $password = $postarray['password'];
  890. $password2 = $postarray['password2'];
  891. try {
  892. $stmt = $pdo->prepare("SELECT `domain`
  893. FROM `mailbox`
  894. WHERE username = :username");
  895. $stmt->execute(array(':username' => $username));
  896. $MailboxData1 = $stmt->fetch(PDO::FETCH_ASSOC);
  897. $stmt = $pdo->prepare("SELECT
  898. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_now`
  899. FROM `mailbox`
  900. WHERE `username` = :username");
  901. $stmt->execute(array(':username' => $username));
  902. $MailboxData2 = $stmt->fetch(PDO::FETCH_ASSOC);
  903. $stmt = $pdo->prepare("SELECT
  904. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_in_use`
  905. FROM `mailbox`
  906. WHERE `domain` = :domain");
  907. $stmt->execute(array(':domain' => $MailboxData1['domain']));
  908. $MailboxData3 = $stmt->fetch(PDO::FETCH_ASSOC);
  909. $stmt = $pdo->prepare("SELECT `quota`, `maxquota`
  910. FROM `domain`
  911. WHERE `domain` = :domain");
  912. $stmt->execute(array(':domain' => $MailboxData1['domain']));
  913. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  914. }
  915. catch(PDOException $e) {
  916. $_SESSION['return'] = array(
  917. 'type' => 'danger',
  918. 'msg' => 'MySQL: '.$e
  919. );
  920. return false;
  921. }
  922. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $MailboxData1['domain'])) {
  923. $_SESSION['return'] = array(
  924. 'type' => 'danger',
  925. 'msg' => sprintf($lang['danger']['access_denied'])
  926. );
  927. return false;
  928. }
  929. if (!is_numeric($quota_m) || $quota_m == "0") {
  930. $_SESSION['return'] = array(
  931. 'type' => 'danger',
  932. 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'], htmlspecialchars($quota_m))
  933. );
  934. return false;
  935. }
  936. if ($quota_m > $DomainData['maxquota']) {
  937. $_SESSION['return'] = array(
  938. 'type' => 'danger',
  939. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
  940. );
  941. return false;
  942. }
  943. if (($MailboxData3['quota_m_in_use'] - $MailboxData2['quota_m_now'] + $quota_m) > $DomainData['quota']) {
  944. $quota_left_m = ($DomainData['quota'] - $MailboxData3['quota_m_in_use'] + $MailboxData2['quota_m_now']);
  945. $_SESSION['return'] = array(
  946. 'type' => 'danger',
  947. 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
  948. );
  949. return false;
  950. }
  951. // Get sender_acl items set by admin
  952. $sender_acl_admin = array_merge(
  953. mailbox_get_sender_acl_handles($username)['sender_acl_domains']['ro'],
  954. mailbox_get_sender_acl_handles($username)['sender_acl_addresses']['ro']
  955. );
  956. // Get sender_acl items from POST array
  957. (isset($postarray['sender_acl'])) ? $sender_acl_domain_admin = $postarray['sender_acl'] : $sender_acl_domain_admin = array();
  958. if (!empty($sender_acl_domain_admin) || !empty($sender_acl_admin)) {
  959. // Check items in POST array
  960. foreach ($sender_acl_domain_admin as $sender_acl) {
  961. if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name(ltrim($sender_acl, '@'))) {
  962. $_SESSION['return'] = array(
  963. 'type' => 'danger',
  964. 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
  965. );
  966. return false;
  967. }
  968. if (is_valid_domain_name(ltrim($sender_acl, '@'))) {
  969. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], ltrim($sender_acl, '@'))) {
  970. $_SESSION['return'] = array(
  971. 'type' => 'danger',
  972. 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
  973. );
  974. return false;
  975. }
  976. }
  977. if (filter_var($sender_acl, FILTER_VALIDATE_EMAIL)) {
  978. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $sender_acl)) {
  979. $_SESSION['return'] = array(
  980. 'type' => 'danger',
  981. 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
  982. );
  983. return false;
  984. }
  985. }
  986. }
  987. // Merge both arrays
  988. $sender_acl_merged = array_merge($sender_acl_domain_admin, $sender_acl_admin);
  989. try {
  990. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  991. $stmt->execute(array(
  992. ':username' => $username
  993. ));
  994. }
  995. catch (PDOException $e) {
  996. $_SESSION['return'] = array(
  997. 'type' => 'danger',
  998. 'msg' => 'MySQL: '.$e
  999. );
  1000. return false;
  1001. }
  1002. foreach ($sender_acl_merged as $sender_acl) {
  1003. $domain = ltrim($sender_acl, '@');
  1004. if (is_valid_domain_name($domain)) {
  1005. $sender_acl = '@' . $domain;
  1006. }
  1007. try {
  1008. $stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`)
  1009. VALUES (:sender_acl, :username)");
  1010. $stmt->execute(array(
  1011. ':sender_acl' => $sender_acl,
  1012. ':username' => $username
  1013. ));
  1014. }
  1015. catch (PDOException $e) {
  1016. $_SESSION['return'] = array(
  1017. 'type' => 'danger',
  1018. 'msg' => 'MySQL: '.$e
  1019. );
  1020. return false;
  1021. }
  1022. }
  1023. }
  1024. else {
  1025. try {
  1026. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  1027. $stmt->execute(array(
  1028. ':username' => $username
  1029. ));
  1030. }
  1031. catch (PDOException $e) {
  1032. $_SESSION['return'] = array(
  1033. 'type' => 'danger',
  1034. 'msg' => 'MySQL: '.$e
  1035. );
  1036. return false;
  1037. }
  1038. }
  1039. if (!empty($password) && !empty($password2)) {
  1040. if ($password != $password2) {
  1041. $_SESSION['return'] = array(
  1042. 'type' => 'danger',
  1043. 'msg' => sprintf($lang['danger']['password_mismatch'])
  1044. );
  1045. return false;
  1046. }
  1047. $password_hashed = hash_password($password);
  1048. try {
  1049. $stmt = $pdo->prepare("UPDATE `alias` SET
  1050. `modified` = :modified,
  1051. `active` = :active
  1052. WHERE `address` = :address");
  1053. $stmt->execute(array(
  1054. ':address' => $username,
  1055. ':modified' => date('Y-m-d H:i:s'),
  1056. ':active' => $active
  1057. ));
  1058. $stmt = $pdo->prepare("UPDATE `mailbox` SET
  1059. `modified` = :modified,
  1060. `active` = :active,
  1061. `password` = :password_hashed,
  1062. `name`= :name,
  1063. `quota` = :quota_b
  1064. WHERE `username` = :username");
  1065. $stmt->execute(array(
  1066. ':modified' => date('Y-m-d H:i:s'),
  1067. ':password_hashed' => $password_hashed,
  1068. ':active' => $active,
  1069. ':name' => $name,
  1070. ':quota_b' => $quota_b,
  1071. ':username' => $username
  1072. ));
  1073. $_SESSION['return'] = array(
  1074. 'type' => 'success',
  1075. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  1076. );
  1077. return true;
  1078. }
  1079. catch (PDOException $e) {
  1080. $_SESSION['return'] = array(
  1081. 'type' => 'danger',
  1082. 'msg' => 'MySQL: '.$e
  1083. );
  1084. return false;
  1085. }
  1086. }
  1087. try {
  1088. $stmt = $pdo->prepare("UPDATE `alias` SET
  1089. `modified` = :modified,
  1090. `active` = :active
  1091. WHERE `address` = :address");
  1092. $stmt->execute(array(
  1093. ':address' => $username,
  1094. ':modified' => date('Y-m-d H:i:s'),
  1095. ':active' => $active
  1096. ));
  1097. $stmt = $pdo->prepare("UPDATE `mailbox` SET
  1098. `modified` = :modified,
  1099. `active` = :active,
  1100. `name`= :name,
  1101. `quota` = :quota_b
  1102. WHERE `username` = :username");
  1103. $stmt->execute(array(
  1104. ':active' => $active,
  1105. ':modified' => date('Y-m-d H:i:s'),
  1106. ':name' => $name,
  1107. ':quota_b' => $quota_b,
  1108. ':username' => $username
  1109. ));
  1110. $_SESSION['return'] = array(
  1111. 'type' => 'success',
  1112. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  1113. );
  1114. return true;
  1115. }
  1116. catch (PDOException $e) {
  1117. $_SESSION['return'] = array(
  1118. 'type' => 'danger',
  1119. 'msg' => 'MySQL: '.$e
  1120. );
  1121. return false;
  1122. }
  1123. }
  1124. function mailbox_get_mailboxes($domain = null) {
  1125. global $lang;
  1126. global $pdo;
  1127. $mailboxes = array();
  1128. if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1129. $_SESSION['return'] = array(
  1130. 'type' => 'danger',
  1131. 'msg' => sprintf($lang['danger']['access_denied'])
  1132. );
  1133. return false;
  1134. }
  1135. elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1136. try {
  1137. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` != 'ALL' AND `domain` = :domain");
  1138. $stmt->execute(array(
  1139. ':domain' => $domain,
  1140. ));
  1141. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1142. while($row = array_shift($rows)) {
  1143. $mailboxes[] = $row['username'];
  1144. }
  1145. }
  1146. catch (PDOException $e) {
  1147. $_SESSION['return'] = array(
  1148. 'type' => 'danger',
  1149. 'msg' => 'MySQL: '.$e
  1150. );
  1151. return false;
  1152. }
  1153. }
  1154. else {
  1155. try {
  1156. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role");
  1157. $stmt->execute(array(
  1158. ':username' => $_SESSION['mailcow_cc_username'],
  1159. ':role' => $_SESSION['mailcow_cc_role'],
  1160. ));
  1161. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1162. while($row = array_shift($rows)) {
  1163. $mailboxes[] = $row['username'];
  1164. }
  1165. }
  1166. catch (PDOException $e) {
  1167. $_SESSION['return'] = array(
  1168. 'type' => 'danger',
  1169. 'msg' => 'MySQL: '.$e
  1170. );
  1171. return false;
  1172. }
  1173. }
  1174. return $mailboxes;
  1175. }
  1176. function mailbox_get_alias_domains($domain = null) {
  1177. // Get all domains assigned to mailcow_cc_username or domain, if set
  1178. // Domain admin needs to be active
  1179. // Domain does not need to be active
  1180. global $lang;
  1181. global $pdo;
  1182. $aliasdomains = array();
  1183. if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1184. $_SESSION['return'] = array(
  1185. 'type' => 'danger',
  1186. 'msg' => sprintf($lang['danger']['access_denied'])
  1187. );
  1188. return false;
  1189. }
  1190. elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1191. try {
  1192. $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain");
  1193. $stmt->execute(array(
  1194. ':domain' => $domain,
  1195. ));
  1196. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1197. while($row = array_shift($rows)) {
  1198. $aliasdomains[] = $row['alias_domain'];
  1199. }
  1200. }
  1201. catch (PDOException $e) {
  1202. $_SESSION['return'] = array(
  1203. 'type' => 'danger',
  1204. 'msg' => 'MySQL: '.$e
  1205. );
  1206. return false;
  1207. }
  1208. }
  1209. else {
  1210. try {
  1211. $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");
  1212. $stmt->execute(array(
  1213. ':username' => $_SESSION['mailcow_cc_username'],
  1214. ':role' => $_SESSION['mailcow_cc_role'],
  1215. ));
  1216. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1217. while($row = array_shift($rows)) {
  1218. $aliasdomains[] = $row['alias_domain'];
  1219. }
  1220. }
  1221. catch (PDOException $e) {
  1222. $_SESSION['return'] = array(
  1223. 'type' => 'danger',
  1224. 'msg' => 'MySQL: '.$e
  1225. );
  1226. return false;
  1227. }
  1228. }
  1229. return $aliasdomains;
  1230. }
  1231. function mailbox_get_aliases($domain) {
  1232. global $lang;
  1233. global $pdo;
  1234. $aliases = array();
  1235. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1236. $_SESSION['return'] = array(
  1237. 'type' => 'danger',
  1238. 'msg' => sprintf($lang['danger']['access_denied'])
  1239. );
  1240. return false;
  1241. }
  1242. try {
  1243. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
  1244. $stmt->execute(array(
  1245. ':domain' => $domain,
  1246. ));
  1247. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1248. while($row = array_shift($rows)) {
  1249. $aliases[] = $row['address'];
  1250. }
  1251. }
  1252. catch (PDOException $e) {
  1253. $_SESSION['return'] = array(
  1254. 'type' => 'danger',
  1255. 'msg' => 'MySQL: '.$e
  1256. );
  1257. return false;
  1258. }
  1259. return $aliases;
  1260. }
  1261. function mailbox_get_alias_details($address) {
  1262. global $lang;
  1263. global $pdo;
  1264. $aliasdata = array();
  1265. try {
  1266. $stmt = $pdo->prepare("SELECT
  1267. `domain`,
  1268. `goto`,
  1269. `address`,
  1270. `active` as `active_int`,
  1271. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1272. `created`,
  1273. `modified`
  1274. FROM `alias`
  1275. WHERE `address` = :address AND `address` != `goto`");
  1276. $stmt->execute(array(
  1277. ':address' => $address,
  1278. ));
  1279. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1280. $aliasdata['domain'] = $row['domain'];
  1281. $aliasdata['goto'] = $row['goto'];
  1282. $aliasdata['address'] = $row['address'];
  1283. (!filter_var($aliasdata['address'], FILTER_VALIDATE_EMAIL)) ? $aliasdata['is_catch_all'] = 1 : $aliasdata['is_catch_all'] = 0;
  1284. $aliasdata['active'] = $row['active'];
  1285. $aliasdata['active_int'] = $row['active_int'];
  1286. $aliasdata['created'] = $row['created'];
  1287. $aliasdata['modified'] = $row['modified'];
  1288. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdata['domain'])) {
  1289. $_SESSION['return'] = array(
  1290. 'type' => 'danger',
  1291. 'msg' => sprintf($lang['danger']['access_denied'])
  1292. );
  1293. return false;
  1294. }
  1295. }
  1296. catch (PDOException $e) {
  1297. $_SESSION['return'] = array(
  1298. 'type' => 'danger',
  1299. 'msg' => 'MySQL: '.$e
  1300. );
  1301. return false;
  1302. }
  1303. return $aliasdata;
  1304. }
  1305. function mailbox_get_alias_domain_details($aliasdomain) {
  1306. global $lang;
  1307. global $pdo;
  1308. $aliasdomaindata = array();
  1309. try {
  1310. $stmt = $pdo->prepare("SELECT
  1311. `alias_domain`,
  1312. `target_domain`,
  1313. `active` AS `active_int`,
  1314. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1315. `created`,
  1316. `modified`
  1317. FROM `alias_domain`
  1318. WHERE `alias_domain` = :aliasdomain");
  1319. $stmt->execute(array(
  1320. ':aliasdomain' => $aliasdomain,
  1321. ));
  1322. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1323. $aliasdomaindata['alias_domain'] = $row['alias_domain'];
  1324. $aliasdomaindata['target_domain'] = $row['target_domain'];
  1325. $aliasdomaindata['active'] = $row['active'];
  1326. $aliasdomaindata['active_int'] = $row['active_int'];
  1327. $aliasdomaindata['created'] = $row['created'];
  1328. $aliasdomaindata['modified'] = $row['modified'];
  1329. }
  1330. catch (PDOException $e) {
  1331. $_SESSION['return'] = array(
  1332. 'type' => 'danger',
  1333. 'msg' => 'MySQL: '.$e
  1334. );
  1335. return false;
  1336. }
  1337. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdomaindata['target_domain'])) {
  1338. $_SESSION['return'] = array(
  1339. 'type' => 'danger',
  1340. 'msg' => sprintf($lang['danger']['access_denied'])
  1341. );
  1342. return false;
  1343. }
  1344. return $aliasdomaindata;
  1345. }
  1346. function mailbox_get_domains() {
  1347. // Get all domains assigned to mailcow_cc_username
  1348. // Domain admin needs to be active
  1349. // Domain does not need to be active
  1350. global $lang;
  1351. global $pdo;
  1352. try {
  1353. $domains = array();
  1354. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  1355. WHERE (`domain` IN (
  1356. SELECT `domain` from `domain_admins`
  1357. WHERE (`active`='1' AND `username` = :username))
  1358. )
  1359. OR ('admin'= :role)
  1360. AND `domain` != 'ALL'");
  1361. $stmt->execute(array(
  1362. ':username' => $_SESSION['mailcow_cc_username'],
  1363. ':role' => $_SESSION['mailcow_cc_role'],
  1364. ));
  1365. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1366. while($row = array_shift($rows)) {
  1367. $domains[] = $row['domain'];
  1368. }
  1369. }
  1370. catch (PDOException $e) {
  1371. $_SESSION['return'] = array(
  1372. 'type' => 'danger',
  1373. 'msg' => 'MySQL: '.$e
  1374. );
  1375. return false;
  1376. }
  1377. return $domains;
  1378. }
  1379. function mailbox_get_domain_details($domain) {
  1380. global $lang;
  1381. global $pdo;
  1382. $domaindata = array();
  1383. $domain = idn_to_ascii(strtolower(trim($domain)));
  1384. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1385. $_SESSION['return'] = array(
  1386. 'type' => 'danger',
  1387. 'msg' => sprintf($lang['danger']['access_denied'])
  1388. );
  1389. return false;
  1390. }
  1391. try {
  1392. $stmt = $pdo->prepare("SELECT
  1393. `domain`,
  1394. `description`,
  1395. `aliases`,
  1396. `mailboxes`,
  1397. `maxquota`,
  1398. `quota`,
  1399. `relay_all_recipients` as `relay_all_recipients_int`,
  1400. `backupmx` as `backupmx_int`,
  1401. `active` as `active_int`,
  1402. CASE `relay_all_recipients` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `relay_all_recipients`,
  1403. CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
  1404. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
  1405. FROM `domain` WHERE `domain`= :domain");
  1406. $stmt->execute(array(
  1407. ':domain' => $domain,
  1408. ));
  1409. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1410. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `domain` = :domain");
  1411. $stmt->execute(array(':domain' => $row['domain']));
  1412. $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
  1413. $domaindata['max_new_mailbox_quota'] = ($row['quota'] * 1048576) - $MailboxDataDomain['in_use'];
  1414. if ($domaindata['max_new_mailbox_quota'] > ($row['maxquota'] * 1048576)) {
  1415. $domaindata['max_new_mailbox_quota'] = ($row['maxquota'] * 1048576);
  1416. }
  1417. $domaindata['quota_used_in_domain'] = $MailboxDataDomain['in_use'];
  1418. $domaindata['mboxes_in_domain'] = $MailboxDataDomain['count'];
  1419. $domaindata['mboxes_left'] = $row['mailboxes'] - $MailboxDataDomain['count'];
  1420. $domaindata['domain_name'] = $row['domain'];
  1421. $domaindata['description'] = $row['description'];
  1422. $domaindata['max_num_aliases_for_domain'] = $row['aliases'];
  1423. $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes'];
  1424. $domaindata['max_quota_for_mbox'] = $row['maxquota'] * 1048576;
  1425. $domaindata['max_quota_for_domain'] = $row['quota'] * 1048576;
  1426. $domaindata['backupmx'] = $row['backupmx'];
  1427. $domaindata['backupmx_int'] = $row['backupmx_int'];
  1428. $domaindata['active'] = $row['active'];
  1429. $domaindata['active_int'] = $row['active_int'];
  1430. $domaindata['relay_all_recipients'] = $row['relay_all_recipients'];
  1431. $domaindata['relay_all_recipients_int'] = $row['relay_all_recipients_int'];
  1432. $stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias`
  1433. WHERE `domain`= :domain
  1434. AND `address` NOT IN (
  1435. SELECT `username` FROM `mailbox`
  1436. )");
  1437. $stmt->execute(array(
  1438. ':domain' => $domain,
  1439. ));
  1440. $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
  1441. (isset($AliasData['alias_count'])) ? $domaindata['aliases_in_domain'] = $AliasData['alias_count'] : $domaindata['aliases_in_domain'] = "0";
  1442. }
  1443. catch (PDOException $e) {
  1444. $_SESSION['return'] = array(
  1445. 'type' => 'danger',
  1446. 'msg' => 'MySQL: '.$e
  1447. );
  1448. return false;
  1449. }
  1450. return $domaindata;
  1451. }
  1452. function mailbox_get_mailbox_details($mailbox) {
  1453. global $lang;
  1454. global $pdo;
  1455. $mailboxdata = array();
  1456. try {
  1457. $stmt = $pdo->prepare("SELECT
  1458. `domain`.`backupmx`,
  1459. `mailbox`.`username`,
  1460. `mailbox`.`name`,
  1461. `mailbox`.`active` AS `active_int`,
  1462. CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1463. `mailbox`.`domain`,
  1464. `mailbox`.`quota`,
  1465. `quota2`.`bytes`,
  1466. `quota2`.`messages`
  1467. FROM `mailbox`, `quota2`, `domain`
  1468. WHERE `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox");
  1469. $stmt->execute(array(
  1470. ':mailbox' => $mailbox,
  1471. ));
  1472. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1473. $stmt = $pdo->prepare("SELECT `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain");
  1474. $stmt->execute(array(':domain' => $row['domain']));
  1475. $DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC);
  1476. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `domain` = :domain AND `username` != :username");
  1477. $stmt->execute(array(':domain' => $row['domain'], ':username' => $row['username']));
  1478. $MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC);
  1479. $mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use'];
  1480. if ($mailboxdata['max_new_quota'] > ($DomainQuota['maxquota'] * 1048576)) {
  1481. $mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
  1482. }
  1483. $mailboxdata['username'] = $row['username'];
  1484. $mailboxdata['is_relayed'] = $row['backupmx'];
  1485. $mailboxdata['name'] = $row['name'];
  1486. $mailboxdata['active'] = $row['active'];
  1487. $mailboxdata['active_int'] = $row['active_int'];
  1488. $mailboxdata['domain'] = $row['domain'];
  1489. $mailboxdata['quota'] = $row['quota'];
  1490. $mailboxdata['quota_used'] = intval($row['bytes']);
  1491. $mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
  1492. $mailboxdata['messages'] = $row['messages'];
  1493. if ($mailboxdata['percent_in_use'] >= 90) {
  1494. $mailboxdata['percent_class'] = "danger";
  1495. }
  1496. elseif ($mailboxdata['percent_in_use'] >= 75) {
  1497. $mailboxdata['percent_class'] = "warning";
  1498. }
  1499. else {
  1500. $mailboxdata['percent_class'] = "success";
  1501. }
  1502. }
  1503. catch (PDOException $e) {
  1504. $_SESSION['return'] = array(
  1505. 'type' => 'danger',
  1506. 'msg' => 'MySQL: '.$e
  1507. );
  1508. return false;
  1509. }
  1510. if (!isset($mailboxdata['domain']) ||
  1511. (isset($mailboxdata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailboxdata['domain']))) {
  1512. $_SESSION['return'] = array(
  1513. 'type' => 'danger',
  1514. 'msg' => sprintf($lang['danger']['access_denied'])
  1515. );
  1516. return false;
  1517. }
  1518. return $mailboxdata;
  1519. }
  1520. function mailbox_delete_domain($postarray) {
  1521. global $lang;
  1522. global $pdo;
  1523. $domain = $postarray['domain'];
  1524. if ($_SESSION['mailcow_cc_role'] != "admin") {
  1525. $_SESSION['return'] = array(
  1526. 'type' => 'danger',
  1527. 'msg' => sprintf($lang['danger']['access_denied'])
  1528. );
  1529. return false;
  1530. }
  1531. if (!is_valid_domain_name($domain)) {
  1532. $_SESSION['return'] = array(
  1533. 'type' => 'danger',
  1534. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1535. );
  1536. return false;
  1537. }
  1538. $domain = strtolower(trim($domain));
  1539. try {
  1540. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
  1541. WHERE `domain` = :domain");
  1542. $stmt->execute(array(':domain' => $domain));
  1543. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  1544. }
  1545. catch(PDOException $e) {
  1546. $_SESSION['return'] = array(
  1547. 'type' => 'danger',
  1548. 'msg' => 'MySQL: '.$e
  1549. );
  1550. return false;
  1551. }
  1552. if ($num_results != 0 || !empty($num_results)) {
  1553. $_SESSION['return'] = array(
  1554. 'type' => 'danger',
  1555. 'msg' => sprintf($lang['danger']['domain_not_empty'])
  1556. );
  1557. return false;
  1558. }
  1559. try {
  1560. $stmt = $pdo->prepare("DELETE FROM `domain` WHERE `domain` = :domain");
  1561. $stmt->execute(array(
  1562. ':domain' => $domain,
  1563. ));
  1564. $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `domain` = :domain");
  1565. $stmt->execute(array(
  1566. ':domain' => $domain,
  1567. ));
  1568. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :domain");
  1569. $stmt->execute(array(
  1570. ':domain' => $domain,
  1571. ));
  1572. $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `target_domain` = :domain");
  1573. $stmt->execute(array(
  1574. ':domain' => $domain,
  1575. ));
  1576. $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `domain` = :domain");
  1577. $stmt->execute(array(
  1578. ':domain' => $domain,
  1579. ));
  1580. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` LIKE :domain");
  1581. $stmt->execute(array(
  1582. ':domain' => '%@'.$domain,
  1583. ));
  1584. $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :domain");
  1585. $stmt->execute(array(
  1586. ':domain' => '%@'.$domain,
  1587. ));
  1588. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `address` = :domain");
  1589. $stmt->execute(array(
  1590. ':domain' => '%@'.$domain,
  1591. ));
  1592. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :domain");
  1593. $stmt->execute(array(
  1594. ':domain' => '%@'.$domain,
  1595. ));
  1596. }
  1597. catch (PDOException $e) {
  1598. $_SESSION['return'] = array(
  1599. 'type' => 'danger',
  1600. 'msg' => 'MySQL: '.$e
  1601. );
  1602. return false;
  1603. }
  1604. $_SESSION['return'] = array(
  1605. 'type' => 'success',
  1606. 'msg' => sprintf($lang['success']['domain_removed'], htmlspecialchars($domain))
  1607. );
  1608. return true;
  1609. }
  1610. function mailbox_delete_alias($postarray) {
  1611. global $lang;
  1612. global $pdo;
  1613. $address = $postarray['address'];
  1614. $local_part = strstr($address, '@', true);
  1615. $domain = mailbox_get_alias_details($address)['domain'];
  1616. try {
  1617. $stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :address");
  1618. $stmt->execute(array(':address' => $address));
  1619. $gotos = $stmt->fetch(PDO::FETCH_ASSOC);
  1620. }
  1621. catch(PDOException $e) {
  1622. $_SESSION['return'] = array(
  1623. 'type' => 'danger',
  1624. 'msg' => 'MySQL: '.$e
  1625. );
  1626. return false;
  1627. }
  1628. $goto_array = explode(',', $gotos['goto']);
  1629. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1630. $_SESSION['return'] = array(
  1631. 'type' => 'danger',
  1632. 'msg' => sprintf($lang['danger']['access_denied'])
  1633. );
  1634. return false;
  1635. }
  1636. try {
  1637. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `address` = :address AND `address` NOT IN (SELECT `username` FROM `mailbox`)");
  1638. $stmt->execute(array(
  1639. ':address' => $address
  1640. ));
  1641. }
  1642. catch (PDOException $e) {
  1643. $_SESSION['return'] = array(
  1644. 'type' => 'danger',
  1645. 'msg' => 'MySQL: '.$e
  1646. );
  1647. return false;
  1648. }
  1649. $_SESSION['return'] = array(
  1650. 'type' => 'success',
  1651. 'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars($address))
  1652. );
  1653. }
  1654. function mailbox_delete_alias_domain($postarray) {
  1655. global $lang;
  1656. global $pdo;
  1657. if (!is_valid_domain_name($postarray['alias_domain'])) {
  1658. $_SESSION['return'] = array(
  1659. 'type' => 'danger',
  1660. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1661. );
  1662. return false;
  1663. }
  1664. $alias_domain = $postarray['alias_domain'];
  1665. try {
  1666. $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
  1667. WHERE `alias_domain`= :alias_domain");
  1668. $stmt->execute(array(':alias_domain' => $alias_domain));
  1669. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  1670. }
  1671. catch(PDOException $e) {
  1672. $_SESSION['return'] = array(
  1673. 'type' => 'danger',
  1674. 'msg' => 'MySQL: '.$e
  1675. );
  1676. return false;
  1677. }
  1678. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
  1679. $_SESSION['return'] = array(
  1680. 'type' => 'danger',
  1681. 'msg' => sprintf($lang['danger']['access_denied'])
  1682. );
  1683. return false;
  1684. }
  1685. try {
  1686. $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `alias_domain` = :alias_domain");
  1687. $stmt->execute(array(
  1688. ':alias_domain' => $alias_domain,
  1689. ));
  1690. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :alias_domain");
  1691. $stmt->execute(array(
  1692. ':alias_domain' => $alias_domain,
  1693. ));
  1694. }
  1695. catch (PDOException $e) {
  1696. $_SESSION['return'] = array(
  1697. 'type' => 'danger',
  1698. 'msg' => 'MySQL: '.$e
  1699. );
  1700. return false;
  1701. }
  1702. $_SESSION['return'] = array(
  1703. 'type' => 'success',
  1704. 'msg' => sprintf($lang['success']['alias_domain_removed'], htmlspecialchars($alias_domain))
  1705. );
  1706. }
  1707. function mailbox_delete_mailbox($postarray) {
  1708. global $lang;
  1709. global $pdo;
  1710. $username = $postarray['username'];
  1711. $domain = mailbox_get_mailbox_details($username)['domain'];
  1712. if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
  1713. $_SESSION['return'] = array(
  1714. 'type' => 'danger',
  1715. 'msg' => sprintf($lang['danger']['access_denied'])
  1716. );
  1717. return false;
  1718. }
  1719. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1720. $_SESSION['return'] = array(
  1721. 'type' => 'danger',
  1722. 'msg' => sprintf($lang['danger']['access_denied'])
  1723. );
  1724. return false;
  1725. }
  1726. try {
  1727. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `goto` = :username");
  1728. $stmt->execute(array(
  1729. ':username' => $username
  1730. ));
  1731. $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :username");
  1732. $stmt->execute(array(
  1733. ':username' => $username
  1734. ));
  1735. $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
  1736. $stmt->execute(array(
  1737. ':username' => $username
  1738. ));
  1739. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  1740. $stmt->execute(array(
  1741. ':username' => $username
  1742. ));
  1743. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
  1744. $stmt->execute(array(
  1745. ':username' => $username
  1746. ));
  1747. $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username");
  1748. $stmt->execute(array(
  1749. ':username' => $username
  1750. ));
  1751. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username");
  1752. $stmt->execute(array(
  1753. ':username' => $username
  1754. ));
  1755. $stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
  1756. WHERE `goto` LIKE :username");
  1757. $stmt->execute(array(':username' => '%'.$username.'%'));
  1758. $GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1759. foreach ($GotoData as $gotos) {
  1760. $goto_exploded = explode(',', $gotos['goto']);
  1761. if (($key = array_search($username, $goto_exploded)) !== false) {
  1762. unset($goto_exploded[$key]);
  1763. }
  1764. $gotos_rebuild = implode(',', $goto_exploded);
  1765. $stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto WHERE `address` = :address");
  1766. $stmt->execute(array(
  1767. ':goto' => $gotos_rebuild,
  1768. ':address' => $gotos['address']
  1769. ));
  1770. }
  1771. }
  1772. catch (PDOException $e) {
  1773. $_SESSION['return'] = array(
  1774. 'type' => 'danger',
  1775. 'msg' => 'MySQL: '.$e
  1776. );
  1777. return false;
  1778. }
  1779. $_SESSION['return'] = array(
  1780. 'type' => 'success',
  1781. 'msg' => sprintf($lang['success']['mailbox_removed'], htmlspecialchars($username))
  1782. );
  1783. }
  1784. function mailbox_get_sender_acl_handles($mailbox) {
  1785. global $pdo;
  1786. global $lang;
  1787. if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
  1788. $_SESSION['return'] = array(
  1789. 'type' => 'danger',
  1790. 'msg' => sprintf($lang['danger']['access_denied'])
  1791. );
  1792. return false;
  1793. }
  1794. $data['sender_acl_domains']['ro'] = array();
  1795. $data['sender_acl_domains']['rw'] = array();
  1796. $data['sender_acl_domains']['selectable'] = array();
  1797. $data['sender_acl_addresses']['ro'] = array();
  1798. $data['sender_acl_addresses']['rw'] = array();
  1799. $data['sender_acl_addresses']['selectable'] = array();
  1800. $data['fixed_sender_aliases'] = array();
  1801. try {
  1802. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :goto AND `address` NOT LIKE '@%'");
  1803. $stmt->execute(array(':goto' => $mailbox));
  1804. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1805. while ($row = array_shift($rows)) {
  1806. $data['fixed_sender_aliases'][] = $row['address'];
  1807. }
  1808. // Return array $data['sender_acl_domains/addresses']['ro'] with read-only objects
  1809. // Return array $data['sender_acl_domains/addresses']['rw'] with read-write objects (can be deleted)
  1810. $stmt = $pdo->prepare("SELECT REPLACE(`send_as`, '@', '') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` LIKE '@%'");
  1811. $stmt->execute(array(':logged_in_as' => $mailbox));
  1812. $domain_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1813. while ($domain_row = array_shift($domain_rows)) {
  1814. if (is_valid_domain_name($domain_row['send_as']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
  1815. $data['sender_acl_domains']['ro'][] = $domain_row['send_as'];
  1816. continue;
  1817. }
  1818. if (is_valid_domain_name($domain_row['send_as']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
  1819. $data['sender_acl_domains']['rw'][] = $domain_row['send_as'];
  1820. continue;
  1821. }
  1822. }
  1823. $stmt = $pdo->prepare("SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` NOT LIKE '@%'");
  1824. $stmt->execute(array(':logged_in_as' => $mailbox));
  1825. $address_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1826. while ($address_row = array_shift($address_rows)) {
  1827. if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && !hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
  1828. $data['sender_acl_addresses']['ro'][] = $address_row['send_as'];
  1829. continue;
  1830. }
  1831. if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
  1832. $data['sender_acl_addresses']['rw'][] = $address_row['send_as'];
  1833. continue;
  1834. }
  1835. }
  1836. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  1837. WHERE `domain` NOT IN (
  1838. SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
  1839. WHERE `logged_in_as` = :logged_in_as
  1840. AND `send_as` LIKE '@%')");
  1841. $stmt->execute(array(
  1842. ':logged_in_as' => $mailbox,
  1843. ));
  1844. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1845. while ($row = array_shift($rows)) {
  1846. if (is_valid_domain_name($row['domain']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['domain'])) {
  1847. $data['sender_acl_domains']['selectable'][] = $row['domain'];
  1848. }
  1849. }
  1850. $stmt = $pdo->prepare("SELECT `address` FROM `alias`
  1851. WHERE `goto` != :goto
  1852. AND `address` NOT IN (
  1853. SELECT `send_as` FROM `sender_acl`
  1854. WHERE `logged_in_as` = :logged_in_as
  1855. AND `send_as` NOT LIKE '@%')");
  1856. $stmt->execute(array(
  1857. ':logged_in_as' => $mailbox,
  1858. ':goto' => $mailbox
  1859. ));
  1860. while ($row = array_shift($rows)) {
  1861. if (filter_var($row['address'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['address'])) {
  1862. $data['sender_acl_addresses']['selectable'][] = $row['address'];
  1863. }
  1864. }
  1865. }
  1866. catch(PDOException $e) {
  1867. $_SESSION['return'] = array(
  1868. 'type' => 'danger',
  1869. 'msg' => 'MySQL: '.$e
  1870. );
  1871. return false;
  1872. }
  1873. return $data;
  1874. }