diff --git a/admin/inc/class.admin_ui.inc.php b/admin/inc/class.admin_ui.inc.php index fccf53dcd0..fe25cadab4 100644 --- a/admin/inc/class.admin_ui.inc.php +++ b/admin/inc/class.admin_ui.inc.php @@ -374,6 +374,10 @@ class admin_ui $params['query'] = $query['search']; $params['query_type'] = 'all'; } + if (!empty($query['account_id'])) + { + $params['account_id'] = (array)$query['account_id']; + } $rows = array_values(self::$accounts->search($params)); //error_log(__METHOD__."() accounts->search(".array2string($params).") total=".self::$accounts->total); diff --git a/api/src/Accounts.php b/api/src/Accounts.php index 99f1aac756..c9c0a06505 100644 --- a/api/src/Accounts.php +++ b/api/src/Accounts.php @@ -187,6 +187,7 @@ class Accounts { // normalize our cache-key by not storing anything, plus adding default the default sort (if none requested) $keys = array_filter($params)+['order' => 'account_lid', 'sort' => 'ASC']; + if (isset($keys['account_id'])) $keys['account_id'] = md5(json_encode($keys['account_id'])); // sort keys ksort($keys); $key = json_encode($keys); @@ -221,6 +222,7 @@ class Accounts * 'lid','firstname','lastname','email' - query only the given field for containing $param[query] * @param $param['app'] string with an app-name, to limit result on accounts with run-right for that app * @param $param['active']=true boolean - true: return only acctive accounts, false: return expired or deactivated too + * @param $param['account_id'] int[] return only given account_id's * @return array with account_id => data pairs, data is an array with account_id, account_lid, account_firstname, * account_lastname, person_id (id of the linked addressbook entry), account_status, account_expires, account_primary_group */ diff --git a/api/src/Accounts/Ads.php b/api/src/Accounts/Ads.php index e8420a0c8f..18493eb6c3 100644 --- a/api/src/Accounts/Ads.php +++ b/api/src/Accounts/Ads.php @@ -918,6 +918,7 @@ class Ads * @param $param['objectclass'] boolean return objectclass(es) under key 'objectclass' in each account * @param $param['active'] boolean true: only return active / not expired accounts * @param $param['modified'] int if given minimum modification time + * @param $param['account_id'] int[] return only given account_id's * @return array with account_id => data pairs, data is an array with account_id, account_lid, account_firstname, * account_lastname, person_id (id of the linked addressbook entry), account_status, account_expires, account_primary_group */ @@ -967,6 +968,11 @@ class Ads $membership_filter = '(|(memberOf='.$this->id2name((int)$param['type'], 'account_dn').')(PrimaryGroupId='.abs($param['type']).'))'; $filter = $filter ? "(&$membership_filter$filter)" : $membership_filter; } + if (!empty($param['account_id'])) + { + $account_ids_filter = '(|(objectsid='.implode(')(objectsid=', array_map([$this, 'get_sid'], $param['account_id'])).')'; + $filter = $filter ? "(&$filter$account_ids_filter)" : $account_ids_filter; + } if (!empty($param['modified'])) { $filter = "(&(whenChanged>=".gmdate('YmdHis', $param['modified']).".0Z)$filter)"; diff --git a/api/src/Accounts/Ldap.php b/api/src/Accounts/Ldap.php index 9d41164576..21776250b2 100644 --- a/api/src/Accounts/Ldap.php +++ b/api/src/Accounts/Ldap.php @@ -731,6 +731,7 @@ class Ldap * @param $param['offset'] int - number of matches to return if start given, default use the value in the prefs * @param $param['objectclass'] boolean return objectclass(es) under key 'objectclass' in each account * @param $param['modified'] int if given minimum modification time + * @param $param['account_id'] int[] return only given account_id's * @return array with account_id => data pairs, data is an array with account_id, account_lid, account_firstname, * account_lastname, person_id (id of the linked addressbook entry), account_status, account_expires, account_primary_group */ @@ -812,6 +813,11 @@ class Ldap $filter .= '(uidNumber=0)'; // to NOT find any user } } + // only return given account_id's + if (!empty($param['account_id'])) + { + $filter .= '(|(uidNumber=' . implode(')(uidNumber=', $param['account_id']) . '))'; + } if (!empty($param['modified'])) { $filter .= "(modifytimestamp>=".gmdate('YmdHis', $param['modified']).".0Z)"; diff --git a/api/src/Accounts/Sql.php b/api/src/Accounts/Sql.php index 845079040a..a8dc7166f4 100644 --- a/api/src/Accounts/Sql.php +++ b/api/src/Accounts/Sql.php @@ -424,6 +424,7 @@ class Sql * 'lid','firstname','lastname','email' - query only the given field for containing $param[query] * @param $param['offset'] int - number of matches to return if start given, default use the value in the prefs * @param $param['objectclass'] boolean return objectclass(es) under key 'objectclass' in each account + * @param $param['account_id'] int[] return only given account_id's * @return array with account_id => data pairs, data is an array with account_id, account_lid, account_firstname, * account_lastname, person_id (id of the linked addressbook entry), account_status, account_expires, account_primary_group */ @@ -443,7 +444,7 @@ class Sql } $order = str_replace(array_keys($order2contact),array_values($order2contact),$param['order'] ?? ''); - // allways add 'account_lid' + // always add 'account_lid' if (strpos($order, 'account_lid') === false) { $order .= ($order?',':'').'account_lid'; @@ -465,7 +466,7 @@ class Sql $join .= ' LEFT JOIN '.Api\Mail\Smtp\Sql::TABLE.' ON '.$this->table.'.account_id=-'.Api\Mail\Smtp\Sql::TABLE.'.account_id AND mail_type='.Api\Mail\Smtp\Sql::TYPE_ALIAS; } - $filter = array(); + $filter = empty($param['account_id']) ? [] : ['account_id' => (array)$param['account_id']]; switch($param['type']) { case 'accounts': @@ -487,7 +488,7 @@ class Sql $members = array_unique(array_merge($members, array_keys((array)$this->members($grp)))); if ($param['type'] == 'groupmembers+memberships') $members[] = abs($grp); } - $filter['account_id'] = $members; + $filter['account_id'] = empty($filter['account_id']) ? $members : array_merge($members, $filter['account_id']); break; default: if (is_numeric($param['type']))