functions.inc.php 104 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474
  1. <?php
  2. function hash_password($password) {
  3. $salt_str = bin2hex(openssl_random_pseudo_bytes(8));
  4. return "{SSHA256}".base64_encode(hash('sha256', $password . $salt_str, true) . $salt_str);
  5. }
  6. function hasDomainAccess($username, $role, $domain) {
  7. global $pdo;
  8. if (!filter_var($username, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
  9. return false;
  10. }
  11. if (!is_valid_domain_name($domain)) {
  12. return false;
  13. }
  14. if ($role != 'admin' && $role != 'domainadmin' && $role != 'user') {
  15. return false;
  16. }
  17. try {
  18. $stmt = $pdo->prepare("SELECT `domain` FROM `domain_admins`
  19. WHERE (
  20. `active`='1'
  21. AND `username` = :username
  22. AND `domain` = :domain
  23. )
  24. OR 'admin' = :role");
  25. $stmt->execute(array(':username' => $username, ':domain' => $domain, ':role' => $role));
  26. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  27. } catch(PDOException $e) {
  28. error_log($e);
  29. return false;
  30. }
  31. if ($num_results != 0 && !empty($num_results)) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. function init_db_schema() {
  37. global $pdo;
  38. try {
  39. $stmt = $pdo->prepare("SELECT NULL FROM `admin`, `imapsync`");
  40. $stmt->execute();
  41. }
  42. catch (Exception $e) {
  43. $lines = file('/web/inc/init.sql');
  44. $data = '';
  45. foreach ($lines as $line) {
  46. if (substr($line, 0, 2) == '--' || $line == '') {
  47. continue;
  48. }
  49. $data .= $line;
  50. if (substr(trim($line), -1, 1) == ';') {
  51. $pdo->query($data);
  52. $data = '';
  53. }
  54. }
  55. // Create index if not exists
  56. $stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_folder_id_idx'");
  57. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  58. if ($num_results == 0) {
  59. $pdo->query("CREATE INDEX sogo_acl_c_folder_id_idx ON sogo_acl(c_folder_id)");
  60. }
  61. $stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_uid_idx'");
  62. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  63. if ($num_results == 0) {
  64. $pdo->query("CREATE INDEX sogo_acl_c_uid_idx ON sogo_acl(c_uid)");
  65. }
  66. $_SESSION['return'] = array(
  67. 'type' => 'success',
  68. 'msg' => 'Database initialization completed.'
  69. );
  70. }
  71. // Add newly added columns
  72. $stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'kind'");
  73. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  74. if ($num_results == 0) {
  75. $pdo->query("ALTER TABLE `mailbox` ADD `kind` varchar(100) NOT NULL DEFAULT ''");
  76. }
  77. $stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'multiple_bookings'");
  78. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  79. if ($num_results == 0) {
  80. $pdo->query("ALTER TABLE `mailbox` ADD `multiple_bookings` tinyint(1) NOT NULL DEFAULT '0'");
  81. }
  82. $stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'wants_tagged_subject'");
  83. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  84. if ($num_results == 0) {
  85. $pdo->query("ALTER TABLE `mailbox` ADD `wants_tagged_subject` tinyint(1) NOT NULL DEFAULT '0'");
  86. }
  87. }
  88. function verify_ssha256($hash, $password) {
  89. // Remove tag if any
  90. $hash = ltrim($hash, '{SSHA256}');
  91. // Decode hash
  92. $dhash = base64_decode($hash);
  93. // Get first 32 bytes of binary which equals a SHA256 hash
  94. $ohash = substr($dhash, 0, 32);
  95. // Remove SHA256 hash from decoded hash to get original salt string
  96. $osalt = str_replace($ohash, '', $dhash);
  97. // Check single salted SHA256 hash against extracted hash
  98. if (hash('sha256', $password . $osalt, true) == $ohash) {
  99. return true;
  100. }
  101. else {
  102. return false;
  103. }
  104. }
  105. function doveadm_authenticate($hash, $algorithm, $password) {
  106. $descr = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
  107. $pipes = array();
  108. $process = proc_open("/usr/bin/doveadm pw -s ".$algorithm." -t '".$hash."'", $descr, $pipes);
  109. if (is_resource($process)) {
  110. fputs($pipes[0], $password);
  111. fclose($pipes[0]);
  112. while ($f = fgets($pipes[1])) {
  113. if (preg_match('/(verified)/', $f)) {
  114. proc_close($process);
  115. return true;
  116. }
  117. return false;
  118. }
  119. fclose($pipes[1]);
  120. while ($f = fgets($pipes[2])) {
  121. proc_close($process);
  122. return false;
  123. }
  124. fclose($pipes[2]);
  125. proc_close($process);
  126. }
  127. return false;
  128. }
  129. function check_login($user, $pass) {
  130. global $pdo;
  131. if (!filter_var($user, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $user))) {
  132. return false;
  133. }
  134. $user = strtolower(trim($user));
  135. $stmt = $pdo->prepare("SELECT `password` FROM `admin`
  136. WHERE `superadmin` = '1'
  137. AND `username` = :user");
  138. $stmt->execute(array(':user' => $user));
  139. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  140. foreach ($rows as $row) {
  141. if (verify_ssha256($row['password'], $pass) !== false) {
  142. unset($_SESSION['ldelay']);
  143. return "admin";
  144. }
  145. }
  146. $stmt = $pdo->prepare("SELECT `password` FROM `admin`
  147. WHERE `superadmin` = '0'
  148. AND `active`='1'
  149. AND `username` = :user");
  150. $stmt->execute(array(':user' => $user));
  151. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  152. foreach ($rows as $row) {
  153. if (verify_ssha256($row['password'], $pass) !== false) {
  154. unset($_SESSION['ldelay']);
  155. return "domainadmin";
  156. }
  157. }
  158. $stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
  159. WHERE `active`='1'
  160. AND `username` = :user");
  161. $stmt->execute(array(':user' => $user));
  162. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  163. foreach ($rows as $row) {
  164. if (verify_ssha256($row['password'], $pass) !== false) {
  165. unset($_SESSION['ldelay']);
  166. return "user";
  167. }
  168. }
  169. if (!isset($_SESSION['ldelay'])) {
  170. $_SESSION['ldelay'] = "0";
  171. }
  172. elseif (!isset($_SESSION['mailcow_cc_username'])) {
  173. $_SESSION['ldelay'] = $_SESSION['ldelay']+0.5;
  174. }
  175. sleep($_SESSION['ldelay']);
  176. }
  177. function formatBytes($size, $precision = 2) {
  178. if(!is_numeric($size)) {
  179. return "0";
  180. }
  181. $base = log($size, 1024);
  182. $suffixes = array(' Byte', ' KiB', ' MiB', ' GiB', ' TiB');
  183. if ($size == "0") {
  184. return "0";
  185. }
  186. return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
  187. }
  188. function dkim_table($action, $item) {
  189. global $lang;
  190. switch ($action) {
  191. case "delete":
  192. $domain = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['domain']);
  193. if (!is_valid_domain_name($domain)) {
  194. $_SESSION['return'] = array(
  195. 'type' => 'danger',
  196. 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
  197. );
  198. break;
  199. }
  200. exec('rm ' . escapeshellarg($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim'), $out, $return);
  201. if ($return != "0") {
  202. $_SESSION['return'] = array(
  203. 'type' => 'danger',
  204. 'msg' => sprintf($lang['danger']['dkim_remove_failed'])
  205. );
  206. break;
  207. }
  208. exec('rm ' . escapeshellarg($GLOBALS['MC_DKIM_KEYS'] . '/' . $domain . '.dkim'), $out, $return);
  209. if ($return != "0") {
  210. $_SESSION['return'] = array(
  211. 'type' => 'danger',
  212. 'msg' => sprintf($lang['danger']['dkim_remove_failed'])
  213. );
  214. break;
  215. }
  216. $_SESSION['return'] = array(
  217. 'type' => 'success',
  218. 'msg' => sprintf($lang['success']['dkim_removed'])
  219. );
  220. break;
  221. case "add":
  222. $domain = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['domain']);
  223. $key_length = intval($item['dkim']['key_size']);
  224. if (!is_valid_domain_name($domain) || !is_numeric($key_length)) {
  225. $_SESSION['return'] = array(
  226. 'type' => 'danger',
  227. 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
  228. );
  229. break;
  230. }
  231. if (!empty(glob($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim'))) {
  232. $_SESSION['return'] = array(
  233. 'type' => 'danger',
  234. 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
  235. );
  236. break;
  237. }
  238. $config = array(
  239. "digest_alg" => "sha256",
  240. "private_key_bits" => $key_length,
  241. "private_key_type" => OPENSSL_KEYTYPE_RSA,
  242. );
  243. $keypair_ressource = openssl_pkey_new($config);
  244. $key_details = openssl_pkey_get_details($keypair_ressource);
  245. $pubKey = implode(array_slice(
  246. array_filter(
  247. explode(PHP_EOL, $key_details['key'])
  248. ), 1, -1)
  249. );
  250. // Save public key to file
  251. file_put_contents($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim', $pubKey);
  252. // Save private key to file
  253. openssl_pkey_export_to_file($keypair_ressource, $GLOBALS['MC_DKIM_KEYS'] . '/' . $domain . '.dkim');
  254. $_SESSION['return'] = array(
  255. 'type' => 'success',
  256. 'msg' => sprintf($lang['success']['dkim_added'])
  257. );
  258. break;
  259. }
  260. }
  261. function mailbox_add_domain($postarray) {
  262. // Array elements
  263. // domain string
  264. // description string
  265. // aliases int
  266. // mailboxes int
  267. // maxquota int
  268. // quota int
  269. // active int
  270. // relay_all_recipients int
  271. // backupmx int
  272. global $pdo;
  273. global $lang;
  274. if ($_SESSION['mailcow_cc_role'] != "admin") {
  275. $_SESSION['return'] = array(
  276. 'type' => 'danger',
  277. 'msg' => sprintf($lang['danger']['access_denied'])
  278. );
  279. return false;
  280. }
  281. $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
  282. $description = $postarray['description'];
  283. $aliases = $postarray['aliases'];
  284. $mailboxes = $postarray['mailboxes'];
  285. $maxquota = $postarray['maxquota'];
  286. $quota = $postarray['quota'];
  287. if ($maxquota > $quota) {
  288. $_SESSION['return'] = array(
  289. 'type' => 'danger',
  290. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
  291. );
  292. return false;
  293. }
  294. isset($postarray['active']) ? $active = '1' : $active = '0';
  295. isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
  296. isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
  297. isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
  298. if (!is_valid_domain_name($domain)) {
  299. $_SESSION['return'] = array(
  300. 'type' => 'danger',
  301. 'msg' => sprintf($lang['danger']['domain_invalid'])
  302. );
  303. return false;
  304. }
  305. foreach (array($quota, $maxquota, $mailboxes, $aliases) as $data) {
  306. if (!is_numeric($data)) {
  307. $_SESSION['return'] = array(
  308. 'type' => 'danger',
  309. 'msg' => sprintf($lang['danger']['object_is_not_numeric'], htmlspecialchars($data))
  310. );
  311. return false;
  312. }
  313. }
  314. try {
  315. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  316. WHERE `domain` = :domain");
  317. $stmt->execute(array(':domain' => $domain));
  318. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  319. $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
  320. WHERE `alias_domain` = :domain");
  321. $stmt->execute(array(':domain' => $domain));
  322. $num_results = $num_results + count($stmt->fetchAll(PDO::FETCH_ASSOC));
  323. }
  324. catch(PDOException $e) {
  325. $_SESSION['return'] = array(
  326. 'type' => 'danger',
  327. 'msg' => 'MySQL: '.$e
  328. );
  329. return false;
  330. }
  331. if ($num_results != 0) {
  332. $_SESSION['return'] = array(
  333. 'type' => 'danger',
  334. 'msg' => sprintf($lang['danger']['domain_exists'], htmlspecialchars($domain))
  335. );
  336. return false;
  337. }
  338. try {
  339. $stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `created`, `modified`, `active`, `relay_all_recipients`)
  340. VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :created, :modified, :active, :relay_all_recipients)");
  341. $stmt->execute(array(
  342. ':domain' => $domain,
  343. ':description' => $description,
  344. ':aliases' => $aliases,
  345. ':mailboxes' => $mailboxes,
  346. ':maxquota' => $maxquota,
  347. ':quota' => $quota,
  348. ':backupmx' => $backupmx,
  349. ':active' => $active,
  350. ':created' => date('Y-m-d H:i:s'),
  351. ':modified' => date('Y-m-d H:i:s'),
  352. ':relay_all_recipients' => $relay_all_recipients
  353. ));
  354. $_SESSION['return'] = array(
  355. 'type' => 'success',
  356. 'msg' => sprintf($lang['success']['domain_added'], htmlspecialchars($domain))
  357. );
  358. }
  359. catch (PDOException $e) {
  360. $_SESSION['return'] = array(
  361. 'type' => 'danger',
  362. 'msg' => 'MySQL: '.$e
  363. );
  364. return false;
  365. }
  366. }
  367. function mailbox_add_alias($postarray) {
  368. // Array elements
  369. // address string (separated by " ", "," ";" "\n") - email address or domain
  370. // goto string (separated by " ", "," ";" "\n")
  371. // active int
  372. global $lang;
  373. global $pdo;
  374. $addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['address']));
  375. $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
  376. isset($postarray['active']) ? $active = '1' : $active = '0';
  377. if (empty($addresses[0])) {
  378. $_SESSION['return'] = array(
  379. 'type' => 'danger',
  380. 'msg' => sprintf($lang['danger']['alias_empty'])
  381. );
  382. return false;
  383. }
  384. if (empty($gotos[0])) {
  385. $_SESSION['return'] = array(
  386. 'type' => 'danger',
  387. 'msg' => sprintf($lang['danger']['goto_empty'])
  388. );
  389. return false;
  390. }
  391. foreach ($addresses as $address) {
  392. if (empty($address)) {
  393. continue;
  394. }
  395. $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
  396. $local_part = strstr($address, '@', true);
  397. $address = $local_part.'@'.$domain;
  398. try {
  399. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  400. WHERE `domain`= :domain");
  401. $stmt->execute(array(':domain' => $domain));
  402. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  403. }
  404. catch(PDOException $e) {
  405. $_SESSION['return'] = array(
  406. 'type' => 'danger',
  407. 'msg' => 'MySQL: '.$e
  408. );
  409. return false;
  410. }
  411. if ($num_results == 0) {
  412. $_SESSION['return'] = array(
  413. 'type' => 'danger',
  414. 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
  415. );
  416. return false;
  417. }
  418. if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
  419. $_SESSION['return'] = array(
  420. 'type' => 'danger',
  421. 'msg' => sprintf($lang['danger']['alias_invalid'])
  422. );
  423. return false;
  424. }
  425. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  426. $_SESSION['return'] = array(
  427. 'type' => 'danger',
  428. 'msg' => sprintf($lang['danger']['access_denied'])
  429. );
  430. return false;
  431. }
  432. try {
  433. $stmt = $pdo->prepare("SELECT `address` FROM `alias`
  434. WHERE `address`= :address");
  435. $stmt->execute(array(':address' => $address));
  436. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  437. }
  438. catch(PDOException $e) {
  439. $_SESSION['return'] = array(
  440. 'type' => 'danger',
  441. 'msg' => 'MySQL: '.$e
  442. );
  443. return false;
  444. }
  445. if ($num_results != 0) {
  446. $_SESSION['return'] = array(
  447. 'type' => 'danger',
  448. 'msg' => sprintf($lang['danger']['is_alias_or_mailbox'], htmlspecialchars($address))
  449. );
  450. return false;
  451. }
  452. try {
  453. $stmt = $pdo->prepare("SELECT `address` FROM `spamalias`
  454. WHERE `address`= :address");
  455. $stmt->execute(array(':address' => $address));
  456. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  457. }
  458. catch(PDOException $e) {
  459. $_SESSION['return'] = array(
  460. 'type' => 'danger',
  461. 'msg' => 'MySQL: '.$e
  462. );
  463. return false;
  464. }
  465. if ($num_results != 0) {
  466. $_SESSION['return'] = array(
  467. 'type' => 'danger',
  468. 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($address))
  469. );
  470. return false;
  471. }
  472. foreach ($gotos as &$goto) {
  473. if (empty($goto)) {
  474. continue;
  475. }
  476. $goto_domain = idn_to_ascii(substr(strstr($goto, '@'), 1));
  477. $goto_local_part = strstr($goto, '@', true);
  478. $goto = $goto_local_part.'@'.$goto_domain;
  479. if (!filter_var($goto, FILTER_VALIDATE_EMAIL) === true) {
  480. $_SESSION['return'] = array(
  481. 'type' => 'danger',
  482. 'msg' => sprintf($lang['danger']['goto_invalid'])
  483. );
  484. return false;
  485. }
  486. if ($goto == $address) {
  487. $_SESSION['return'] = array(
  488. 'type' => 'danger',
  489. 'msg' => sprintf($lang['danger']['alias_goto_identical'])
  490. );
  491. return false;
  492. }
  493. }
  494. $gotos = array_filter($gotos);
  495. $goto = implode(",", $gotos);
  496. try {
  497. $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
  498. VALUES (:address, :goto, :domain, :created, :modified, :active)");
  499. if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
  500. $stmt->execute(array(
  501. ':address' => '@'.$domain,
  502. ':goto' => $goto,
  503. ':domain' => $domain,
  504. ':created' => date('Y-m-d H:i:s'),
  505. ':modified' => date('Y-m-d H:i:s'),
  506. ':active' => $active
  507. ));
  508. }
  509. else {
  510. $stmt->execute(array(
  511. ':address' => $address,
  512. ':goto' => $goto,
  513. ':domain' => $domain,
  514. ':created' => date('Y-m-d H:i:s'),
  515. ':modified' => date('Y-m-d H:i:s'),
  516. ':active' => $active
  517. ));
  518. }
  519. $_SESSION['return'] = array(
  520. 'type' => 'success',
  521. 'msg' => sprintf($lang['success']['alias_added'])
  522. );
  523. }
  524. catch (PDOException $e) {
  525. $_SESSION['return'] = array(
  526. 'type' => 'danger',
  527. 'msg' => 'MySQL: '.$e
  528. );
  529. return false;
  530. }
  531. }
  532. $_SESSION['return'] = array(
  533. 'type' => 'success',
  534. 'msg' => sprintf($lang['success']['alias_added'])
  535. );
  536. }
  537. function mailbox_add_alias_domain($postarray) {
  538. // Array elements
  539. // active int
  540. // alias_domain string
  541. // target_domain string
  542. global $lang;
  543. global $pdo;
  544. isset($postarray['active']) ? $active = '1' : $active = '0';
  545. $alias_domain = idn_to_ascii(strtolower(trim($postarray['alias_domain'])));
  546. $target_domain = idn_to_ascii(strtolower(trim($postarray['target_domain'])));
  547. if (!is_valid_domain_name($alias_domain)) {
  548. $_SESSION['return'] = array(
  549. 'type' => 'danger',
  550. 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
  551. );
  552. return false;
  553. }
  554. if (!is_valid_domain_name($target_domain)) {
  555. $_SESSION['return'] = array(
  556. 'type' => 'danger',
  557. 'msg' => sprintf($lang['danger']['target_domain_invalid'])
  558. );
  559. return false;
  560. }
  561. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $target_domain)) {
  562. $_SESSION['return'] = array(
  563. 'type' => 'danger',
  564. 'msg' => sprintf($lang['danger']['access_denied'])
  565. );
  566. return false;
  567. }
  568. if ($alias_domain == $target_domain) {
  569. $_SESSION['return'] = array(
  570. 'type' => 'danger',
  571. 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
  572. );
  573. return false;
  574. }
  575. try {
  576. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  577. WHERE `domain`= :target_domain");
  578. $stmt->execute(array(':target_domain' => $target_domain));
  579. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  580. }
  581. catch(PDOException $e) {
  582. $_SESSION['return'] = array(
  583. 'type' => 'danger',
  584. 'msg' => 'MySQL: '.$e
  585. );
  586. return false;
  587. }
  588. if ($num_results == 0) {
  589. $_SESSION['return'] = array(
  590. 'type' => 'danger',
  591. 'msg' => sprintf($lang['danger']['targetd_not_found'])
  592. );
  593. return false;
  594. }
  595. try {
  596. $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain
  597. UNION
  598. SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain_in_domain");
  599. $stmt->execute(array(':alias_domain' => $alias_domain, ':alias_domain_in_domain' => $alias_domain));
  600. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  601. }
  602. catch(PDOException $e) {
  603. $_SESSION['return'] = array(
  604. 'type' => 'danger',
  605. 'msg' => 'MySQL: '.$e
  606. );
  607. return false;
  608. }
  609. if ($num_results != 0) {
  610. $_SESSION['return'] = array(
  611. 'type' => 'danger',
  612. 'msg' => sprintf($lang['danger']['aliasd_exists'])
  613. );
  614. return false;
  615. }
  616. try {
  617. $stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `created`, `modified`, `active`)
  618. VALUES (:alias_domain, :target_domain, :created, :modified, :active)");
  619. $stmt->execute(array(
  620. ':alias_domain' => $alias_domain,
  621. ':target_domain' => $target_domain,
  622. ':created' => date('Y-m-d H:i:s'),
  623. ':modified' => date('Y-m-d H:i:s'),
  624. ':active' => $active
  625. ));
  626. $_SESSION['return'] = array(
  627. 'type' => 'success',
  628. 'msg' => sprintf($lang['success']['aliasd_added'], htmlspecialchars($alias_domain))
  629. );
  630. }
  631. catch (PDOException $e) {
  632. $_SESSION['return'] = array(
  633. 'type' => 'danger',
  634. 'msg' => 'MySQL: '.$e
  635. );
  636. return false;
  637. }
  638. }
  639. function mailbox_edit_alias_domain($postarray) {
  640. // Array elements
  641. // active int
  642. // alias_domain_now string
  643. // alias_domain string
  644. global $lang;
  645. global $pdo;
  646. isset($postarray['active']) ? $active = '1' : $active = '0';
  647. $alias_domain = idn_to_ascii(strtolower(trim($postarray['alias_domain'])));
  648. $alias_domain_now = strtolower(trim($postarray['alias_domain_now']));
  649. if (!is_valid_domain_name($alias_domain)) {
  650. $_SESSION['return'] = array(
  651. 'type' => 'danger',
  652. 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
  653. );
  654. return false;
  655. }
  656. if (!is_valid_domain_name($alias_domain_now)) {
  657. $_SESSION['return'] = array(
  658. 'type' => 'danger',
  659. 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
  660. );
  661. return false;
  662. }
  663. try {
  664. $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
  665. WHERE `alias_domain`= :alias_domain_now");
  666. $stmt->execute(array(':alias_domain_now' => $alias_domain_now));
  667. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  668. }
  669. catch(PDOException $e) {
  670. $_SESSION['return'] = array(
  671. 'type' => 'danger',
  672. 'msg' => 'MySQL: '.$e
  673. );
  674. return false;
  675. }
  676. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
  677. $_SESSION['return'] = array(
  678. 'type' => 'danger',
  679. 'msg' => sprintf($lang['danger']['access_denied'])
  680. );
  681. return false;
  682. }
  683. try {
  684. $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
  685. WHERE `target_domain`= :alias_domain");
  686. $stmt->execute(array(':alias_domain' => $alias_domain));
  687. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  688. }
  689. catch(PDOException $e) {
  690. $_SESSION['return'] = array(
  691. 'type' => 'danger',
  692. 'msg' => 'MySQL: '.$e
  693. );
  694. return false;
  695. }
  696. if ($num_results != 0) {
  697. $_SESSION['return'] = array(
  698. 'type' => 'danger',
  699. 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
  700. );
  701. return false;
  702. }
  703. try {
  704. $stmt = $pdo->prepare("UPDATE `alias_domain` SET `alias_domain` = :alias_domain, `active` = :active WHERE `alias_domain` = :alias_domain_now");
  705. $stmt->execute(array(
  706. ':alias_domain' => $alias_domain,
  707. ':alias_domain_now' => $alias_domain_now,
  708. ':active' => $active
  709. ));
  710. }
  711. catch (PDOException $e) {
  712. $_SESSION['return'] = array(
  713. 'type' => 'danger',
  714. 'msg' => 'MySQL: '.$e
  715. );
  716. return false;
  717. }
  718. $_SESSION['return'] = array(
  719. 'type' => 'success',
  720. 'msg' => sprintf($lang['success']['aliasd_modified'], htmlspecialchars($alias_domain))
  721. );
  722. }
  723. function mailbox_add_mailbox($postarray) {
  724. // Array elements
  725. // active int
  726. // local_part string
  727. // domain string
  728. // name string (username if empty)
  729. // password string
  730. // password2 string
  731. // quota int (MiB)
  732. // active int
  733. global $pdo;
  734. global $lang;
  735. $local_part = strtolower(trim($postarray['local_part']));
  736. $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
  737. $username = $local_part . '@' . $domain;
  738. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  739. $_SESSION['return'] = array(
  740. 'type' => 'danger',
  741. 'msg' => sprintf($lang['danger']['mailbox_invalid'])
  742. );
  743. return false;
  744. }
  745. if (empty($postarray['local_part'])) {
  746. $_SESSION['return'] = array(
  747. 'type' => 'danger',
  748. 'msg' => sprintf($lang['danger']['mailbox_invalid'])
  749. );
  750. return false;
  751. }
  752. $password = $postarray['password'];
  753. $password2 = $postarray['password2'];
  754. $name = $postarray['name'];
  755. $quota_m = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
  756. if (empty($name)) {
  757. $name = $local_part;
  758. }
  759. isset($postarray['active']) ? $active = '1' : $active = '0';
  760. $quota_b = ($quota_m * 1048576);
  761. $maildir = $domain."/".$local_part."/";
  762. if (!is_valid_domain_name($domain)) {
  763. $_SESSION['return'] = array(
  764. 'type' => 'danger',
  765. 'msg' => sprintf($lang['danger']['domain_invalid'])
  766. );
  767. return false;
  768. }
  769. try {
  770. $stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` FROM `domain`
  771. WHERE `domain` = :domain");
  772. $stmt->execute(array(':domain' => $domain));
  773. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  774. }
  775. catch(PDOException $e) {
  776. $_SESSION['return'] = array(
  777. 'type' => 'danger',
  778. 'msg' => 'MySQL: '.$e
  779. );
  780. return false;
  781. }
  782. try {
  783. $stmt = $pdo->prepare("SELECT
  784. COUNT(*) as count,
  785. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota`
  786. FROM `mailbox`
  787. WHERE `domain` = :domain");
  788. $stmt->execute(array(':domain' => $domain));
  789. $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
  790. }
  791. catch(PDOException $e) {
  792. $_SESSION['return'] = array(
  793. 'type' => 'danger',
  794. 'msg' => 'MySQL: '.$e
  795. );
  796. return false;
  797. }
  798. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  799. $_SESSION['return'] = array(
  800. 'type' => 'danger',
  801. 'msg' => sprintf($lang['danger']['access_denied'])
  802. );
  803. return false;
  804. }
  805. try {
  806. $stmt = $pdo->prepare("SELECT `local_part` FROM `mailbox` WHERE `local_part` = :local_part and `domain`= :domain");
  807. $stmt->execute(array(':local_part' => $local_part, ':domain' => $domain));
  808. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  809. }
  810. catch(PDOException $e) {
  811. $_SESSION['return'] = array(
  812. 'type' => 'danger',
  813. 'msg' => 'MySQL: '.$e
  814. );
  815. return false;
  816. }
  817. if ($num_results != 0) {
  818. $_SESSION['return'] = array(
  819. 'type' => 'danger',
  820. 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
  821. );
  822. return false;
  823. }
  824. try {
  825. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :username");
  826. $stmt->execute(array(':username' => $username));
  827. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  828. }
  829. catch(PDOException $e) {
  830. $_SESSION['return'] = array(
  831. 'type' => 'danger',
  832. 'msg' => 'MySQL: '.$e
  833. );
  834. return false;
  835. }
  836. if ($num_results != 0) {
  837. $_SESSION['return'] = array(
  838. 'type' => 'danger',
  839. 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($username))
  840. );
  841. return false;
  842. }
  843. try {
  844. $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :username");
  845. $stmt->execute(array(':username' => $username));
  846. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  847. }
  848. catch(PDOException $e) {
  849. $_SESSION['return'] = array(
  850. 'type' => 'danger',
  851. 'msg' => 'MySQL: '.$e
  852. );
  853. return false;
  854. }
  855. if ($num_results != 0) {
  856. $_SESSION['return'] = array(
  857. 'type' => 'danger',
  858. 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($username))
  859. );
  860. return false;
  861. }
  862. if (!is_numeric($quota_m) || $quota_m == "0") {
  863. $_SESSION['return'] = array(
  864. 'type' => 'danger',
  865. 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'])
  866. );
  867. return false;
  868. }
  869. if (!empty($password) && !empty($password2)) {
  870. if ($password != $password2) {
  871. $_SESSION['return'] = array(
  872. 'type' => 'danger',
  873. 'msg' => sprintf($lang['danger']['password_mismatch'])
  874. );
  875. return false;
  876. }
  877. $password_hashed = hash_password($password);
  878. }
  879. else {
  880. $_SESSION['return'] = array(
  881. 'type' => 'danger',
  882. 'msg' => sprintf($lang['danger']['password_empty'])
  883. );
  884. return false;
  885. }
  886. if ($MailboxData['count'] >= $DomainData['mailboxes']) {
  887. $_SESSION['return'] = array(
  888. 'type' => 'danger',
  889. 'msg' => sprintf($lang['danger']['max_mailbox_exceeded'], $MailboxData['count'], $DomainData['mailboxes'])
  890. );
  891. return false;
  892. }
  893. try {
  894. $stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain");
  895. $stmt->execute(array(':domain' => $domain));
  896. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  897. }
  898. catch(PDOException $e) {
  899. $_SESSION['return'] = array(
  900. 'type' => 'danger',
  901. 'msg' => 'MySQL: '.$e
  902. );
  903. return false;
  904. }
  905. if ($num_results == 0) {
  906. $_SESSION['return'] = array(
  907. 'type' => 'danger',
  908. 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
  909. );
  910. return false;
  911. }
  912. if ($quota_m > $DomainData['maxquota']) {
  913. $_SESSION['return'] = array(
  914. 'type' => 'danger',
  915. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
  916. );
  917. return false;
  918. }
  919. if (($MailboxData['quota'] + $quota_m) > $DomainData['quota']) {
  920. $quota_left_m = ($DomainData['quota'] - $MailboxData['quota']);
  921. $_SESSION['return'] = array(
  922. 'type' => 'danger',
  923. 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
  924. );
  925. return false;
  926. }
  927. try {
  928. $stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`)
  929. VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :created, :modified, :active)");
  930. $stmt->execute(array(
  931. ':username' => $username,
  932. ':password_hashed' => $password_hashed,
  933. ':name' => $name,
  934. ':maildir' => $maildir,
  935. ':quota_b' => $quota_b,
  936. ':local_part' => $local_part,
  937. ':domain' => $domain,
  938. ':created' => date('Y-m-d H:i:s'),
  939. ':modified' => date('Y-m-d H:i:s'),
  940. ':active' => $active
  941. ));
  942. $stmt = $pdo->prepare("INSERT INTO `quota2` (`username`, `bytes`, `messages`)
  943. VALUES (:username, '0', '0')");
  944. $stmt->execute(array(':username' => $username));
  945. $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
  946. VALUES (:username1, :username2, :domain, :created, :modified, :active)");
  947. $stmt->execute(array(
  948. ':username1' => $username,
  949. ':username2' => $username,
  950. ':domain' => $domain,
  951. ':created' => date('Y-m-d H:i:s'),
  952. ':modified' => date('Y-m-d H:i:s'),
  953. ':active' => $active
  954. ));
  955. $_SESSION['return'] = array(
  956. 'type' => 'success',
  957. 'msg' => sprintf($lang['success']['mailbox_added'], htmlspecialchars($username))
  958. );
  959. }
  960. catch (PDOException $e) {
  961. $_SESSION['return'] = array(
  962. 'type' => 'danger',
  963. 'msg' => 'MySQL: '.$e
  964. );
  965. return false;
  966. }
  967. }
  968. function mailbox_edit_alias($postarray) {
  969. // Array elements
  970. // address string
  971. // goto string (separated by " ", "," ";" "\n") - email address or domain
  972. // active int
  973. global $lang;
  974. global $pdo;
  975. $address = $postarray['address'];
  976. $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
  977. $local_part = strstr($address, '@', true);
  978. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  979. $_SESSION['return'] = array(
  980. 'type' => 'danger',
  981. 'msg' => sprintf($lang['danger']['access_denied'])
  982. );
  983. return false;
  984. }
  985. if (empty($postarray['goto'])) {
  986. $_SESSION['return'] = array(
  987. 'type' => 'danger',
  988. 'msg' => sprintf($lang['danger']['goto_empty'])
  989. );
  990. return false;
  991. }
  992. $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
  993. foreach ($gotos as &$goto) {
  994. if (empty($goto)) {
  995. continue;
  996. }
  997. if (!filter_var($goto, FILTER_VALIDATE_EMAIL)) {
  998. $_SESSION['return'] = array(
  999. 'type' => 'danger',
  1000. 'msg' =>sprintf($lang['danger']['goto_invalid'])
  1001. );
  1002. return false;
  1003. }
  1004. if ($goto == $address) {
  1005. $_SESSION['return'] = array(
  1006. 'type' => 'danger',
  1007. 'msg' => sprintf($lang['danger']['alias_goto_identical'])
  1008. );
  1009. return false;
  1010. }
  1011. }
  1012. $gotos = array_filter($gotos);
  1013. $goto = implode(",", $gotos);
  1014. isset($postarray['active']) ? $active = '1' : $active = '0';
  1015. if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
  1016. $_SESSION['return'] = array(
  1017. 'type' => 'danger',
  1018. 'msg' => sprintf($lang['danger']['alias_invalid'])
  1019. );
  1020. return false;
  1021. }
  1022. try {
  1023. $stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto, `active`= :active WHERE `address` = :address");
  1024. $stmt->execute(array(
  1025. ':goto' => $goto,
  1026. ':active' => $active,
  1027. ':address' => $address
  1028. ));
  1029. $_SESSION['return'] = array(
  1030. 'type' => 'success',
  1031. 'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars($address))
  1032. );
  1033. }
  1034. catch (PDOException $e) {
  1035. $_SESSION['return'] = array(
  1036. 'type' => 'danger',
  1037. 'msg' => 'MySQL: '.$e
  1038. );
  1039. return false;
  1040. }
  1041. }
  1042. function mailbox_edit_domain($postarray) {
  1043. // Array elements
  1044. // domain string
  1045. // description string
  1046. // active int
  1047. // relay_all_recipients int
  1048. // backupmx int
  1049. // aliases float
  1050. // mailboxes float
  1051. // maxquota float
  1052. // quota float (Byte)
  1053. // active int
  1054. global $lang;
  1055. global $pdo;
  1056. $domain = idn_to_ascii($postarray['domain']);
  1057. $description = $postarray['description'];
  1058. $aliases = filter_var($postarray['aliases'], FILTER_SANITIZE_NUMBER_FLOAT);
  1059. $mailboxes = filter_var($postarray['mailboxes'], FILTER_SANITIZE_NUMBER_FLOAT);
  1060. $maxquota = filter_var($postarray['maxquota'], FILTER_SANITIZE_NUMBER_FLOAT);
  1061. $quota = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
  1062. isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
  1063. isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
  1064. isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
  1065. isset($postarray['active']) ? $active = '1' : $active = '0';
  1066. try {
  1067. $stmt = $pdo->prepare("SELECT
  1068. COUNT(*) AS count,
  1069. MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `maxquota`,
  1070. COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota`
  1071. FROM `mailbox`
  1072. WHERE domain= :domain");
  1073. $stmt->execute(array(':domain' => $domain));
  1074. $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
  1075. }
  1076. catch(PDOException $e) {
  1077. $_SESSION['return'] = array(
  1078. 'type' => 'danger',
  1079. 'msg' => 'MySQL: '.$e
  1080. );
  1081. return false;
  1082. }
  1083. try {
  1084. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
  1085. WHERE domain = :domain
  1086. AND address NOT IN (
  1087. SELECT `username` FROM `mailbox`
  1088. )");
  1089. $stmt->execute(array(':domain' => $domain));
  1090. $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
  1091. }
  1092. catch(PDOException $e) {
  1093. $_SESSION['return'] = array(
  1094. 'type' => 'danger',
  1095. 'msg' => 'MySQL: '.$e
  1096. );
  1097. return false;
  1098. }
  1099. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1100. $_SESSION['return'] = array(
  1101. 'type' => 'danger',
  1102. 'msg' => sprintf($lang['danger']['access_denied'])
  1103. );
  1104. return false;
  1105. }
  1106. if ($maxquota > $quota) {
  1107. $_SESSION['return'] = array(
  1108. 'type' => 'danger',
  1109. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
  1110. );
  1111. return false;
  1112. }
  1113. if ($MailboxData['maxquota'] > $maxquota) {
  1114. $_SESSION['return'] = array(
  1115. 'type' => 'danger',
  1116. 'msg' => sprintf($lang['danger']['max_quota_in_use'], $MailboxData['maxquota'])
  1117. );
  1118. return false;
  1119. }
  1120. if ($MailboxData['quota'] > $quota) {
  1121. $_SESSION['return'] = array(
  1122. 'type' => 'danger',
  1123. 'msg' => sprintf($lang['danger']['domain_quota_m_in_use'], $MailboxData['quota'])
  1124. );
  1125. return false;
  1126. }
  1127. if ($MailboxData['count'] > $mailboxes) {
  1128. $_SESSION['return'] = array(
  1129. 'type' => 'danger',
  1130. 'msg' => sprintf($lang['danger']['mailboxes_in_use'], $MailboxData['count'])
  1131. );
  1132. return false;
  1133. }
  1134. if ($AliasData['count'] > $aliases) {
  1135. $_SESSION['return'] = array(
  1136. 'type' => 'danger',
  1137. 'msg' => sprintf($lang['danger']['aliases_in_use'], $AliasData['count'])
  1138. );
  1139. return false;
  1140. }
  1141. if (!is_valid_domain_name($domain)) {
  1142. $_SESSION['return'] = array(
  1143. 'type' => 'danger',
  1144. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1145. );
  1146. return false;
  1147. }
  1148. try {
  1149. $stmt = $pdo->prepare("UPDATE `domain` SET
  1150. `modified`= :modified,
  1151. `relay_all_recipients` = :relay_all_recipients,
  1152. `backupmx` = :backupmx,
  1153. `active` = :active,
  1154. `quota` = :quota,
  1155. `maxquota` = :maxquota,
  1156. `mailboxes` = :mailboxes,
  1157. `aliases` = :aliases,
  1158. `description` = :description
  1159. WHERE `domain` = :domain");
  1160. $stmt->execute(array(
  1161. ':relay_all_recipients' => $relay_all_recipients,
  1162. ':backupmx' => $backupmx,
  1163. ':active' => $active,
  1164. ':quota' => $quota,
  1165. ':maxquota' => $maxquota,
  1166. ':mailboxes' => $mailboxes,
  1167. ':aliases' => $aliases,
  1168. ':modified' => date('Y-m-d H:i:s'),
  1169. ':description' => $description,
  1170. ':domain' => $domain
  1171. ));
  1172. $_SESSION['return'] = array(
  1173. 'type' => 'success',
  1174. 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
  1175. );
  1176. }
  1177. catch (PDOException $e) {
  1178. $_SESSION['return'] = array(
  1179. 'type' => 'danger',
  1180. 'msg' => 'MySQL: '.$e
  1181. );
  1182. return false;
  1183. }
  1184. }
  1185. function mailbox_get_mailboxes($domain) {
  1186. global $lang;
  1187. global $pdo;
  1188. $mailboxes = array();
  1189. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1190. $_SESSION['return'] = array(
  1191. 'type' => 'danger',
  1192. 'msg' => sprintf($lang['danger']['access_denied'])
  1193. );
  1194. return false;
  1195. }
  1196. try {
  1197. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` != 'ALL' AND `domain` = :domain");
  1198. $stmt->execute(array(
  1199. ':domain' => $domain,
  1200. ));
  1201. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1202. while($row = array_shift($rows)) {
  1203. $mailboxes[] = $row['username'];
  1204. }
  1205. }
  1206. catch (PDOException $e) {
  1207. $_SESSION['return'] = array(
  1208. 'type' => 'danger',
  1209. 'msg' => 'MySQL: '.$e
  1210. );
  1211. return false;
  1212. }
  1213. return $mailboxes;
  1214. }
  1215. function mailbox_get_alias_domains($domain) {
  1216. global $lang;
  1217. global $pdo;
  1218. $aliasdomains = array();
  1219. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1220. $_SESSION['return'] = array(
  1221. 'type' => 'danger',
  1222. 'msg' => sprintf($lang['danger']['access_denied'])
  1223. );
  1224. return false;
  1225. }
  1226. try {
  1227. $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain");
  1228. $stmt->execute(array(
  1229. ':domain' => $domain,
  1230. ));
  1231. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1232. while($row = array_shift($rows)) {
  1233. $aliasdomains[] = $row['alias_domain'];
  1234. }
  1235. }
  1236. catch (PDOException $e) {
  1237. $_SESSION['return'] = array(
  1238. 'type' => 'danger',
  1239. 'msg' => 'MySQL: '.$e
  1240. );
  1241. return false;
  1242. }
  1243. return $aliasdomains;
  1244. }
  1245. function mailbox_get_aliases($domain) {
  1246. global $lang;
  1247. global $pdo;
  1248. $aliases = array();
  1249. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1250. $_SESSION['return'] = array(
  1251. 'type' => 'danger',
  1252. 'msg' => sprintf($lang['danger']['access_denied'])
  1253. );
  1254. return false;
  1255. }
  1256. try {
  1257. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
  1258. $stmt->execute(array(
  1259. ':domain' => $domain,
  1260. ));
  1261. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1262. while($row = array_shift($rows)) {
  1263. $aliases[] = $row['address'];
  1264. }
  1265. }
  1266. catch (PDOException $e) {
  1267. $_SESSION['return'] = array(
  1268. 'type' => 'danger',
  1269. 'msg' => 'MySQL: '.$e
  1270. );
  1271. return false;
  1272. }
  1273. return $aliases;
  1274. }
  1275. function mailbox_get_alias_details($address) {
  1276. global $lang;
  1277. global $pdo;
  1278. $aliasdata = array();
  1279. try {
  1280. $stmt = $pdo->prepare("SELECT
  1281. `domain`,
  1282. `goto`,
  1283. `address`,
  1284. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1285. `created`,
  1286. `modified`
  1287. FROM `alias`
  1288. WHERE `address` = :address AND `address` != `goto`");
  1289. $stmt->execute(array(
  1290. ':address' => $address,
  1291. ));
  1292. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1293. while($row = array_shift($rows)) {
  1294. $aliasdata['domain'] = $row['domain'];
  1295. $aliasdata['goto'] = $row['goto'];
  1296. $aliasdata['address'] = $row['address'];
  1297. (!filter_var($aliasdata['address'], FILTER_VALIDATE_EMAIL)) ? $aliasdata['is_catch_all'] = 1 : $aliasdata['is_catch_all'] = 0;
  1298. $aliasdata['active'] = $row['active'];
  1299. $aliasdata['created'] = $row['created'];
  1300. $aliasdata['modified'] = $row['modified'];
  1301. }
  1302. }
  1303. catch (PDOException $e) {
  1304. $_SESSION['return'] = array(
  1305. 'type' => 'danger',
  1306. 'msg' => 'MySQL: '.$e
  1307. );
  1308. return false;
  1309. }
  1310. if (isset($aliasdata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdata['domain'])) {
  1311. $_SESSION['return'] = array(
  1312. 'type' => 'danger',
  1313. 'msg' => sprintf($lang['danger']['access_denied'])
  1314. );
  1315. return false;
  1316. }
  1317. return $aliasdata;
  1318. }
  1319. function mailbox_get_alias_domain_details($aliasdomain) {
  1320. global $lang;
  1321. global $pdo;
  1322. $aliasdomaindata = array();
  1323. try {
  1324. $stmt = $pdo->prepare("SELECT
  1325. `alias_domain`,
  1326. `target_domain`,
  1327. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1328. `created`,
  1329. `modified`
  1330. FROM `alias_domain`
  1331. WHERE `alias_domain` = :aliasdomain");
  1332. $stmt->execute(array(
  1333. ':aliasdomain' => $aliasdomain,
  1334. ));
  1335. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1336. while($row = array_shift($rows)) {
  1337. $aliasdomaindata['alias_domain'] = $row['alias_domain'];
  1338. $aliasdomaindata['target_domain'] = $row['target_domain'];
  1339. $aliasdomaindata['active'] = $row['active'];
  1340. $aliasdomaindata['created'] = $row['created'];
  1341. $aliasdomaindata['modified'] = $row['modified'];
  1342. }
  1343. }
  1344. catch (PDOException $e) {
  1345. $_SESSION['return'] = array(
  1346. 'type' => 'danger',
  1347. 'msg' => 'MySQL: '.$e
  1348. );
  1349. return false;
  1350. }
  1351. if (isset($aliasdomaindata['target_domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdomaindata['target_domain'])) {
  1352. $_SESSION['return'] = array(
  1353. 'type' => 'danger',
  1354. 'msg' => sprintf($lang['danger']['access_denied'])
  1355. );
  1356. return false;
  1357. }
  1358. return $aliasdomaindata;
  1359. }
  1360. function mailbox_get_domains() {
  1361. global $lang;
  1362. global $pdo;
  1363. try {
  1364. $domains = array();
  1365. $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
  1366. WHERE (`domain` IN (
  1367. SELECT `domain` from `domain_admins`
  1368. WHERE (`active`='1' AND `username` = :username))
  1369. )
  1370. OR ('admin'= :role)
  1371. AND `domain` != 'ALL'");
  1372. $stmt->execute(array(
  1373. ':username' => $_SESSION['mailcow_cc_username'],
  1374. ':role' => $_SESSION['mailcow_cc_role'],
  1375. ));
  1376. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1377. while($row = array_shift($rows)) {
  1378. $domains[] = $row['domain'];
  1379. }
  1380. }
  1381. catch (PDOException $e) {
  1382. $_SESSION['return'] = array(
  1383. 'type' => 'danger',
  1384. 'msg' => 'MySQL: '.$e
  1385. );
  1386. return false;
  1387. }
  1388. return $domains;
  1389. }
  1390. function mailbox_get_domain_details($domain) {
  1391. global $lang;
  1392. global $pdo;
  1393. $domain = idn_to_ascii(strtolower(trim($domain)));
  1394. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1395. $_SESSION['return'] = array(
  1396. 'type' => 'danger',
  1397. 'msg' => sprintf($lang['danger']['access_denied'])
  1398. );
  1399. return false;
  1400. }
  1401. try {
  1402. $stmt = $pdo->prepare("SELECT
  1403. `domain`,
  1404. `aliases`,
  1405. `mailboxes`,
  1406. `maxquota`,
  1407. `quota`,
  1408. CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
  1409. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
  1410. FROM `domain` WHERE `domain`= :domain");
  1411. $stmt->execute(array(
  1412. ':domain' => $domain,
  1413. ));
  1414. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1415. while($row = array_shift($rows)) {
  1416. $domaindata['domain_name'] = $row['domain'];
  1417. $domaindata['max_num_aliases_for_domain'] = $row['aliases'];
  1418. $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes'];
  1419. $domaindata['max_quota_for_mbox'] = formatBytes(intval($row['maxquota'] * 1048576), 2);
  1420. $domaindata['max_quota_for_domain'] = formatBytes(intval($row['quota'] * 1048576), 2);
  1421. $domaindata['backupmx'] = $row['backupmx'];
  1422. $domaindata['active'] = $row['active'];
  1423. }
  1424. $stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias`
  1425. WHERE `domain`= :domain
  1426. AND `address` NOT IN (
  1427. SELECT `username` FROM `mailbox`
  1428. )");
  1429. $stmt->execute(array(
  1430. ':domain' => $domain,
  1431. ));
  1432. $row = $stmt->fetchAll();
  1433. $domaindata['aliases_in_domain'] = $row[0]['alias_count'];
  1434. $stmt = $pdo->prepare("SELECT COUNT(`username`) AS `mailbox_count`, SUM(`quota`) AS `quota` FROM `mailbox`
  1435. WHERE `domain` = :domain");
  1436. $stmt->execute(array(
  1437. ':domain' => $domain,
  1438. ));
  1439. $row = $stmt->fetchAll();
  1440. $domaindata['mboxes_in_domain'] = $row[0]['mailbox_count'];
  1441. $domaindata['quota_used_in_domain'] = formatBytes(intval($row[0]['quota']), 2);
  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. try {
  1456. $stmt = $pdo->prepare("SELECT
  1457. `domain`.`backupmx`,
  1458. `mailbox`.`username`,
  1459. `mailbox`.`name`,
  1460. CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  1461. `mailbox`.`domain`,
  1462. `mailbox`.`quota`,
  1463. `quota2`.`bytes`,
  1464. `quota2`.`messages`
  1465. FROM `mailbox`, `quota2`, `domain`
  1466. WHERE `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox");
  1467. $stmt->execute(array(
  1468. ':mailbox' => $mailbox,
  1469. ));
  1470. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1471. while($row = array_shift($rows)) {
  1472. $mailboxdata['username'] = $row['username'];
  1473. $mailboxdata['is_relayed'] = $row['backupmx'];
  1474. $mailboxdata['name'] = $row['name'];
  1475. $mailboxdata['active'] = $row['active'];
  1476. $mailboxdata['domain'] = $row['domain'];
  1477. $mailboxdata['quota'] = formatBytes(intval($row['quota']), 2);
  1478. $mailboxdata['quota_used'] = formatBytes(intval($row['bytes']), 2);
  1479. $mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
  1480. $mailboxdata['messages'] = $row['messages'];
  1481. if ($mailboxdata['percent_in_use'] >= 90) {
  1482. $mailboxdata['percent_class'] = "danger";
  1483. }
  1484. elseif ($mailboxdata['percent_in_use'] >= 75) {
  1485. $mailboxdata['percent_class'] = "warning";
  1486. }
  1487. else {
  1488. $mailboxdata['percent_class'] = "success";
  1489. }
  1490. }
  1491. }
  1492. catch (PDOException $e) {
  1493. $_SESSION['return'] = array(
  1494. 'type' => 'danger',
  1495. 'msg' => 'MySQL: '.$e
  1496. );
  1497. return false;
  1498. }
  1499. if (isset($mailboxdata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailboxdata['domain'])) {
  1500. $_SESSION['return'] = array(
  1501. 'type' => 'danger',
  1502. 'msg' => sprintf($lang['danger']['access_denied'])
  1503. );
  1504. return false;
  1505. }
  1506. return $mailboxdata;
  1507. }
  1508. function mailbox_edit_mailbox($postarray) {
  1509. global $lang;
  1510. global $pdo;
  1511. isset($postarray['active']) ? $active = '1' : $active = '0';
  1512. if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
  1513. $_SESSION['return'] = array(
  1514. 'type' => 'danger',
  1515. 'msg' => sprintf($lang['danger']['username_invalid'])
  1516. );
  1517. return false;
  1518. }
  1519. $quota_m = $postarray['quota'];
  1520. $quota_b = $quota_m*1048576;
  1521. $username = $postarray['username'];
  1522. $name = $postarray['name'];
  1523. $password = $postarray['password'];
  1524. $password2 = $postarray['password2'];
  1525. try {
  1526. $stmt = $pdo->prepare("SELECT `domain`
  1527. FROM `mailbox`
  1528. WHERE username = :username");
  1529. $stmt->execute(array(':username' => $username));
  1530. $MailboxData1 = $stmt->fetch(PDO::FETCH_ASSOC);
  1531. $stmt = $pdo->prepare("SELECT
  1532. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_now`
  1533. FROM `mailbox`
  1534. WHERE `username` = :username");
  1535. $stmt->execute(array(':username' => $username));
  1536. $MailboxData2 = $stmt->fetch(PDO::FETCH_ASSOC);
  1537. $stmt = $pdo->prepare("SELECT
  1538. COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_in_use`
  1539. FROM `mailbox`
  1540. WHERE `domain` = :domain");
  1541. $stmt->execute(array(':domain' => $MailboxData1['domain']));
  1542. $MailboxData3 = $stmt->fetch(PDO::FETCH_ASSOC);
  1543. $stmt = $pdo->prepare("SELECT `quota`, `maxquota`
  1544. FROM `domain`
  1545. WHERE `domain` = :domain");
  1546. $stmt->execute(array(':domain' => $MailboxData1['domain']));
  1547. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  1548. }
  1549. catch(PDOException $e) {
  1550. $_SESSION['return'] = array(
  1551. 'type' => 'danger',
  1552. 'msg' => 'MySQL: '.$e
  1553. );
  1554. return false;
  1555. }
  1556. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $MailboxData1['domain'])) {
  1557. $_SESSION['return'] = array(
  1558. 'type' => 'danger',
  1559. 'msg' => sprintf($lang['danger']['access_denied'])
  1560. );
  1561. return false;
  1562. }
  1563. if (!is_numeric($quota_m) || $quota_m == "0") {
  1564. $_SESSION['return'] = array(
  1565. 'type' => 'danger',
  1566. 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'], htmlspecialchars($quota_m))
  1567. );
  1568. return false;
  1569. }
  1570. if ($quota_m > $DomainData['maxquota']) {
  1571. $_SESSION['return'] = array(
  1572. 'type' => 'danger',
  1573. 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
  1574. );
  1575. return false;
  1576. }
  1577. if (($MailboxData3['quota_m_in_use'] - $MailboxData2['quota_m_now'] + $quota_m) > $DomainData['quota']) {
  1578. $quota_left_m = ($DomainData['quota'] - $MailboxData3['quota_m_in_use'] + $MailboxData2['quota_m_now']);
  1579. $_SESSION['return'] = array(
  1580. 'type' => 'danger',
  1581. 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
  1582. );
  1583. return false;
  1584. }
  1585. try {
  1586. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  1587. $stmt->execute(array(
  1588. ':username' => $username
  1589. ));
  1590. }
  1591. catch (PDOException $e) {
  1592. $_SESSION['return'] = array(
  1593. 'type' => 'danger',
  1594. 'msg' => 'MySQL: '.$e
  1595. );
  1596. return false;
  1597. }
  1598. if (isset($postarray['sender_acl']) && is_array($postarray['sender_acl'])) {
  1599. foreach ($postarray['sender_acl'] as $sender_acl) {
  1600. if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) &&
  1601. !is_valid_domain_name(str_replace('@', '', $sender_acl))) {
  1602. $_SESSION['return'] = array(
  1603. 'type' => 'danger',
  1604. 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
  1605. );
  1606. return false;
  1607. }
  1608. }
  1609. foreach ($postarray['sender_acl'] as $sender_acl) {
  1610. try {
  1611. $stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`)
  1612. VALUES (:sender_acl, :username)");
  1613. $stmt->execute(array(
  1614. ':sender_acl' => $sender_acl,
  1615. ':username' => $username
  1616. ));
  1617. }
  1618. catch (PDOException $e) {
  1619. $_SESSION['return'] = array(
  1620. 'type' => 'danger',
  1621. 'msg' => 'MySQL: '.$e
  1622. );
  1623. return false;
  1624. }
  1625. }
  1626. }
  1627. if (!empty($password) && !empty($password2)) {
  1628. if ($password != $password2) {
  1629. $_SESSION['return'] = array(
  1630. 'type' => 'danger',
  1631. 'msg' => sprintf($lang['danger']['password_mismatch'])
  1632. );
  1633. return false;
  1634. }
  1635. $password_hashed = hash_password($password);
  1636. try {
  1637. $stmt = $pdo->prepare("UPDATE `alias` SET
  1638. `modified` = :modified,
  1639. `active` = :active
  1640. WHERE `address` = :address");
  1641. $stmt->execute(array(
  1642. ':address' => $username,
  1643. ':modified' => date('Y-m-d H:i:s'),
  1644. ':active' => $active
  1645. ));
  1646. $stmt = $pdo->prepare("UPDATE `mailbox` SET
  1647. `modified` = :modified,
  1648. `active` = :active,
  1649. `password` = :password_hashed,
  1650. `name`= :name,
  1651. `quota` = :quota_b
  1652. WHERE `username` = :username");
  1653. $stmt->execute(array(
  1654. ':modified' => date('Y-m-d H:i:s'),
  1655. ':password_hashed' => $password_hashed,
  1656. ':active' => $active,
  1657. ':name' => $name,
  1658. ':quota_b' => $quota_b,
  1659. ':username' => $username
  1660. ));
  1661. $_SESSION['return'] = array(
  1662. 'type' => 'success',
  1663. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  1664. );
  1665. return true;
  1666. }
  1667. catch (PDOException $e) {
  1668. $_SESSION['return'] = array(
  1669. 'type' => 'danger',
  1670. 'msg' => 'MySQL: '.$e
  1671. );
  1672. return false;
  1673. }
  1674. }
  1675. try {
  1676. $stmt = $pdo->prepare("UPDATE `alias` SET
  1677. `modified` = :modified,
  1678. `active` = :active
  1679. WHERE `address` = :address");
  1680. $stmt->execute(array(
  1681. ':address' => $username,
  1682. ':modified' => date('Y-m-d H:i:s'),
  1683. ':active' => $active
  1684. ));
  1685. $stmt = $pdo->prepare("UPDATE `mailbox` SET
  1686. `modified` = :modified,
  1687. `active` = :active,
  1688. `name`= :name,
  1689. `quota` = :quota_b
  1690. WHERE `username` = :username");
  1691. $stmt->execute(array(
  1692. ':active' => $active,
  1693. ':modified' => date('Y-m-d H:i:s'),
  1694. ':name' => $name,
  1695. ':quota_b' => $quota_b,
  1696. ':username' => $username
  1697. ));
  1698. $_SESSION['return'] = array(
  1699. 'type' => 'success',
  1700. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  1701. );
  1702. return true;
  1703. }
  1704. catch (PDOException $e) {
  1705. $_SESSION['return'] = array(
  1706. 'type' => 'danger',
  1707. 'msg' => 'MySQL: '.$e
  1708. );
  1709. return false;
  1710. }
  1711. }
  1712. function mailbox_delete_domain($postarray) {
  1713. global $lang;
  1714. global $pdo;
  1715. $domain = $postarray['domain'];
  1716. if ($_SESSION['mailcow_cc_role'] != "admin") {
  1717. $_SESSION['return'] = array(
  1718. 'type' => 'danger',
  1719. 'msg' => sprintf($lang['danger']['access_denied'])
  1720. );
  1721. return false;
  1722. }
  1723. if (!is_valid_domain_name($domain)) {
  1724. $_SESSION['return'] = array(
  1725. 'type' => 'danger',
  1726. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1727. );
  1728. return false;
  1729. }
  1730. $domain = strtolower(trim($domain));
  1731. try {
  1732. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
  1733. WHERE `domain` = :domain");
  1734. $stmt->execute(array(':domain' => $domain));
  1735. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  1736. }
  1737. catch(PDOException $e) {
  1738. $_SESSION['return'] = array(
  1739. 'type' => 'danger',
  1740. 'msg' => 'MySQL: '.$e
  1741. );
  1742. return false;
  1743. }
  1744. if ($num_results != 0 || !empty($num_results)) {
  1745. $_SESSION['return'] = array(
  1746. 'type' => 'danger',
  1747. 'msg' => sprintf($lang['danger']['domain_not_empty'])
  1748. );
  1749. return false;
  1750. }
  1751. try {
  1752. $stmt = $pdo->prepare("DELETE FROM `domain` WHERE `domain` = :domain");
  1753. $stmt->execute(array(
  1754. ':domain' => $domain,
  1755. ));
  1756. $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `domain` = :domain");
  1757. $stmt->execute(array(
  1758. ':domain' => $domain,
  1759. ));
  1760. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :domain");
  1761. $stmt->execute(array(
  1762. ':domain' => $domain,
  1763. ));
  1764. $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `target_domain` = :domain");
  1765. $stmt->execute(array(
  1766. ':domain' => $domain,
  1767. ));
  1768. $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `domain` = :domain");
  1769. $stmt->execute(array(
  1770. ':domain' => $domain,
  1771. ));
  1772. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` LIKE :domain");
  1773. $stmt->execute(array(
  1774. ':domain' => '%@'.$domain,
  1775. ));
  1776. $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :domain");
  1777. $stmt->execute(array(
  1778. ':domain' => '%@'.$domain,
  1779. ));
  1780. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `address` = :domain");
  1781. $stmt->execute(array(
  1782. ':domain' => '%@'.$domain,
  1783. ));
  1784. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :domain");
  1785. $stmt->execute(array(
  1786. ':domain' => '%@'.$domain,
  1787. ));
  1788. }
  1789. catch (PDOException $e) {
  1790. $_SESSION['return'] = array(
  1791. 'type' => 'danger',
  1792. 'msg' => 'MySQL: '.$e
  1793. );
  1794. return false;
  1795. }
  1796. $_SESSION['return'] = array(
  1797. 'type' => 'success',
  1798. 'msg' => sprintf($lang['success']['domain_removed'], htmlspecialchars($domain))
  1799. );
  1800. return true;
  1801. }
  1802. function mailbox_delete_alias($postarray) {
  1803. global $lang;
  1804. global $pdo;
  1805. $address = $postarray['address'];
  1806. $local_part = strstr($address, '@', true);
  1807. $domain = substr(strrchr($address, "@"), 1);
  1808. try {
  1809. $stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :address");
  1810. $stmt->execute(array(':address' => $address));
  1811. $gotos = $stmt->fetch(PDO::FETCH_ASSOC);
  1812. }
  1813. catch(PDOException $e) {
  1814. $_SESSION['return'] = array(
  1815. 'type' => 'danger',
  1816. 'msg' => 'MySQL: '.$e
  1817. );
  1818. return false;
  1819. }
  1820. $goto_array = explode(',', $gotos['goto']);
  1821. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1822. $_SESSION['return'] = array(
  1823. 'type' => 'danger',
  1824. 'msg' => sprintf($lang['danger']['access_denied'])
  1825. );
  1826. return false;
  1827. }
  1828. try {
  1829. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `address` = :address AND `address` NOT IN (SELECT `username` FROM `mailbox`)");
  1830. $stmt->execute(array(
  1831. ':address' => $address
  1832. ));
  1833. }
  1834. catch (PDOException $e) {
  1835. $_SESSION['return'] = array(
  1836. 'type' => 'danger',
  1837. 'msg' => 'MySQL: '.$e
  1838. );
  1839. return false;
  1840. }
  1841. $_SESSION['return'] = array(
  1842. 'type' => 'success',
  1843. 'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars($address))
  1844. );
  1845. }
  1846. function mailbox_delete_alias_domain($postarray) {
  1847. global $lang;
  1848. global $pdo;
  1849. if (!is_valid_domain_name($postarray['alias_domain'])) {
  1850. $_SESSION['return'] = array(
  1851. 'type' => 'danger',
  1852. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1853. );
  1854. return false;
  1855. }
  1856. $alias_domain = $postarray['alias_domain'];
  1857. try {
  1858. $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
  1859. WHERE `alias_domain`= :alias_domain");
  1860. $stmt->execute(array(':alias_domain' => $alias_domain));
  1861. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  1862. }
  1863. catch(PDOException $e) {
  1864. $_SESSION['return'] = array(
  1865. 'type' => 'danger',
  1866. 'msg' => 'MySQL: '.$e
  1867. );
  1868. return false;
  1869. }
  1870. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
  1871. $_SESSION['return'] = array(
  1872. 'type' => 'danger',
  1873. 'msg' => sprintf($lang['danger']['access_denied'])
  1874. );
  1875. return false;
  1876. }
  1877. try {
  1878. $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `alias_domain` = :alias_domain");
  1879. $stmt->execute(array(
  1880. ':alias_domain' => $alias_domain,
  1881. ));
  1882. }
  1883. catch (PDOException $e) {
  1884. $_SESSION['return'] = array(
  1885. 'type' => 'danger',
  1886. 'msg' => 'MySQL: '.$e
  1887. );
  1888. return false;
  1889. }
  1890. $_SESSION['return'] = array(
  1891. 'type' => 'success',
  1892. 'msg' => sprintf($lang['success']['alias_domain_removed'], htmlspecialchars($alias_domain))
  1893. );
  1894. }
  1895. function mailbox_delete_mailbox($postarray) {
  1896. global $lang;
  1897. global $pdo;
  1898. $domain = substr(strrchr($postarray['username'], "@"), 1);
  1899. $username = $postarray['username'];
  1900. if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
  1901. $_SESSION['return'] = array(
  1902. 'type' => 'danger',
  1903. 'msg' => sprintf($lang['danger']['access_denied'])
  1904. );
  1905. return false;
  1906. }
  1907. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  1908. $_SESSION['return'] = array(
  1909. 'type' => 'danger',
  1910. 'msg' => sprintf($lang['danger']['access_denied'])
  1911. );
  1912. return false;
  1913. }
  1914. try {
  1915. $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `goto` = :username");
  1916. $stmt->execute(array(
  1917. ':username' => $username
  1918. ));
  1919. $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :username");
  1920. $stmt->execute(array(
  1921. ':username' => $username
  1922. ));
  1923. $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
  1924. $stmt->execute(array(
  1925. ':username' => $username
  1926. ));
  1927. $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
  1928. $stmt->execute(array(
  1929. ':username' => $username
  1930. ));
  1931. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
  1932. $stmt->execute(array(
  1933. ':username' => $username
  1934. ));
  1935. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username");
  1936. $stmt->execute(array(
  1937. ':username' => $username
  1938. ));
  1939. $stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
  1940. WHERE `goto` LIKE :username");
  1941. $stmt->execute(array(':username' => '%'.$username.'%'));
  1942. $GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
  1943. foreach ($GotoData as $gotos) {
  1944. $goto_exploded = explode(',', $gotos['goto']);
  1945. if (($key = array_search($username, $goto_exploded)) !== false) {
  1946. unset($goto_exploded[$key]);
  1947. }
  1948. $gotos_rebuild = implode(',', $goto_exploded);
  1949. $stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto WHERE `address` = :address");
  1950. $stmt->execute(array(
  1951. ':goto' => $gotos_rebuild,
  1952. ':address' => $gotos['address']
  1953. ));
  1954. }
  1955. }
  1956. catch (PDOException $e) {
  1957. $_SESSION['return'] = array(
  1958. 'type' => 'danger',
  1959. 'msg' => 'MySQL: '.$e
  1960. );
  1961. return false;
  1962. }
  1963. $_SESSION['return'] = array(
  1964. 'type' => 'success',
  1965. 'msg' => sprintf($lang['success']['mailbox_removed'], htmlspecialchars($username))
  1966. );
  1967. }
  1968. function edit_domain_admin($postarray) {
  1969. global $lang;
  1970. global $pdo;
  1971. $username = $postarray['username'];
  1972. $password = $postarray['password'];
  1973. $password2 = $postarray['password2'];
  1974. isset($postarray['active']) ? $active = '1' : $active = '0';
  1975. if ($_SESSION['mailcow_cc_role'] != "admin") {
  1976. $_SESSION['return'] = array(
  1977. 'type' => 'danger',
  1978. 'msg' => sprintf($lang['danger']['access_denied'])
  1979. );
  1980. return false;
  1981. }
  1982. foreach ($postarray['domain'] as $domain) {
  1983. if (!is_valid_domain_name($domain)) {
  1984. $_SESSION['return'] = array(
  1985. 'type' => 'danger',
  1986. 'msg' => sprintf($lang['danger']['domain_invalid'])
  1987. );
  1988. return false;
  1989. }
  1990. }
  1991. if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
  1992. $_SESSION['return'] = array(
  1993. 'type' => 'danger',
  1994. 'msg' => sprintf($lang['danger']['username_invalid'])
  1995. );
  1996. return false;
  1997. }
  1998. try {
  1999. $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
  2000. $stmt->execute(array(
  2001. ':username' => $username,
  2002. ));
  2003. }
  2004. catch (PDOException $e) {
  2005. $_SESSION['return'] = array(
  2006. 'type' => 'danger',
  2007. 'msg' => 'MySQL: '.$e
  2008. );
  2009. return false;
  2010. }
  2011. foreach ($postarray['domain'] as $domain) {
  2012. try {
  2013. $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
  2014. VALUES (:username, :domain, :created, :active)");
  2015. $stmt->execute(array(
  2016. ':username' => $username,
  2017. ':domain' => $domain,
  2018. ':created' => date('Y-m-d H:i:s'),
  2019. ':active' => $active
  2020. ));
  2021. }
  2022. catch (PDOException $e) {
  2023. $_SESSION['return'] = array(
  2024. 'type' => 'danger',
  2025. 'msg' => 'MySQL: '.$e
  2026. );
  2027. return false;
  2028. }
  2029. }
  2030. if (!empty($password) && !empty($password2)) {
  2031. if ($password != $password2) {
  2032. $_SESSION['return'] = array(
  2033. 'type' => 'danger',
  2034. 'msg' => sprintf($lang['danger']['password_mismatch'])
  2035. );
  2036. return false;
  2037. }
  2038. $password_hashed = hash_password($password);
  2039. try {
  2040. $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
  2041. $stmt->execute(array(
  2042. ':password_hashed' => $password_hashed,
  2043. ':username' => $username,
  2044. ':modified' => date('Y-m-d H:i:s'),
  2045. ':active' => $active
  2046. ));
  2047. }
  2048. catch (PDOException $e) {
  2049. $_SESSION['return'] = array(
  2050. 'type' => 'danger',
  2051. 'msg' => 'MySQL: '.$e
  2052. );
  2053. return false;
  2054. }
  2055. }
  2056. else {
  2057. try {
  2058. $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active WHERE `username` = :username");
  2059. $stmt->execute(array(
  2060. ':username' => $username,
  2061. ':modified' => date('Y-m-d H:i:s'),
  2062. ':active' => $active
  2063. ));
  2064. }
  2065. catch (PDOException $e) {
  2066. $_SESSION['return'] = array(
  2067. 'type' => 'danger',
  2068. 'msg' => 'MySQL: '.$e
  2069. );
  2070. return false;
  2071. }
  2072. }
  2073. $_SESSION['return'] = array(
  2074. 'type' => 'success',
  2075. 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
  2076. );
  2077. }
  2078. function set_admin_account($postarray) {
  2079. global $lang;
  2080. global $pdo;
  2081. if ($_SESSION['mailcow_cc_role'] != "admin") {
  2082. $_SESSION['return'] = array(
  2083. 'type' => 'danger',
  2084. 'msg' => sprintf($lang['danger']['access_denied'])
  2085. );
  2086. return false;
  2087. }
  2088. $name = $postarray['admin_user'];
  2089. $name_now = $postarray['admin_user_now'];
  2090. if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $name)) || empty ($name)) {
  2091. $_SESSION['return'] = array(
  2092. 'type' => 'danger',
  2093. 'msg' => sprintf($lang['danger']['username_invalid'])
  2094. );
  2095. return false;
  2096. }
  2097. if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $name_now)) || empty ($name_now)) {
  2098. $_SESSION['return'] = array(
  2099. 'type' => 'danger',
  2100. 'msg' => sprintf($lang['danger']['username_invalid'])
  2101. );
  2102. return false;
  2103. }
  2104. if (!empty($postarray['admin_pass']) && !empty($postarray['admin_pass2'])) {
  2105. if ($postarray['admin_pass'] != $postarray['admin_pass2']) {
  2106. $_SESSION['return'] = array(
  2107. 'type' => 'danger',
  2108. 'msg' => sprintf($lang['danger']['password_mismatch'])
  2109. );
  2110. return false;
  2111. }
  2112. $password_hashed = hash_password($postarray['admin_pass']);
  2113. try {
  2114. $stmt = $pdo->prepare("UPDATE `admin` SET
  2115. `modified` = :modified,
  2116. `password` = :password_hashed,
  2117. `username` = :name
  2118. WHERE `username` = :username");
  2119. $stmt->execute(array(
  2120. ':password_hashed' => $password_hashed,
  2121. ':modified' => date('Y-m-d H:i:s'),
  2122. ':name' => $name,
  2123. ':username' => $name_now
  2124. ));
  2125. }
  2126. catch (PDOException $e) {
  2127. $_SESSION['return'] = array(
  2128. 'type' => 'danger',
  2129. 'msg' => 'MySQL: '.$e
  2130. );
  2131. return false;
  2132. }
  2133. }
  2134. else {
  2135. try {
  2136. $stmt = $pdo->prepare("UPDATE `admin` SET
  2137. `modified` = :modified,
  2138. `username` = :name
  2139. WHERE `username` = :name_now");
  2140. $stmt->execute(array(
  2141. ':name' => $name,
  2142. ':modified' => date('Y-m-d H:i:s'),
  2143. ':name_now' => $name_now
  2144. ));
  2145. }
  2146. catch (PDOException $e) {
  2147. $_SESSION['return'] = array(
  2148. 'type' => 'danger',
  2149. 'msg' => 'MySQL: '.$e
  2150. );
  2151. return false;
  2152. }
  2153. }
  2154. try {
  2155. $stmt = $pdo->prepare("UPDATE `domain_admins` SET
  2156. `domain` = :domain,
  2157. `username` = :name
  2158. WHERE `username` = :name_now");
  2159. $stmt->execute(array(
  2160. ':domain' => 'ALL',
  2161. ':name' => $name,
  2162. ':name_now' => $name_now
  2163. ));
  2164. }
  2165. catch (PDOException $e) {
  2166. $_SESSION['return'] = array(
  2167. 'type' => 'danger',
  2168. 'msg' => 'MySQL: '.$e
  2169. );
  2170. return false;
  2171. }
  2172. $_SESSION['return'] = array(
  2173. 'type' => 'success',
  2174. 'msg' => sprintf($lang['success']['admin_modified'])
  2175. );
  2176. }
  2177. function set_time_limited_aliases($postarray) {
  2178. global $lang;
  2179. global $pdo;
  2180. $username = $_SESSION['mailcow_cc_username'];
  2181. try {
  2182. $stmt = $pdo->prepare("SELECT `domain` FROM `mailbox` WHERE `username` = :username");
  2183. $stmt->execute(array(':username' => $username));
  2184. $domain = $stmt->fetch(PDO::FETCH_ASSOC)['domain'];
  2185. }
  2186. catch (PDOException $e) {
  2187. $_SESSION['return'] = array(
  2188. 'type' => 'danger',
  2189. 'msg' => 'MySQL: '.$e
  2190. );
  2191. return false;
  2192. }
  2193. if ($_SESSION['mailcow_cc_role'] != "user" || empty($username) || empty($domain)) {
  2194. $_SESSION['return'] = array(
  2195. 'type' => 'danger',
  2196. 'msg' => sprintf($lang['danger']['access_denied'])
  2197. );
  2198. return false;
  2199. }
  2200. switch ($postarray["trigger_set_time_limited_aliases"]) {
  2201. case "generate":
  2202. if (!is_numeric($postarray["validity"]) || $postarray["validity"] > 672) {
  2203. $_SESSION['return'] = array(
  2204. 'type' => 'danger',
  2205. 'msg' => sprintf($lang['danger']['validity_missing'])
  2206. );
  2207. return false;
  2208. }
  2209. $validity = strtotime("+".$postarray["validity"]." hour");
  2210. $letters = 'abcefghijklmnopqrstuvwxyz1234567890';
  2211. $random_name = substr(str_shuffle($letters), 0, 24);
  2212. try {
  2213. $stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `goto`, `validity`) VALUES
  2214. (:address, :goto, :validity)");
  2215. $stmt->execute(array(
  2216. ':address' => $random_name . '@' . $domain,
  2217. ':goto' => $username,
  2218. ':validity' => $validity
  2219. ));
  2220. }
  2221. catch (PDOException $e) {
  2222. $_SESSION['return'] = array(
  2223. 'type' => 'danger',
  2224. 'msg' => 'MySQL: '.$e
  2225. );
  2226. return false;
  2227. }
  2228. $_SESSION['return'] = array(
  2229. 'type' => 'success',
  2230. 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
  2231. );
  2232. break;
  2233. case "deleteall":
  2234. try {
  2235. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
  2236. $stmt->execute(array(
  2237. ':username' => $username
  2238. ));
  2239. }
  2240. catch (PDOException $e) {
  2241. $_SESSION['return'] = array(
  2242. 'type' => 'danger',
  2243. 'msg' => 'MySQL: '.$e
  2244. );
  2245. return false;
  2246. }
  2247. $_SESSION['return'] = array(
  2248. 'type' => 'success',
  2249. 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
  2250. );
  2251. break;
  2252. case "delete":
  2253. if (empty($postarray['item']) || !filter_var($postarray['item'], FILTER_VALIDATE_EMAIL)) {
  2254. $_SESSION['return'] = array(
  2255. 'type' => 'danger',
  2256. 'msg' => sprintf($lang['danger']['access_denied'])
  2257. );
  2258. return false;
  2259. }
  2260. $item = $postarray['item'];
  2261. try {
  2262. $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username AND `address` = :item");
  2263. $stmt->execute(array(
  2264. ':username' => $username,
  2265. ':item' => $item
  2266. ));
  2267. }
  2268. catch (PDOException $e) {
  2269. $_SESSION['return'] = array(
  2270. 'type' => 'danger',
  2271. 'msg' => 'MySQL: '.$e
  2272. );
  2273. return false;
  2274. }
  2275. $_SESSION['return'] = array(
  2276. 'type' => 'success',
  2277. 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
  2278. );
  2279. break;
  2280. case "extend":
  2281. try {
  2282. $stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600)
  2283. WHERE `goto` = :username
  2284. AND `validity` >= :validity");
  2285. $stmt->execute(array(
  2286. ':username' => $username,
  2287. ':validity' => time(),
  2288. ));
  2289. }
  2290. catch (PDOException $e) {
  2291. $_SESSION['return'] = array(
  2292. 'type' => 'danger',
  2293. 'msg' => 'MySQL: '.$e
  2294. );
  2295. return false;
  2296. }
  2297. $_SESSION['return'] = array(
  2298. 'type' => 'success',
  2299. 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
  2300. );
  2301. break;
  2302. }
  2303. }
  2304. function set_user_account($postarray) {
  2305. global $lang;
  2306. global $pdo;
  2307. $username = $_SESSION['mailcow_cc_username'];
  2308. $password_old = $postarray['user_old_pass'];
  2309. isset($postarray['togglePwNew']) ? $pwnew_active = '1' : $pwnew_active = '0';
  2310. if (isset($pwnew_active) && $pwnew_active == "1") {
  2311. $password_new = $postarray['user_new_pass'];
  2312. $password_new2 = $postarray['user_new_pass2'];
  2313. }
  2314. if (!check_login($username, $password_old) == "user") {
  2315. $_SESSION['return'] = array(
  2316. 'type' => 'danger',
  2317. 'msg' => sprintf($lang['danger']['access_denied'])
  2318. );
  2319. return false;
  2320. }
  2321. if ($_SESSION['mailcow_cc_role'] != "user" &&
  2322. $_SESSION['mailcow_cc_role'] != "domainadmin") {
  2323. $_SESSION['return'] = array(
  2324. 'type' => 'danger',
  2325. 'msg' => sprintf($lang['danger']['access_denied'])
  2326. );
  2327. return false;
  2328. }
  2329. if (isset($password_new) && isset($password_new2)) {
  2330. if (!empty($password_new2) && !empty($password_new)) {
  2331. if ($password_new2 != $password_new) {
  2332. $_SESSION['return'] = array(
  2333. 'type' => 'danger',
  2334. 'msg' => sprintf($lang['danger']['password_mismatch'])
  2335. );
  2336. return false;
  2337. }
  2338. if (strlen($password_new) < "6" ||
  2339. !preg_match('/[A-Za-z]/', $password_new) ||
  2340. !preg_match('/[0-9]/', $password_new)) {
  2341. $_SESSION['return'] = array(
  2342. 'type' => 'danger',
  2343. 'msg' => sprintf($lang['danger']['password_complexity'])
  2344. );
  2345. return false;
  2346. }
  2347. $password_hashed = hash_password($password_new);
  2348. try {
  2349. $stmt = $pdo->prepare("UPDATE `mailbox` SET `modified` = :modified, `password` = :password_hashed WHERE `username` = :username");
  2350. $stmt->execute(array(
  2351. ':password_hashed' => $password_hashed,
  2352. ':modified' => date('Y-m-d H:i:s'),
  2353. ':username' => $username
  2354. ));
  2355. }
  2356. catch (PDOException $e) {
  2357. $_SESSION['return'] = array(
  2358. 'type' => 'danger',
  2359. 'msg' => 'MySQL: '.$e
  2360. );
  2361. return false;
  2362. }
  2363. }
  2364. }
  2365. $_SESSION['return'] = array(
  2366. 'type' => 'success',
  2367. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  2368. );
  2369. }
  2370. function add_domain_admin($postarray) {
  2371. global $lang;
  2372. global $pdo;
  2373. $username = strtolower(trim($postarray['username']));
  2374. $password = $postarray['password'];
  2375. $password2 = $postarray['password2'];
  2376. isset($postarray['active']) ? $active = '1' : $active = '0';
  2377. if ($_SESSION['mailcow_cc_role'] != "admin") {
  2378. $_SESSION['return'] = array(
  2379. 'type' => 'danger',
  2380. 'msg' => sprintf($lang['danger']['access_denied'])
  2381. );
  2382. return false;
  2383. }
  2384. if (empty($postarray['domain'])) {
  2385. $_SESSION['return'] = array(
  2386. 'type' => 'danger',
  2387. 'msg' => sprintf($lang['danger']['domain_invalid'])
  2388. );
  2389. return false;
  2390. }
  2391. if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username)) {
  2392. $_SESSION['return'] = array(
  2393. 'type' => 'danger',
  2394. 'msg' => sprintf($lang['danger']['username_invalid'])
  2395. );
  2396. return false;
  2397. }
  2398. try {
  2399. $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
  2400. WHERE `username` = :username");
  2401. $stmt->execute(array(':username' => $username));
  2402. $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  2403. $stmt = $pdo->prepare("SELECT `username` FROM `admin`
  2404. WHERE `username` = :username");
  2405. $stmt->execute(array(':username' => $username));
  2406. $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  2407. $stmt = $pdo->prepare("SELECT `username` FROM `domain_admins`
  2408. WHERE `username` = :username");
  2409. $stmt->execute(array(':username' => $username));
  2410. $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  2411. }
  2412. catch(PDOException $e) {
  2413. $_SESSION['return'] = array(
  2414. 'type' => 'danger',
  2415. 'msg' => 'MySQL: '.$e
  2416. );
  2417. return false;
  2418. }
  2419. foreach ($num_results as $num_results_each) {
  2420. if ($num_results_each != 0) {
  2421. $_SESSION['return'] = array(
  2422. 'type' => 'danger',
  2423. 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
  2424. );
  2425. return false;
  2426. }
  2427. }
  2428. if (!empty($password) && !empty($password2)) {
  2429. if ($password != $password2) {
  2430. $_SESSION['return'] = array(
  2431. 'type' => 'danger',
  2432. 'msg' => sprintf($lang['danger']['password_mismatch'])
  2433. );
  2434. return false;
  2435. }
  2436. $password_hashed = hash_password($password);
  2437. foreach ($postarray['domain'] as $domain) {
  2438. if (!is_valid_domain_name($domain)) {
  2439. $_SESSION['return'] = array(
  2440. 'type' => 'danger',
  2441. 'msg' => sprintf($lang['danger']['domain_invalid'])
  2442. );
  2443. return false;
  2444. }
  2445. try {
  2446. $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
  2447. VALUES (:username, :domain, :created, :active)");
  2448. $stmt->execute(array(
  2449. ':username' => $username,
  2450. ':domain' => $domain,
  2451. ':created' => date('Y-m-d H:i:s'),
  2452. ':active' => $active
  2453. ));
  2454. }
  2455. catch (PDOException $e) {
  2456. $_SESSION['return'] = array(
  2457. 'type' => 'danger',
  2458. 'msg' => 'MySQL: '.$e
  2459. );
  2460. return false;
  2461. }
  2462. }
  2463. try {
  2464. $stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
  2465. VALUES (:username, :password_hashed, '0', :created, :modified, :active)");
  2466. $stmt->execute(array(
  2467. ':username' => $username,
  2468. ':password_hashed' => $password_hashed,
  2469. ':created' => date('Y-m-d H:i:s'),
  2470. ':modified' => date('Y-m-d H:i:s'),
  2471. ':active' => $active
  2472. ));
  2473. }
  2474. catch (PDOException $e) {
  2475. $_SESSION['return'] = array(
  2476. 'type' => 'danger',
  2477. 'msg' => 'MySQL: '.$e
  2478. );
  2479. return false;
  2480. }
  2481. }
  2482. else {
  2483. $_SESSION['return'] = array(
  2484. 'type' => 'danger',
  2485. 'msg' => sprintf($lang['danger']['password_empty'])
  2486. );
  2487. return false;
  2488. }
  2489. $_SESSION['return'] = array(
  2490. 'type' => 'success',
  2491. 'msg' => sprintf($lang['success']['domain_admin_added'], htmlspecialchars($username))
  2492. );
  2493. }
  2494. function delete_domain_admin($postarray) {
  2495. global $pdo;
  2496. global $lang;
  2497. if ($_SESSION['mailcow_cc_role'] != "admin") {
  2498. $_SESSION['return'] = array(
  2499. 'type' => 'danger',
  2500. 'msg' => sprintf($lang['danger']['access_denied'])
  2501. );
  2502. return false;
  2503. }
  2504. $username = $postarray['username'];
  2505. if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
  2506. $_SESSION['return'] = array(
  2507. 'type' => 'danger',
  2508. 'msg' => sprintf($lang['danger']['username_invalid'])
  2509. );
  2510. return false;
  2511. }
  2512. try {
  2513. $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
  2514. $stmt->execute(array(
  2515. ':username' => $username,
  2516. ));
  2517. $stmt = $pdo->prepare("DELETE FROM `admin` WHERE `username` = :username");
  2518. $stmt->execute(array(
  2519. ':username' => $username,
  2520. ));
  2521. }
  2522. catch (PDOException $e) {
  2523. $_SESSION['return'] = array(
  2524. 'type' => 'danger',
  2525. 'msg' => 'MySQL: '.$e
  2526. );
  2527. return false;
  2528. }
  2529. $_SESSION['return'] = array(
  2530. 'type' => 'success',
  2531. 'msg' => sprintf($lang['success']['domain_admin_removed'], htmlspecialchars($username))
  2532. );
  2533. }
  2534. function get_spam_score($username) {
  2535. global $pdo;
  2536. $default = "5, 15";
  2537. if ($_SESSION['mailcow_cc_role'] != "user") {
  2538. return false;
  2539. }
  2540. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  2541. return $default;
  2542. }
  2543. try {
  2544. $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `object` = :username AND
  2545. (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
  2546. $stmt->execute(array(':username' => $username));
  2547. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  2548. }
  2549. catch(PDOException $e) {
  2550. $_SESSION['return'] = array(
  2551. 'type' => 'danger',
  2552. 'msg' => 'MySQL: '.$e
  2553. );
  2554. return false;
  2555. }
  2556. if ($num_results == 0 || empty ($num_results)) {
  2557. return $default;
  2558. }
  2559. else {
  2560. try {
  2561. $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'highspamlevel' AND `object` = :username");
  2562. $stmt->execute(array(':username' => $username));
  2563. $highspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
  2564. $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'lowspamlevel' AND `object` = :username");
  2565. $stmt->execute(array(':username' => $username));
  2566. $lowspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
  2567. return $lowspamlevel['value'].', '.$highspamlevel['value'];
  2568. }
  2569. catch(PDOException $e) {
  2570. $_SESSION['return'] = array(
  2571. 'type' => 'danger',
  2572. 'msg' => 'MySQL: '.$e
  2573. );
  2574. return false;
  2575. }
  2576. }
  2577. }
  2578. function set_spam_score($postarray) {
  2579. global $lang;
  2580. global $pdo;
  2581. if ($_SESSION['mailcow_cc_role'] != "user") {
  2582. $_SESSION['return'] = array(
  2583. 'type' => 'danger',
  2584. 'msg' => sprintf($lang['danger']['access_denied'])
  2585. );
  2586. return false;
  2587. }
  2588. $username = $_SESSION['mailcow_cc_username'];
  2589. $lowspamlevel = explode(',', $postarray['score'])[0];
  2590. $highspamlevel = explode(',', $postarray['score'])[1];
  2591. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  2592. $_SESSION['return'] = array(
  2593. 'type' => 'danger',
  2594. 'msg' => sprintf($lang['danger']['username_invalid'])
  2595. );
  2596. return false;
  2597. }
  2598. if (!is_numeric($lowspamlevel) || !is_numeric($highspamlevel)) {
  2599. $_SESSION['return'] = array(
  2600. 'type' => 'danger',
  2601. 'msg' => sprintf($lang['danger']['access_denied'])
  2602. );
  2603. return false;
  2604. }
  2605. try {
  2606. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username
  2607. AND (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
  2608. $stmt->execute(array(
  2609. ':username' => $username
  2610. ));
  2611. $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
  2612. VALUES (:username, 'highspamlevel', :highspamlevel)");
  2613. $stmt->execute(array(
  2614. ':username' => $username,
  2615. ':highspamlevel' => $highspamlevel
  2616. ));
  2617. $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
  2618. VALUES (:username, 'lowspamlevel', :lowspamlevel)");
  2619. $stmt->execute(array(
  2620. ':username' => $username,
  2621. ':lowspamlevel' => $lowspamlevel
  2622. ));
  2623. }
  2624. catch (PDOException $e) {
  2625. $_SESSION['return'] = array(
  2626. 'type' => 'danger',
  2627. 'msg' => 'MySQL: '.$e
  2628. );
  2629. return false;
  2630. }
  2631. $_SESSION['return'] = array(
  2632. 'type' => 'success',
  2633. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  2634. );
  2635. }
  2636. function set_policy_list($postarray) {
  2637. global $lang;
  2638. global $pdo;
  2639. if ($_SESSION['mailcow_cc_role'] != "admin" &&
  2640. $_SESSION['mailcow_cc_role'] != "domainadmin" &&
  2641. $_SESSION['mailcow_cc_role'] != "user") {
  2642. $_SESSION['return'] = array(
  2643. 'type' => 'danger',
  2644. 'msg' => sprintf($lang['danger']['access_denied'])
  2645. );
  2646. return false;
  2647. }
  2648. (isset($postarray['domain'])) ? $object = $postarray['domain'] : $object = $_SESSION['mailcow_cc_username'];
  2649. ($postarray['object_list'] == "bl") ? $object_list = "blacklist_from" : $object_list = "whitelist_from";
  2650. $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($postarray['object_from']))), '.'));
  2651. if (!filter_var($object, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name($object)) {
  2652. $_SESSION['return'] = array(
  2653. 'type' => 'danger',
  2654. 'msg' => sprintf($lang['danger']['username_invalid'])
  2655. );
  2656. return false;
  2657. }
  2658. if (is_valid_domain_name($object)) {
  2659. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  2660. $_SESSION['return'] = array(
  2661. 'type' => 'danger',
  2662. 'msg' => sprintf($lang['danger']['access_denied'])
  2663. );
  2664. return false;
  2665. }
  2666. }
  2667. if (isset($postarray['prefid'])) {
  2668. if (!is_numeric($postarray['prefid'])) {
  2669. $_SESSION['return'] = array(
  2670. 'type' => 'danger',
  2671. 'msg' => sprintf($lang['danger']['access_denied'])
  2672. );
  2673. return false;
  2674. }
  2675. try {
  2676. $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
  2677. $stmt->execute(array(
  2678. ':object' => $object,
  2679. ':prefid' => $postarray['prefid']
  2680. ));
  2681. }
  2682. catch (PDOException $e) {
  2683. $_SESSION['return'] = array(
  2684. 'type' => 'danger',
  2685. 'msg' => 'MySQL: '.$e
  2686. );
  2687. return false;
  2688. }
  2689. $_SESSION['return'] = array(
  2690. 'type' => 'success',
  2691. 'msg' => sprintf($lang['success']['mailbox_modified'], $object)
  2692. );
  2693. return true;
  2694. }
  2695. if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $object_from))) {
  2696. $_SESSION['return'] = array(
  2697. 'type' => 'danger',
  2698. 'msg' => sprintf($lang['danger']['policy_list_from_invalid'])
  2699. );
  2700. return false;
  2701. }
  2702. try {
  2703. $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
  2704. WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
  2705. AND `object` = :object
  2706. AND `value` = :object_from");
  2707. $stmt->execute(array(':object' => $object, ':object_from' => $object_from));
  2708. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  2709. }
  2710. catch(PDOException $e) {
  2711. $_SESSION['return'] = array(
  2712. 'type' => 'danger',
  2713. 'msg' => 'MySQL: '.$e
  2714. );
  2715. return false;
  2716. }
  2717. if ($num_results != 0) {
  2718. $_SESSION['return'] = array(
  2719. 'type' => 'danger',
  2720. 'msg' => sprintf($lang['danger']['policy_list_from_exists'])
  2721. );
  2722. return false;
  2723. }
  2724. try {
  2725. $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
  2726. VALUES (:object, :object_list, :object_from)");
  2727. $stmt->execute(array(
  2728. ':object' => $object,
  2729. ':object_list' => $object_list,
  2730. ':object_from' => $object_from
  2731. ));
  2732. }
  2733. catch (PDOException $e) {
  2734. $_SESSION['return'] = array(
  2735. 'type' => 'danger',
  2736. 'msg' => 'MySQL: '.$e
  2737. );
  2738. return false;
  2739. }
  2740. $_SESSION['return'] = array(
  2741. 'type' => 'success',
  2742. 'msg' => sprintf($lang['success']['mailbox_modified'], $object)
  2743. );
  2744. }
  2745. function set_tls_policy($postarray) {
  2746. global $lang;
  2747. global $pdo;
  2748. if ($_SESSION['mailcow_cc_role'] != "user") {
  2749. $_SESSION['return'] = array(
  2750. 'type' => 'danger',
  2751. 'msg' => sprintf($lang['danger']['access_denied'])
  2752. );
  2753. return false;
  2754. }
  2755. isset($postarray['tls_in']) ? $tls_in = '1' : $tls_in = '0';
  2756. isset($postarray['tls_out']) ? $tls_out = '1' : $tls_out = '0';
  2757. $username = $_SESSION['mailcow_cc_username'];
  2758. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  2759. $_SESSION['return'] = array(
  2760. 'type' => 'danger',
  2761. 'msg' => sprintf($lang['danger']['username_invalid'])
  2762. );
  2763. return false;
  2764. }
  2765. try {
  2766. $stmt = $pdo->prepare("UPDATE `mailbox` SET `tls_enforce_out` = :tls_out, `tls_enforce_in` = :tls_in WHERE `username` = :username");
  2767. $stmt->execute(array(
  2768. ':tls_out' => $tls_out,
  2769. ':tls_in' => $tls_in,
  2770. ':username' => $username
  2771. ));
  2772. }
  2773. catch (PDOException $e) {
  2774. $_SESSION['return'] = array(
  2775. 'type' => 'danger',
  2776. 'msg' => 'MySQL: '.$e
  2777. );
  2778. return false;
  2779. }
  2780. $_SESSION['return'] = array(
  2781. 'type' => 'success',
  2782. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  2783. );
  2784. }
  2785. function set_syncjob($postarray, $action) {
  2786. global $lang;
  2787. global $pdo;
  2788. $username = $_SESSION['mailcow_cc_username'];
  2789. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  2790. $_SESSION['return'] = array(
  2791. 'type' => 'danger',
  2792. 'msg' => sprintf($lang['danger']['access_denied'])
  2793. );
  2794. return false;
  2795. }
  2796. if ($_SESSION['mailcow_cc_role'] != "user") {
  2797. $_SESSION['return'] = array(
  2798. 'type' => 'danger',
  2799. 'msg' => sprintf($lang['danger']['access_denied'])
  2800. );
  2801. return false;
  2802. }
  2803. // DELETE
  2804. if ($action == "delete") {
  2805. $id = $postarray['id'];
  2806. if (!is_numeric($id)) {
  2807. $_SESSION['return'] = array(
  2808. 'type' => 'danger',
  2809. 'msg' => sprintf($lang['danger']['access_denied'])
  2810. );
  2811. return false;
  2812. }
  2813. try {
  2814. $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username AND `id`= :id");
  2815. $stmt->execute(array(
  2816. ':username' => $username,
  2817. ':id' => $id,
  2818. ));
  2819. }
  2820. catch (PDOException $e) {
  2821. $_SESSION['return'] = array(
  2822. 'type' => 'danger',
  2823. 'msg' => 'MySQL: '.$e
  2824. );
  2825. return false;
  2826. }
  2827. $_SESSION['return'] = array(
  2828. 'type' => 'success',
  2829. 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
  2830. );
  2831. return true;
  2832. }
  2833. // ADD
  2834. elseif ($action == "add") {
  2835. isset($postarray['active']) ? $active = '1' : $active = '0';
  2836. isset($postarray['delete2duplicates']) ? $delete2duplicates = '1' : $delete2duplicates = '0';
  2837. $port1 = $postarray['port1'];
  2838. $host1 = $postarray['host1'];
  2839. $password1 = $postarray['password1'];
  2840. $exclude = $postarray['exclude'];
  2841. $maxage = $postarray['maxage'];
  2842. $subfolder2 = $postarray['subfolder2'];
  2843. $user1 = $postarray['user1'];
  2844. $mins_interval = $postarray['mins_interval'];
  2845. $enc1 = $postarray['enc1'];
  2846. if (empty($subfolder2)) {
  2847. $subfolder2 = "";
  2848. }
  2849. if (empty($maxage)) {
  2850. $maxage = 0;
  2851. }
  2852. if (!filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 0, 'max_range' => 32767)))) {
  2853. $_SESSION['return'] = array(
  2854. 'type' => 'danger',
  2855. 'msg' => sprintf($lang['danger']['access_denied'])
  2856. );
  2857. return false;
  2858. }
  2859. if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
  2860. $_SESSION['return'] = array(
  2861. 'type' => 'danger',
  2862. 'msg' => sprintf($lang['danger']['access_denied'])
  2863. );
  2864. return false;
  2865. }
  2866. if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
  2867. $_SESSION['return'] = array(
  2868. 'type' => 'danger',
  2869. 'msg' => sprintf($lang['danger']['access_denied'])
  2870. );
  2871. return false;
  2872. }
  2873. if (!is_valid_domain_name($host1)) {
  2874. $_SESSION['return'] = array(
  2875. 'type' => 'danger',
  2876. 'msg' => sprintf($lang['danger']['access_denied'])
  2877. );
  2878. return false;
  2879. }
  2880. if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
  2881. $_SESSION['return'] = array(
  2882. 'type' => 'danger',
  2883. 'msg' => sprintf($lang['danger']['access_denied'])
  2884. );
  2885. return false;
  2886. }
  2887. if (@preg_match("/" . $exclude . "/", null) === false) {
  2888. $_SESSION['return'] = array(
  2889. 'type' => 'danger',
  2890. 'msg' => sprintf($lang['danger']['access_denied'])
  2891. );
  2892. return false;
  2893. }
  2894. try {
  2895. $stmt = $pdo->prepare("SELECT `user2`, `user1` FROM `imapsync`
  2896. WHERE `user2` = :user2 AND `user1` = :user1");
  2897. $stmt->execute(array(':user1' => $user1, ':user2' => $username));
  2898. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  2899. }
  2900. catch(PDOException $e) {
  2901. $_SESSION['return'] = array(
  2902. 'type' => 'danger',
  2903. 'msg' => 'MySQL: '.$e
  2904. );
  2905. return false;
  2906. }
  2907. if ($num_results != 0) {
  2908. $_SESSION['return'] = array(
  2909. 'type' => 'danger',
  2910. 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($host1 . ' / ' . $user1))
  2911. );
  2912. return false;
  2913. }
  2914. try {
  2915. $stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `maxage`, `subfolder2`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `active`)
  2916. VALUES (:user2, :exclude, :maxage, :subfolder2, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :active)");
  2917. $stmt->execute(array(
  2918. ':user2' => $username,
  2919. ':exclude' => $exclude,
  2920. ':maxage' => $maxage,
  2921. ':subfolder2' => $subfolder2,
  2922. ':host1' => $host1,
  2923. ':authmech1' => 'PLAIN',
  2924. ':user1' => $user1,
  2925. ':password1' => $password1,
  2926. ':mins_interval' => $mins_interval,
  2927. ':port1' => $port1,
  2928. ':enc1' => $enc1,
  2929. ':delete2duplicates' => $delete2duplicates,
  2930. ':active' => $active,
  2931. ));
  2932. }
  2933. catch(PDOException $e) {
  2934. $_SESSION['return'] = array(
  2935. 'type' => 'danger',
  2936. 'msg' => 'MySQL: '.$e
  2937. );
  2938. return false;
  2939. }
  2940. $_SESSION['return'] = array(
  2941. 'type' => 'success',
  2942. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  2943. );
  2944. return true;
  2945. }
  2946. // EDIT
  2947. elseif ($action == "edit") {
  2948. isset($postarray['active']) ? $active = '1' : $active = '0';
  2949. isset($postarray['delete2duplicates']) ? $delete2duplicates = '1' : $delete2duplicates = '0';
  2950. $id = $postarray['id'];
  2951. $port1 = $postarray['port1'];
  2952. $host1 = $postarray['host1'];
  2953. $password1 = $postarray['password1'];
  2954. $exclude = $postarray['exclude'];
  2955. $maxage = $postarray['maxage'];
  2956. $subfolder2 = $postarray['subfolder2'];
  2957. $user1 = $postarray['user1'];
  2958. $mins_interval = $postarray['mins_interval'];
  2959. $enc1 = $postarray['enc1'];
  2960. if (empty($subfolder2)) {
  2961. $subfolder2 = "";
  2962. }
  2963. if (empty($maxage)) {
  2964. $maxage = 0;
  2965. }
  2966. if (!filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 0, 'max_range' => 32767)))) {
  2967. $_SESSION['return'] = array(
  2968. 'type' => 'danger',
  2969. 'msg' => sprintf($lang['danger']['access_denied'])
  2970. );
  2971. return false;
  2972. }
  2973. if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
  2974. $_SESSION['return'] = array(
  2975. 'type' => 'danger',
  2976. 'msg' => sprintf($lang['danger']['access_denied'])
  2977. );
  2978. return false;
  2979. }
  2980. if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
  2981. $_SESSION['return'] = array(
  2982. 'type' => 'danger',
  2983. 'msg' => sprintf($lang['danger']['access_denied'])
  2984. );
  2985. return false;
  2986. }
  2987. if (!is_valid_domain_name($host1)) {
  2988. $_SESSION['return'] = array(
  2989. 'type' => 'danger',
  2990. 'msg' => sprintf($lang['danger']['access_denied'])
  2991. );
  2992. return false;
  2993. }
  2994. if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
  2995. $_SESSION['return'] = array(
  2996. 'type' => 'danger',
  2997. 'msg' => sprintf($lang['danger']['access_denied'])
  2998. );
  2999. return false;
  3000. }
  3001. if (@preg_match("/" . $exclude . "/", null) === false) {
  3002. $_SESSION['return'] = array(
  3003. 'type' => 'danger',
  3004. 'msg' => sprintf($lang['danger']['access_denied'])
  3005. );
  3006. return false;
  3007. }
  3008. try {
  3009. $stmt = $pdo->prepare("SELECT `user2` FROM `imapsync`
  3010. WHERE `user2` = :user2 AND `id` = :id");
  3011. $stmt->execute(array(':user2' => $username, ':id' => $id));
  3012. $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  3013. }
  3014. catch(PDOException $e) {
  3015. $_SESSION['return'] = array(
  3016. 'type' => 'danger',
  3017. 'msg' => 'MySQL: '.$e
  3018. );
  3019. return false;
  3020. }
  3021. if (empty($num_results)) {
  3022. $_SESSION['return'] = array(
  3023. 'type' => 'danger',
  3024. 'msg' => sprintf($lang['danger']['access_denied'])
  3025. );
  3026. return false;
  3027. }
  3028. try {
  3029. $stmt = $pdo->prepare("UPDATE `imapsync` set `maxage` = :maxage, `subfolder2` = :subfolder2, `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
  3030. WHERE `user2` = :user2 AND `id` = :id");
  3031. $stmt->execute(array(
  3032. ':user2' => $username,
  3033. ':id' => $id,
  3034. ':exclude' => $exclude,
  3035. ':maxage' => $maxage,
  3036. ':subfolder2' => $subfolder2,
  3037. ':host1' => $host1,
  3038. ':user1' => $user1,
  3039. ':password1' => $password1,
  3040. ':mins_interval' => $mins_interval,
  3041. ':port1' => $port1,
  3042. ':enc1' => $enc1,
  3043. ':delete2duplicates' => $delete2duplicates,
  3044. ':active' => $active,
  3045. ));
  3046. }
  3047. catch(PDOException $e) {
  3048. $_SESSION['return'] = array(
  3049. 'type' => 'danger',
  3050. 'msg' => 'MySQL: '.$e
  3051. );
  3052. return false;
  3053. }
  3054. $_SESSION['return'] = array(
  3055. 'type' => 'success',
  3056. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  3057. );
  3058. return true;
  3059. }
  3060. }
  3061. function get_tls_policy($username) {
  3062. global $lang;
  3063. global $pdo;
  3064. if ($_SESSION['mailcow_cc_role'] != "user") {
  3065. return false;
  3066. }
  3067. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  3068. $_SESSION['return'] = array(
  3069. 'type' => 'danger',
  3070. 'msg' => sprintf($lang['danger']['username_invalid'])
  3071. );
  3072. return false;
  3073. }
  3074. try {
  3075. $stmt = $pdo->prepare("SELECT `tls_enforce_out`, `tls_enforce_in` FROM `mailbox` WHERE `username` = :username");
  3076. $stmt->execute(array(':username' => $username));
  3077. $TLSData = $stmt->fetch(PDO::FETCH_ASSOC);
  3078. }
  3079. catch(PDOException $e) {
  3080. $_SESSION['return'] = array(
  3081. 'type' => 'danger',
  3082. 'msg' => 'MySQL: '.$e
  3083. );
  3084. return false;
  3085. }
  3086. return $TLSData;
  3087. }
  3088. function remaining_specs($domain, $object = null, $js = null) {
  3089. // left_m without object given = MiB left in domain
  3090. // left_m with object given = Max. MiB we can assign to given object
  3091. // limit_m = Domain limit in MiB
  3092. // left_c = Mailboxes we can create depending on domain quota
  3093. global $pdo;
  3094. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
  3095. return false;
  3096. }
  3097. try {
  3098. $stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain");
  3099. $stmt->execute(array(':domain' => $domain));
  3100. $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
  3101. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `in_use_m` FROM `mailbox` WHERE `domain` = :domain AND `username` != :object");
  3102. $stmt->execute(array(':domain' => $domain, ':object' => $object));
  3103. $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
  3104. $quota_left_m = $DomainData['quota'] - $MailboxDataDomain['in_use_m'];
  3105. $mboxs_left = $DomainData['mailboxes'] - $MailboxDataDomain['count'];
  3106. if ($quota_left_m > $DomainData['maxquota']) {
  3107. $quota_left_m = $DomainData['maxquota'];
  3108. }
  3109. }
  3110. catch (PDOException $e) {
  3111. return false;
  3112. }
  3113. if (is_numeric($quota_left_m)) {
  3114. $spec['left_m'] = $quota_left_m;
  3115. $spec['limit_m'] = $DomainData['maxquota'];
  3116. }
  3117. if (is_numeric($mboxs_left)) {
  3118. $spec['left_c'] = $mboxs_left;
  3119. }
  3120. if (!empty($js)) {
  3121. echo $quota_left_m;
  3122. exit;
  3123. }
  3124. return $spec;
  3125. }
  3126. function get_sender_acl_handles($mailbox, $which) {
  3127. global $pdo;
  3128. if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
  3129. return false;
  3130. }
  3131. switch ($which) {
  3132. case "preselected":
  3133. try {
  3134. $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :goto AND `address` NOT LIKE '@%'");
  3135. $stmt->execute(array(':goto' => $mailbox));
  3136. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3137. return $rows;
  3138. }
  3139. catch(PDOException $e) {
  3140. $_SESSION['return'] = array(
  3141. 'type' => 'danger',
  3142. 'msg' => 'MySQL: '.$e
  3143. );
  3144. return false;
  3145. }
  3146. break;
  3147. case "selected":
  3148. try {
  3149. $stmt = $pdo->prepare("SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as");
  3150. $stmt->execute(array(':logged_in_as' => $mailbox));
  3151. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3152. return $rows;
  3153. }
  3154. catch(PDOException $e) {
  3155. $_SESSION['return'] = array(
  3156. 'type' => 'danger',
  3157. 'msg' => 'MySQL: '.$e
  3158. );
  3159. return false;
  3160. }
  3161. break;
  3162. case "unselected-domains":
  3163. try {
  3164. if ($_SESSION['mailcow_cc_role'] == "admin" ) {
  3165. $stmt = $pdo->prepare("SELECT DISTINCT `domain` FROM `domain`
  3166. WHERE `domain` NOT IN (
  3167. SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
  3168. WHERE `logged_in_as` = :logged_in_as)
  3169. AND `domain` NOT IN (
  3170. SELECT REPLACE(`address`, '@', '') FROM `alias`
  3171. WHERE `goto` = :goto)");
  3172. $stmt->execute(array(
  3173. ':logged_in_as' => $mailbox,
  3174. ':goto' => $mailbox,
  3175. ));
  3176. }
  3177. else {
  3178. $stmt = $pdo->prepare("SELECT DISTINCT `domain` FROM `domain_admins`
  3179. WHERE `username` = :username
  3180. AND `domain` != 'ALL'
  3181. AND `domain` NOT IN (
  3182. SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
  3183. WHERE `logged_in_as` = :logged_in_as)");
  3184. $stmt->execute(array(
  3185. ':logged_in_as' => $mailbox,
  3186. ':username' => $_SESSION['mailcow_cc_username']
  3187. ));
  3188. }
  3189. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3190. return $rows;
  3191. }
  3192. catch(PDOException $e) {
  3193. $_SESSION['return'] = array(
  3194. 'type' => 'danger',
  3195. 'msg' => 'MySQL: '.$e
  3196. );
  3197. return false;
  3198. }
  3199. break;
  3200. case "unselected-addresses":
  3201. try {
  3202. if ($_SESSION['mailcow_cc_role'] == "admin" ) {
  3203. $stmt = $pdo->prepare("SELECT `address` FROM `alias`
  3204. WHERE `goto` != :goto
  3205. AND `address` NOT IN (
  3206. SELECT `send_as` FROM `sender_acl`
  3207. WHERE `logged_in_as` = :logged_in_as)");
  3208. $stmt->execute(array(
  3209. ':logged_in_as' => $mailbox,
  3210. ':goto' => $mailbox
  3211. ));
  3212. }
  3213. else {
  3214. $stmt = $pdo->prepare("SELECT `address` FROM `alias`
  3215. WHERE `goto` != :goto
  3216. AND `domain` IN (
  3217. SELECT `domain` FROM `domain_admins`
  3218. WHERE `username` = :username)
  3219. AND `address` NOT IN (
  3220. SELECT `send_as` FROM `sender_acl`
  3221. WHERE `logged_in_as` = :logged_in_as)");
  3222. $stmt->execute(array(
  3223. ':logged_in_as' => $mailbox,
  3224. ':goto' => $mailbox,
  3225. ':username' => $_SESSION['mailcow_cc_username']
  3226. ));
  3227. }
  3228. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3229. return $rows;
  3230. }
  3231. catch(PDOException $e) {
  3232. $_SESSION['return'] = array(
  3233. 'type' => 'danger',
  3234. 'msg' => 'MySQL: '.$e
  3235. );
  3236. return false;
  3237. }
  3238. break;
  3239. }
  3240. return false;
  3241. }
  3242. function tagging_options($action, $data = null) {
  3243. global $lang;
  3244. global $pdo;
  3245. $username = $_SESSION['mailcow_cc_username'];
  3246. if ($action == "get") {
  3247. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  3248. return false;
  3249. }
  3250. try {
  3251. $stmt = $pdo->prepare("SELECT `wants_tagged_subject` FROM `mailbox` WHERE `username` = :username");
  3252. $stmt->execute(array(':username' => $username));
  3253. $SelectData = $stmt->fetch(PDO::FETCH_ASSOC);
  3254. }
  3255. catch(PDOException $e) {
  3256. $_SESSION['return'] = array(
  3257. 'type' => 'danger',
  3258. 'msg' => 'MySQL: '.$e
  3259. );
  3260. return false;
  3261. }
  3262. return $SelectData['wants_tagged_subject'];
  3263. }
  3264. elseif ($action == "set") {
  3265. ($data['tagged_mail_handler'] == "subject") ? $wants_tagged_subject = '1' : $wants_tagged_subject = '0';
  3266. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  3267. $_SESSION['return'] = array(
  3268. 'type' => 'danger',
  3269. 'msg' => sprintf($lang['danger']['username_invalid'])
  3270. );
  3271. return false;
  3272. }
  3273. try {
  3274. $stmt = $pdo->prepare("UPDATE `mailbox` SET `wants_tagged_subject` = :wants_tagged_subject WHERE `username` = :username");
  3275. $stmt->execute(array(':username' => $username, ':wants_tagged_subject' => $wants_tagged_subject));
  3276. $SelectData = $stmt->fetch(PDO::FETCH_ASSOC);
  3277. }
  3278. catch(PDOException $e) {
  3279. $_SESSION['return'] = array(
  3280. 'type' => 'danger',
  3281. 'msg' => 'MySQL: '.$e
  3282. );
  3283. return false;
  3284. }
  3285. $_SESSION['return'] = array(
  3286. 'type' => 'success',
  3287. 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
  3288. );
  3289. }
  3290. return false;
  3291. }
  3292. function user_get_alias_details($username) {
  3293. global $lang;
  3294. global $pdo;
  3295. if ($_SESSION['mailcow_cc_role'] == "user") {
  3296. $username = $_SESSION['mailcow_cc_username'];
  3297. }
  3298. if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
  3299. return false;
  3300. }
  3301. try {
  3302. $data['address'] = $username;
  3303. $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '&#10008;') AS `aliases` FROM `alias` WHERE `goto` = :username_goto AND `address` NOT LIKE '@%' AND `address` != :username_address");
  3304. $stmt->execute(array(':username_goto' => $username, ':username_address' => $username));
  3305. $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3306. while ($row = array_shift($run)) {
  3307. $data['aliases'] = $row['aliases'];
  3308. }
  3309. $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ', '), '&#10008;') AS `ad_alias` FROM `mailbox`
  3310. LEFT OUTER JOIN `alias_domain` on `target_domain` = `domain`
  3311. WHERE `username` = :username ;");
  3312. $stmt->execute(array(':username' => $username));
  3313. $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3314. while ($row = array_shift($run)) {
  3315. $data['ad_alias'] = $row['ad_alias'];
  3316. }
  3317. $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '&#10008;') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` NOT LIKE '@%';");
  3318. $stmt->execute(array(':username' => $username));
  3319. $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3320. while ($row = array_shift($run)) {
  3321. $data['aliases_also_send_as'] = $row['send_as'];
  3322. }
  3323. $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '&#10008;') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` LIKE '@%';");
  3324. $stmt->execute(array(':username' => $username));
  3325. $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3326. while ($row = array_shift($run)) {
  3327. $data['aliases_send_as_all'] = $row['send_as'];
  3328. }
  3329. $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '&#10008;') as `address` FROM `alias` WHERE `goto` = :username AND `address` LIKE '@%';");
  3330. $stmt->execute(array(':username' => $username));
  3331. $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
  3332. while ($row = array_shift($run)) {
  3333. $data['is_catch_all'] = $row['address'];
  3334. }
  3335. return $data;
  3336. }
  3337. catch(PDOException $e) {
  3338. $_SESSION['return'] = array(
  3339. 'type' => 'danger',
  3340. 'msg' => 'MySQL: '.$e
  3341. );
  3342. return false;
  3343. }
  3344. }
  3345. function is_valid_domain_name($domain_name) {
  3346. if (empty($domain_name)) {
  3347. return false;
  3348. }
  3349. $domain_name = idn_to_ascii($domain_name);
  3350. return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name)
  3351. && preg_match("/^.{1,253}$/", $domain_name)
  3352. && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name));
  3353. }
  3354. ?>