functions.admin.inc.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <?php
  2. function admin($_action, $_data = null) {
  3. if ($_SESSION['mailcow_cc_role'] != "admin") {
  4. $_SESSION['return'][] = array(
  5. 'type' => 'danger',
  6. 'log' => array(__FUNCTION__, $_action, $_data_log),
  7. 'msg' => 'access_denied'
  8. );
  9. return false;
  10. }
  11. global $pdo;
  12. global $lang;
  13. $_data_log = $_data;
  14. !isset($_data_log['password']) ?: $_data_log['password'] = '*';
  15. !isset($_data_log['password2']) ?: $_data_log['password2'] = '*';
  16. switch ($_action) {
  17. case 'add':
  18. $username = strtolower(trim($_data['username']));
  19. $password = $_data['password'];
  20. $password2 = $_data['password2'];
  21. $active = intval($_data['active']);
  22. if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username) || $username == 'API') {
  23. $_SESSION['return'][] = array(
  24. 'type' => 'danger',
  25. 'log' => array(__FUNCTION__, $_action, $_data_log),
  26. 'msg' => array('username_invalid', $username)
  27. );
  28. return false;
  29. }
  30. $stmt = $pdo->prepare("SELECT `username` FROM `admin`
  31. WHERE `username` = :username");
  32. $stmt->execute(array(':username' => $username));
  33. $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  34. $stmt = $pdo->prepare("SELECT `username` FROM `domain_admins`
  35. WHERE `username` = :username");
  36. $stmt->execute(array(':username' => $username));
  37. $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
  38. foreach ($num_results as $num_results_each) {
  39. if ($num_results_each != 0) {
  40. $_SESSION['return'][] = array(
  41. 'type' => 'danger',
  42. 'log' => array(__FUNCTION__, $_action, $_data_log),
  43. 'msg' => array('object_exists', htmlspecialchars($username))
  44. );
  45. return false;
  46. }
  47. }
  48. if (password_check($password, $password2) !== true) {
  49. return false;
  50. }
  51. $password_hashed = hash_password($password);
  52. $stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
  53. VALUES (:username, :password_hashed, '1', :active)");
  54. $stmt->execute(array(
  55. ':username' => $username,
  56. ':password_hashed' => $password_hashed,
  57. ':active' => $active
  58. ));
  59. $_SESSION['return'][] = array(
  60. 'type' => 'success',
  61. 'log' => array(__FUNCTION__, $_action, $_data_log),
  62. 'msg' => array('admin_added', htmlspecialchars($username))
  63. );
  64. break;
  65. case 'edit':
  66. if (!is_array($_data['username'])) {
  67. $usernames = array();
  68. $usernames[] = $_data['username'];
  69. }
  70. else {
  71. $usernames = $_data['username'];
  72. }
  73. foreach ($usernames as $username) {
  74. $is_now = admin('details', $username);
  75. if (!empty($is_now)) {
  76. $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active'];
  77. $username_new = (!empty($_data['username_new'])) ? $_data['username_new'] : $is_now['username'];
  78. }
  79. else {
  80. $_SESSION['return'][] = array(
  81. 'type' => 'danger',
  82. 'log' => array(__FUNCTION__, $_action, $_data_log),
  83. 'msg' => 'access_denied'
  84. );
  85. continue;
  86. }
  87. $password = $_data['password'];
  88. $password2 = $_data['password2'];
  89. if ($active == 0) {
  90. $left_active = 0;
  91. foreach (admin('get') as $admin) {
  92. $left_active = $left_active + admin('details', $admin)['active'];
  93. }
  94. if ($left_active == 1) {
  95. $_SESSION['return'][] = array(
  96. 'type' => 'warning',
  97. 'log' => array(__FUNCTION__, $_action, $_data_log),
  98. 'msg' => 'no_active_admin'
  99. );
  100. continue;
  101. }
  102. }
  103. if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username_new))) {
  104. $_SESSION['return'][] = array(
  105. 'type' => 'danger',
  106. 'log' => array(__FUNCTION__, $_action, $_data_log),
  107. 'msg' => array('username_invalid', $username_new)
  108. );
  109. continue;
  110. }
  111. if ($username_new != $username) {
  112. if (!empty(admin('details', $username_new)['username'])) {
  113. $_SESSION['return'][] = array(
  114. 'type' => 'danger',
  115. 'log' => array(__FUNCTION__, $_action, $_data_log),
  116. 'msg' => array('username_invalid', $username_new)
  117. );
  118. continue;
  119. }
  120. }
  121. if (!empty($password)) {
  122. if (password_check($password, $password2) !== true) {
  123. return false;
  124. }
  125. $password_hashed = hash_password($password);
  126. $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
  127. $stmt->execute(array(
  128. ':password_hashed' => $password_hashed,
  129. ':username_new' => $username_new,
  130. ':username' => $username,
  131. ':active' => $active
  132. ));
  133. if (isset($_data['disable_tfa'])) {
  134. $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
  135. $stmt->execute(array(':username' => $username));
  136. }
  137. else {
  138. $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
  139. $stmt->execute(array(':username_new' => $username_new, ':username' => $username));
  140. }
  141. }
  142. else {
  143. $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active WHERE `username` = :username");
  144. $stmt->execute(array(
  145. ':username_new' => $username_new,
  146. ':username' => $username,
  147. ':active' => $active
  148. ));
  149. if (isset($_data['disable_tfa'])) {
  150. $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
  151. $stmt->execute(array(':username' => $username));
  152. }
  153. else {
  154. $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
  155. $stmt->execute(array(':username_new' => $username_new, ':username' => $username));
  156. }
  157. }
  158. $_SESSION['return'][] = array(
  159. 'type' => 'success',
  160. 'log' => array(__FUNCTION__, $_action, $_data_log),
  161. 'msg' => array('admin_modified', htmlspecialchars($username))
  162. );
  163. }
  164. return true;
  165. break;
  166. case 'delete':
  167. $usernames = (array)$_data['username'];
  168. foreach ($usernames as $username) {
  169. if ($_SESSION['mailcow_cc_username'] == $username) {
  170. $_SESSION['return'][] = array(
  171. 'type' => 'warning',
  172. 'log' => array(__FUNCTION__, $_action, $_data_log),
  173. 'msg' => 'cannot_delete_self'
  174. );
  175. continue;
  176. }
  177. if (empty(admin('details', $username))) {
  178. $_SESSION['return'][] = array(
  179. 'type' => 'danger',
  180. 'log' => array(__FUNCTION__, $_action, $_data_log),
  181. 'msg' => array('username_invalid', $username)
  182. );
  183. continue;
  184. }
  185. $stmt = $pdo->prepare("DELETE FROM `admin` WHERE `username` = :username");
  186. $stmt->execute(array(
  187. ':username' => $username,
  188. ));
  189. $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
  190. $stmt->execute(array(
  191. ':username' => $username,
  192. ));
  193. $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username");
  194. $stmt->execute(array(
  195. ':username' => $username,
  196. ));
  197. $stmt = $pdo->prepare("DELETE FROM `fido2` WHERE `username` = :username");
  198. $stmt->execute(array(
  199. ':username' => $username,
  200. ));
  201. $_SESSION['return'][] = array(
  202. 'type' => 'success',
  203. 'log' => array(__FUNCTION__, $_action, $_data_log),
  204. 'msg' => array('admin_removed', htmlspecialchars($username))
  205. );
  206. }
  207. break;
  208. case 'get':
  209. $admins = array();
  210. $stmt = $pdo->query("SELECT `username` FROM `admin` WHERE `superadmin` = '1'");
  211. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  212. while ($row = array_shift($rows)) {
  213. $admins[] = $row['username'];
  214. }
  215. return $admins;
  216. break;
  217. case 'details':
  218. $admindata = array();
  219. $stmt = $pdo->prepare("SELECT
  220. `tfa`.`active` AS `tfa_active`,
  221. `admin`.`username`,
  222. `admin`.`created`,
  223. `admin`.`active` AS `active`
  224. FROM `admin`
  225. LEFT OUTER JOIN `tfa` ON `tfa`.`username`=`admin`.`username`
  226. WHERE `admin`.`username`= :admin AND `superadmin` = '1'");
  227. $stmt->execute(array(
  228. ':admin' => $_data
  229. ));
  230. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  231. if (empty($row)) {
  232. return false;
  233. }
  234. $admindata['username'] = $row['username'];
  235. $admindata['tfa_active'] = (is_null($row['tfa_active'])) ? 0 : $row['tfa_active'];
  236. $admindata['tfa_active_int'] = (is_null($row['tfa_active'])) ? 0 : $row['tfa_active'];
  237. $admindata['active'] = $row['active'];
  238. $admindata['active_int'] = $row['active'];
  239. $admindata['created'] = $row['created'];
  240. return $admindata;
  241. break;
  242. }
  243. }