| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 | <?phpfunction acl($_action, $_scope = null, $_data = null) {  global $pdo;  global $lang;  $_data_log = $_data;  switch ($_action) {    case 'edit':      switch ($_scope) {        case 'user':          if (!is_array($_data['username'])) {            $usernames = array();            $usernames[] = $_data['username'];          }          else {            $usernames = $_data['username'];          }          foreach ($usernames as $username) {            // Cast to array for single selections            $acls = (array)$_data['user_acl'];            // Create associative array from index array            // All set items are given 1 as value            foreach ($acls as $acl_key => $acl_val) {              $acl_post[$acl_val] = 1;            }            // Users cannot change their own ACL            if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)              || ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin')) {              $_SESSION['return'][] = array(                'type' => 'danger',                'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),                'msg' => 'access_denied'              );              continue;            }            // Read all available acl options by calling acl(get)            // Set all available acl options we cannot find in the post data to 0, else 1            $is_now = acl('get', 'user', $username);            if (!empty($is_now)) {              foreach ($is_now as $acl_now_name => $acl_now_val) {                $set_acls[$acl_now_name] = (isset($acl_post[$acl_now_name])) ? 1 : 0;              }            }            else {              $_SESSION['return'][] = array(                'type' => 'danger',                'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),                'msg' => 'Cannot determine current ACL'              );              continue;            }            foreach ($set_acls as $set_acl_key => $set_acl_val) {              $stmt = $pdo->prepare("UPDATE `user_acl` SET " . $set_acl_key . " = " . intval($set_acl_val) . "                WHERE `username` = :username");              $stmt->execute(array(                ':username' => $username,              ));            }            $_SESSION['return'][] = array(              'type' => 'success',              'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),              'msg' => array('acl_saved', $username)            );          }        break;        case 'domainadmin':          if ($_SESSION['mailcow_cc_role'] != 'admin') {            $_SESSION['return'][] = array(              'type' => 'danger',              'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),              'msg' => 'access_denied'            );            return false;          }          if (!is_array($_data['username'])) {            $usernames = array();            $usernames[] = $_data['username'];          }          else {            $usernames = $_data['username'];          }          foreach ($usernames as $username) {            // Cast to array for single selections            $acls = (array)$_data['da_acl'];            // Create associative array from index array            // All set items are given 1 as value            foreach ($acls as $acl_key => $acl_val) {              $acl_post[$acl_val] = 1;            }            // Users cannot change their own ACL            if ($_SESSION['mailcow_cc_role'] != 'admin') {              $_SESSION['return'][] = array(                'type' => 'danger',                'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),                'msg' => 'access_denied'              );              continue;            }            // Read all available acl options by calling acl(get)            // Set all available acl options we cannot find in the post data to 0, else 1            $is_now = acl('get', 'domainadmin', $username);            if (!empty($is_now)) {              foreach ($is_now as $acl_now_name => $acl_now_val) {                $set_acls[$acl_now_name] = (isset($acl_post[$acl_now_name])) ? 1 : 0;              }            }            else {              $_SESSION['return'][] = array(                'type' => 'danger',                'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),                'msg' => 'Cannot determine current ACL'              );              continue;            }            foreach ($set_acls as $set_acl_key => $set_acl_val) {              $stmt = $pdo->prepare("UPDATE `da_acl` SET " . $set_acl_key . " = " . intval($set_acl_val) . "                WHERE `username` = :username");              $stmt->execute(array(                ':username' => $username,              ));            }            $_SESSION['return'][] = array(              'type' => 'success',              'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),              'msg' => array('acl_saved', $username)            );          }        break;      }    break;    case 'get':      switch ($_scope) {        case 'user':          if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {            return false;          }          $stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");          $stmt->execute(array(':username' => $_data));          $data = $stmt->fetch(PDO::FETCH_ASSOC);          if ($_SESSION['mailcow_cc_role'] == 'domainadmin') {            // Domain admins cannot see, add or remove user ACLs they don't have access to by themselves            // Editing a user will use acl("get", "user") to determine granted ACLs and therefore block unallowed access escalation via form editing            $self_da_acl = acl('get', 'domainadmin', $_SESSION['mailcow_cc_username']);            foreach ($self_da_acl as $self_da_acl_key => $self_da_acl_val) {              if ($self_da_acl_val == 0) {                unset($data[$self_da_acl_key]);              }            }          }          if (!empty($data)) {            unset($data['username']);            return $data;          }          else {            return false;          }        break;        case 'domainadmin':          if ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin') {            return false;          }          if ($_SESSION['mailcow_cc_role'] == 'domainadmin' && $_SESSION['mailcow_cc_username'] != $_data) {            return false;          }          $stmt = $pdo->prepare("SELECT * FROM `da_acl` WHERE `username` = :username");          $stmt->execute(array(':username' => $_data));          $data = $stmt->fetch(PDO::FETCH_ASSOC);          if (!empty($data)) {            unset($data['username']);            return $data;          }          else {            return false;          }        break;      }    break;    case 'to_session':      if (!isset($_SESSION['mailcow_cc_role'])) {        return false;      }      unset($_SESSION['acl']);      $username = strtolower(trim($_SESSION['mailcow_cc_username']));      // Admins get access to all modules      if ($_SESSION['mailcow_cc_role'] == 'admin' ||        (isset($_SESSION["dual-login"]["role"]) && $_SESSION["dual-login"]["role"] == 'admin')) {        $stmt = $pdo->query("SHOW COLUMNS FROM `user_acl` WHERE `Field` != 'username';");        $acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);        while ($row = array_shift($acl_all)) {          $acl['acl'][$row['Field']] = 1;        }        $stmt = $pdo->query("SHOW COLUMNS FROM `da_acl` WHERE `Field` != 'username';");        $acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);        while ($row = array_shift($acl_all)) {          $acl['acl'][$row['Field']] = 1;        }      }      elseif ($_SESSION['mailcow_cc_role'] == 'domainadmin' ||        (isset($_SESSION["dual-login"]["role"]) && $_SESSION["dual-login"]["role"] == 'domainadmin')) {        // Read all exting user_acl modules and set to 1        $stmt = $pdo->query("SHOW COLUMNS FROM `user_acl` WHERE `Field` != 'username';");        $acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);        while ($row = array_shift($acl_all)) {          $acl['acl'][$row['Field']] = 1;        }        // Read da_acl rules for current user, OVERWRITE overlapping modules        // This prevents access to a users sync jobs, when a domain admins was not given access to sync jobs        $stmt = $pdo->prepare("SELECT * FROM `da_acl` WHERE `username` = :username");        $stmt->execute(array(':username' => (isset($_SESSION["dual-login"]["username"])) ? $_SESSION["dual-login"]["username"] : $username));        $acl_user = $stmt->fetch(PDO::FETCH_ASSOC);        foreach ($acl_user as $acl_user_key => $acl_user_val) {          $acl['acl'][$acl_user_key] = $acl_user_val;        }        unset($acl['acl']['username']);      }      elseif ($_SESSION['mailcow_cc_role'] == 'user') {        $stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");        $stmt->execute(array(':username' => $username));        $acl['acl'] = $stmt->fetch(PDO::FETCH_ASSOC);        unset($acl['acl']['username']);      }      if (!empty($acl)) {        $_SESSION = array_merge($_SESSION, $acl);      }    break;  }}
 |