Blame view
sources/apps/user_ldap/group_ldap.php
9.62 KB
|
03e52840d
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php /** * ownCloud – LDAP group backend * * @author Arthur Schiwon * @copyright 2012 Arthur Schiwon blizzz@owncloud.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU AFFERO GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU Affero General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ namespace OCA\user_ldap; |
|
31b7f2792
|
25 26 27 28 |
use OCA\user_ldap\lib\Access;
use OCA\user_ldap\lib\BackendUtility;
class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
|
|
03e52840d
|
29 |
protected $enabled = false; |
|
31b7f2792
|
30 31 32 33 |
public function __construct(Access $access) {
parent::__construct($access);
$filter = $this->access->connection->ldapGroupFilter;
$gassoc = $this->access->connection->ldapGroupMemberAssocAttr;
|
|
03e52840d
|
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
if(!empty($filter) && !empty($gassoc)) {
$this->enabled = true;
}
}
/**
* @brief is user in group?
* @param $uid uid of the user
* @param $gid gid of the group
* @returns true/false
*
* Checks whether the user is member of a group or not.
*/
public function inGroup($uid, $gid) {
if(!$this->enabled) {
return false;
}
|
|
31b7f2792
|
51 52 |
if($this->access->connection->isCached('inGroup'.$uid.':'.$gid)) {
return $this->access->connection->getFromCache('inGroup'.$uid.':'.$gid);
|
|
03e52840d
|
53 |
} |
|
31b7f2792
|
54 55 |
$dn_user = $this->access->username2dn($uid); $dn_group = $this->access->groupname2dn($gid); |
|
03e52840d
|
56 57 |
// just in case
if(!$dn_group || !$dn_user) {
|
|
31b7f2792
|
58 |
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false);
|
|
03e52840d
|
59 60 61 |
return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. |
|
31b7f2792
|
62 63 |
$members = $this->access->readAttribute($dn_group, $this->access->connection->ldapGroupMemberAssocAttr); |
|
03e52840d
|
64 |
if(!$members) {
|
|
31b7f2792
|
65 |
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false);
|
|
03e52840d
|
66 67 68 69 70 |
return false; } //extra work if we don't get back user DNs //TODO: this can be done with one LDAP query |
|
31b7f2792
|
71 |
if(strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid') {
|
|
03e52840d
|
72 73 |
$dns = array();
foreach($members as $mid) {
|
|
31b7f2792
|
74 75 |
$filter = str_replace('%uid', $mid, $this->access->connection->ldapLoginFilter);
$ldap_users = $this->access->fetchListOfUsers($filter, 'dn');
|
|
03e52840d
|
76 77 78 79 80 81 82 83 84 |
if(count($ldap_users) < 1) {
continue;
}
$dns[] = $ldap_users[0];
}
$members = $dns;
}
$isInGroup = in_array($dn_user, $members);
|
|
31b7f2792
|
85 |
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, $isInGroup);
|
|
03e52840d
|
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
return $isInGroup;
}
/**
* @brief Get all groups a user belongs to
* @param $uid Name of the user
* @returns array with group names
*
* This function fetches all groups a user belongs to. It does not check
* if the user exists at all.
*/
public function getUserGroups($uid) {
if(!$this->enabled) {
return array();
}
$cacheKey = 'getUserGroups'.$uid;
|
|
31b7f2792
|
103 104 |
if($this->access->connection->isCached($cacheKey)) {
return $this->access->connection->getFromCache($cacheKey);
|
|
03e52840d
|
105 |
} |
|
31b7f2792
|
106 |
$userDN = $this->access->username2dn($uid); |
|
03e52840d
|
107 |
if(!$userDN) {
|
|
31b7f2792
|
108 |
$this->access->connection->writeToCache($cacheKey, array()); |
|
03e52840d
|
109 110 111 112 |
return array(); } //uniqueMember takes DN, memberuid the uid, so we need to distinguish |
|
31b7f2792
|
113 114 |
if((strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'uniquemember') || (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'member') |
|
03e52840d
|
115 116 |
) {
$uid = $userDN;
|
|
31b7f2792
|
117 118 |
} else if(strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid') {
$result = $this->access->readAttribute($userDN, 'uid');
|
|
03e52840d
|
119 120 121 122 123 |
$uid = $result[0];
} else {
// just in case
$uid = $userDN;
}
|
|
31b7f2792
|
124 125 126 |
$filter = $this->access->combineFilterWithAnd(array( $this->access->connection->ldapGroupFilter, $this->access->connection->ldapGroupMemberAssocAttr.'='.$uid |
|
03e52840d
|
127 |
)); |
|
31b7f2792
|
128 129 130 131 |
$groups = $this->access->fetchListOfGroups($filter, array($this->access->connection->ldapGroupDisplayName, 'dn')); $groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING); $this->access->connection->writeToCache($cacheKey, $groups); |
|
03e52840d
|
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
return $groups;
}
/**
* @brief get a list of all users in a group
* @returns array with user ids
*/
public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
if(!$this->enabled) {
return array();
}
if(!$this->groupExists($gid)) {
return array();
}
$cachekey = 'usersInGroup-'.$gid.'-'.$search.'-'.$limit.'-'.$offset;
// check for cache of the exact query
|
|
31b7f2792
|
149 |
$groupUsers = $this->access->connection->getFromCache($cachekey); |
|
03e52840d
|
150 151 152 153 154 |
if(!is_null($groupUsers)) {
return $groupUsers;
}
// check for cache of the query without limit and offset
|
|
31b7f2792
|
155 |
$groupUsers = $this->access->connection->getFromCache('usersInGroup-'.$gid.'-'.$search);
|
|
03e52840d
|
156 157 |
if(!is_null($groupUsers)) {
$groupUsers = array_slice($groupUsers, $offset, $limit);
|
|
31b7f2792
|
158 |
$this->access->connection->writeToCache($cachekey, $groupUsers); |
|
03e52840d
|
159 160 |
return $groupUsers; } |
|
31b7f2792
|
161 |
if($limit === -1) {
|
|
03e52840d
|
162 163 |
$limit = null; } |
|
31b7f2792
|
164 |
$groupDN = $this->access->groupname2dn($gid); |
|
03e52840d
|
165 166 |
if(!$groupDN) {
// group couldn't be found, return empty resultset
|
|
31b7f2792
|
167 |
$this->access->connection->writeToCache($cachekey, array()); |
|
03e52840d
|
168 169 |
return array(); } |
|
31b7f2792
|
170 171 |
$members = $this->access->readAttribute($groupDN, $this->access->connection->ldapGroupMemberAssocAttr); |
|
03e52840d
|
172 173 |
if(!$members) {
//in case users could not be retrieved, return empty resultset
|
|
31b7f2792
|
174 |
$this->access->connection->writeToCache($cachekey, array()); |
|
03e52840d
|
175 176 177 178 |
return array(); } $groupUsers = array(); |
|
31b7f2792
|
179 |
$isMemberUid = (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid'); |
|
03e52840d
|
180 181 182 |
foreach($members as $member) {
if($isMemberUid) {
//we got uids, need to get their DNs to 'tranlsate' them to usernames
|
|
31b7f2792
|
183 |
$filter = $this->access->combineFilterWithAnd(array( |
|
03e52840d
|
184 |
\OCP\Util::mb_str_replace('%uid', $member,
|
|
31b7f2792
|
185 186 |
$this->access->connection->ldapLoginFilter, 'UTF-8'), $this->access->getFilterPartForUserSearch($search) |
|
03e52840d
|
187 |
)); |
|
31b7f2792
|
188 |
$ldap_users = $this->access->fetchListOfUsers($filter, 'dn'); |
|
03e52840d
|
189 190 191 |
if(count($ldap_users) < 1) {
continue;
}
|
|
31b7f2792
|
192 |
$groupUsers[] = $this->access->dn2username($ldap_users[0]); |
|
03e52840d
|
193 194 195 |
} else {
//we got DNs, check if we need to filter by search or we can give back all of them
if(!empty($search)) {
|
|
31b7f2792
|
196 197 198 |
if(!$this->access->readAttribute($member,
$this->access->connection->ldapUserDisplayName,
$this->access->getFilterPartForUserSearch($search))) {
|
|
03e52840d
|
199 200 201 202 |
continue; } } // dn2username will also check if the users belong to the allowed base |
|
31b7f2792
|
203 |
if($ocname = $this->access->dn2username($member)) {
|
|
03e52840d
|
204 205 206 207 208 |
$groupUsers[] = $ocname; } } } natsort($groupUsers); |
|
31b7f2792
|
209 |
$this->access->connection->writeToCache('usersInGroup-'.$gid.'-'.$search, $groupUsers);
|
|
03e52840d
|
210 |
$groupUsers = array_slice($groupUsers, $offset, $limit); |
|
31b7f2792
|
211 |
$this->access->connection->writeToCache($cachekey, $groupUsers); |
|
03e52840d
|
212 213 214 215 216 |
return $groupUsers; } /** |
|
03e52840d
|
217 218 219 220 221 222 223 224 225 226 227 228 229 |
* @brief get a list of all groups
* @returns array with group names
*
* Returns a list with all groups
*/
public function getGroups($search = '', $limit = -1, $offset = 0) {
if(!$this->enabled) {
return array();
}
$cachekey = 'getGroups-'.$search.'-'.$limit.'-'.$offset;
//Check cache before driving unnecessary searches
\OCP\Util::writeLog('user_ldap', 'getGroups '.$cachekey, \OCP\Util::DEBUG);
|
|
31b7f2792
|
230 |
$ldap_groups = $this->access->connection->getFromCache($cachekey); |
|
03e52840d
|
231 232 233 234 235 236 237 238 239 |
if(!is_null($ldap_groups)) {
return $ldap_groups;
}
// if we'd pass -1 to LDAP search, we'd end up in a Protocol
// error. With a limit of 0, we get 0 results. So we pass null.
if($limit <= 0) {
$limit = null;
}
|
|
31b7f2792
|
240 241 242 |
$filter = $this->access->combineFilterWithAnd(array( $this->access->connection->ldapGroupFilter, $this->access->getFilterPartForGroupSearch($search) |
|
03e52840d
|
243 244 |
));
\OCP\Util::writeLog('user_ldap', 'getGroups Filter '.$filter, \OCP\Util::DEBUG);
|
|
31b7f2792
|
245 246 247 248 249 |
$ldap_groups = $this->access->fetchListOfGroups($filter, array($this->access->connection->ldapGroupDisplayName, 'dn'), $limit, $offset); $ldap_groups = $this->access->ownCloudGroupNames($ldap_groups); |
|
03e52840d
|
250 |
|
|
31b7f2792
|
251 |
$this->access->connection->writeToCache($cachekey, $ldap_groups); |
|
03e52840d
|
252 253 254 255 256 257 258 259 260 261 262 263 264 |
return $ldap_groups;
}
public function groupMatchesFilter($group) {
return (strripos($group, $this->groupSearch) !== false);
}
/**
* check if a group exists
* @param string $gid
* @return bool
*/
public function groupExists($gid) {
|
|
31b7f2792
|
265 266 |
if($this->access->connection->isCached('groupExists'.$gid)) {
return $this->access->connection->getFromCache('groupExists'.$gid);
|
|
03e52840d
|
267 |
} |
|
31b7f2792
|
268 269 270 |
//getting dn, if false the group does not exist. If dn, it may be mapped //only, requires more checking. $dn = $this->access->groupname2dn($gid); |
|
03e52840d
|
271 |
if(!$dn) {
|
|
31b7f2792
|
272 |
$this->access->connection->writeToCache('groupExists'.$gid, false);
|
|
03e52840d
|
273 274 275 276 |
return false; } //if group really still exists, we will be able to read its objectclass |
|
31b7f2792
|
277 |
$objcs = $this->access->readAttribute($dn, 'objectclass'); |
|
03e52840d
|
278 |
if(!$objcs || empty($objcs)) {
|
|
31b7f2792
|
279 |
$this->access->connection->writeToCache('groupExists'.$gid, false);
|
|
03e52840d
|
280 281 |
return false; } |
|
31b7f2792
|
282 |
$this->access->connection->writeToCache('groupExists'.$gid, true);
|
|
03e52840d
|
283 284 285 286 287 288 289 290 291 292 293 294 |
return true;
}
/**
* @brief Check if backend implements actions
* @param $actions bitwise-or'ed actions
* @returns boolean
*
* Returns the supported actions as int to be
* compared with OC_USER_BACKEND_CREATE_USER etc.
*/
public function implementsActions($actions) {
|
|
837968727
|
295 |
return false; |
|
03e52840d
|
296 297 |
} } |