Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like adLDAPGroups often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use adLDAPGroups, and based on these observations, apply Extract Interface, too.
| 1 | <?php | ||
| 44 | class adLDAPGroups { | ||
| 45 | /** | ||
| 46 | * The current adLDAP connection via dependency injection | ||
| 47 | * | ||
| 48 | * @var adLDAP | ||
| 49 | */ | ||
| 50 | protected $adldap; | ||
| 51 | |||
| 52 |     public function __construct(adLDAP $adldap) { | ||
| 53 | $this->adldap = $adldap; | ||
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Add a group to a group | ||
| 58 | * | ||
| 59 | * @param string $parent The parent group name | ||
| 60 | * @param string $child The child group name | ||
| 61 | * @return bool | ||
| 62 | */ | ||
| 63 |     public function addGroup($parent, $child) { | ||
| 64 | |||
| 65 | // Find the parent group's dn | ||
| 66 |         $parentGroup = $this->ginfo($parent, array("cn")); | ||
| 67 |         if ($parentGroup[0]["dn"] === NULL) { | ||
| 68 | return false; | ||
| 69 | } | ||
| 70 | $parentDn = $parentGroup[0]["dn"]; | ||
| 71 | |||
| 72 | // Find the child group's dn | ||
| 73 |         $childGroup = $this->info($child, array("cn")); | ||
| 74 |         if ($childGroup[0]["dn"] === NULL) {  | ||
| 75 | return false; | ||
| 76 | } | ||
| 77 | $childDn = $childGroup[0]["dn"]; | ||
| 78 | |||
| 79 | $add = array(); | ||
| 80 | $add["member"] = $childDn; | ||
| 81 | |||
| 82 | $result = @ldap_mod_add($this->adldap->getLdapConnection(), $parentDn, $add); | ||
| 83 |         if ($result === false) {  | ||
| 84 | return false; | ||
| 85 | } | ||
| 86 | return true; | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * Add a user to a group | ||
| 91 | * | ||
| 92 | * @param string $group The group to add the user to | ||
| 93 | * @param string $user The user to add to the group | ||
| 94 | * @param bool $isGUID Is the username passed a GUID or a samAccountName | ||
| 95 | * @return bool | ||
| 96 | */ | ||
| 97 |     public function addUser($group, $user, $isGUID = false) { | ||
| 98 | // Adding a user is a bit fiddly, we need to get the full DN of the user | ||
| 99 | // and add it using the full DN of the group | ||
| 100 | |||
| 101 | // Find the user's dn | ||
| 102 | $userDn = $this->adldap->user()->dn($user, $isGUID); | ||
| 103 |         if ($userDn === false) {  | ||
| 104 | return false; | ||
| 105 | } | ||
| 106 | |||
| 107 | // Find the group's dn | ||
| 108 |         $groupInfo = $this->info($group, array("cn")); | ||
| 109 |         if ($groupInfo[0]["dn"] === NULL) {  | ||
| 110 | return false; | ||
| 111 | } | ||
| 112 | $groupDn = $groupInfo[0]["dn"]; | ||
| 113 | |||
| 114 | $add = array(); | ||
| 115 | $add["member"] = $userDn; | ||
| 116 | |||
| 117 | $result = @ldap_mod_add($this->adldap->getLdapConnection(), $groupDn, $add); | ||
| 118 |         if ($result === false) {  | ||
| 119 | return false; | ||
| 120 | } | ||
| 121 | return true; | ||
| 122 | } | ||
| 123 | |||
| 124 | /** | ||
| 125 | * Add a contact to a group | ||
| 126 | * | ||
| 127 | * @param string $group The group to add the contact to | ||
| 128 | * @param string $contactDn The DN of the contact to add | ||
| 129 | * @return bool | ||
| 130 | */ | ||
| 131 | public function addContact($group, $contactDn) | ||
| 132 |     { | ||
| 133 | // To add a contact we take the contact's DN | ||
| 134 | // and add it using the full DN of the group | ||
| 135 | |||
| 136 | // Find the group's dn | ||
| 137 |         $groupInfo = $this->info($group, array("cn")); | ||
| 138 |         if ($groupInfo[0]["dn"] === NULL) {  | ||
| 139 | return false; | ||
| 140 | } | ||
| 141 | $groupDn = $groupInfo[0]["dn"]; | ||
| 142 | |||
| 143 | $add = array(); | ||
| 144 | $add["member"] = $contactDn; | ||
| 145 | |||
| 146 | $result = @ldap_mod_add($this->adldap->getLdapConnection(), $groupDn, $add); | ||
| 147 |         if ($result === false) {  | ||
| 148 | return false; | ||
| 149 | } | ||
| 150 | return true; | ||
| 151 | } | ||
| 152 | |||
| 153 | /** | ||
| 154 | * Create a group | ||
| 155 | * | ||
| 156 | * @param array $attributes Default attributes of the group | ||
| 157 | * @return string|boolean | ||
| 158 | */ | ||
| 159 |     public function create($attributes) { | ||
| 160 |         if (!is_array($attributes)) { return "Attributes must be an array"; } | ||
| 161 |         if (!array_key_exists("group_name", $attributes)) { return "Missing compulsory field [group_name]"; } | ||
| 162 |         if (!array_key_exists("container", $attributes)) { return "Missing compulsory field [container]"; } | ||
| 163 |         if (!array_key_exists("description", $attributes)) { return "Missing compulsory field [description]"; } | ||
| 164 |         if (!is_array($attributes["container"])) { return "Container attribute must be an array."; } | ||
| 165 | $attributes["container"] = array_reverse($attributes["container"]); | ||
| 166 | |||
| 167 | //$member_array = array(); | ||
| 168 | //$member_array[0] = "cn=user1,cn=Users,dc=yourdomain,dc=com"; | ||
| 169 | //$member_array[1] = "cn=administrator,cn=Users,dc=yourdomain,dc=com"; | ||
| 170 | |||
| 171 | $add = array(); | ||
| 172 | $add["cn"] = $attributes["group_name"]; | ||
| 173 | $add["samaccountname"] = $attributes["group_name"]; | ||
| 174 | $add["objectClass"] = "Group"; | ||
| 175 | $add["description"] = $attributes["description"]; | ||
| 176 | //$add["member"] = $member_array; UNTESTED | ||
| 177 | |||
| 178 |         $container = "OU=".implode(",OU=", $attributes["container"]); | ||
| 179 | $result = ldap_add($this->adldap->getLdapConnection(), "CN=".$add["cn"].", ".$container.",".$this->adldap->getBaseDn(), $add); | ||
| 180 |         if ($result !== true) {  | ||
| 181 | return false; | ||
| 182 | } | ||
| 183 | return true; | ||
| 184 | } | ||
| 185 | |||
| 186 | /** | ||
| 187 | * Delete a group account | ||
| 188 | * | ||
| 189 | * @param string $group The group to delete (please be careful here!) | ||
| 190 | * | ||
| 191 | * @return string|boolean | ||
| 192 | */ | ||
| 193 |     public function delete($group) { | ||
| 194 |         if (!$this->adldap->getLdapBind()) { return false; } | ||
| 195 |         if ($group === null) { return "Missing compulsory field [group]"; } | ||
| 196 | |||
| 197 |         $groupInfo = $this->info($group, array("*")); | ||
| 198 | $dn = $groupInfo[0]['distinguishedname'][0]; | ||
| 199 | $result = $this->adldap->folder()->delete($dn); | ||
| 200 |         if ($result !== true) {  | ||
| 201 | return false; | ||
| 202 | } | ||
| 203 | return true; | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * Rename group with new group | ||
| 208 | * @param $group | ||
| 209 | * @param $newName | ||
| 210 | * @param $container | ||
| 211 | * | ||
| 212 | * @return bool | ||
| 213 | */ | ||
| 214 |     public function rename($group, $newName, $container) { | ||
| 215 | $info = $this->info($group); | ||
| 216 |         if ($info[0]["dn"] === NULL) { | ||
| 217 | return false; | ||
| 218 |         } else { | ||
| 219 | $groupDN = $info[0]["dn"]; | ||
| 220 | } | ||
| 221 | $newRDN = 'CN='.$newName; | ||
| 222 | |||
| 223 | // Determine the container | ||
| 224 | $container = array_reverse($container); | ||
| 225 |         $container = "OU=".implode(", OU=", $container); | ||
| 226 | |||
| 227 | // Do the update | ||
| 228 | $result = @ldap_rename($this->adldap->getLdapConnection(), $groupDN, $newRDN, $container.', '.$this->adldap->getBaseDn(), true); | ||
| 229 |         if ($result === false) { | ||
| 230 | return false; | ||
| 231 | } | ||
| 232 | return true; | ||
| 233 | } | ||
| 234 | |||
| 235 | /** | ||
| 236 | * Remove a group from a group | ||
| 237 | * | ||
| 238 | * @param string $parent The parent group name | ||
| 239 | * @param string $child The child group name | ||
| 240 | * @return bool | ||
| 241 | */ | ||
| 242 |     public function removeGroup($parent, $child) { | ||
| 243 | |||
| 244 | // Find the parent dn | ||
| 245 |         $parentGroup = $this->info($parent, array("cn")); | ||
| 246 |         if ($parentGroup[0]["dn"] === NULL) {  | ||
| 247 | return false; | ||
| 248 | } | ||
| 249 | $parentDn = $parentGroup[0]["dn"]; | ||
| 250 | |||
| 251 | // Find the child dn | ||
| 252 |         $childGroup = $this->info($child, array("cn")); | ||
| 253 |         if ($childGroup[0]["dn"] === NULL) {  | ||
| 254 | return false; | ||
| 255 | } | ||
| 256 | $childDn = $childGroup[0]["dn"]; | ||
| 257 | |||
| 258 | $del = array(); | ||
| 259 | $del["member"] = $childDn; | ||
| 260 | |||
| 261 | $result = @ldap_mod_del($this->adldap->getLdapConnection(), $parentDn, $del); | ||
| 262 |         if ($result === false) {  | ||
| 263 | return false; | ||
| 264 | } | ||
| 265 | return true; | ||
| 266 | } | ||
| 267 | |||
| 268 | /** | ||
| 269 | * Remove a user from a group | ||
| 270 | * | ||
| 271 | * @param string $group The group to remove a user from | ||
| 272 | * @param string $user The AD user to remove from the group | ||
| 273 | * @param bool $isGUID Is the username passed a GUID or a samAccountName | ||
| 274 | * @return bool | ||
| 275 | */ | ||
| 276 |     public function removeUser($group, $user, $isGUID = false) { | ||
| 277 | |||
| 278 | // Find the parent dn | ||
| 279 |         $groupInfo = $this->info($group, array("cn")); | ||
| 280 |         if ($groupInfo[0]["dn"] === NULL) {   | ||
| 281 | return false; | ||
| 282 | } | ||
| 283 | $groupDn = $groupInfo[0]["dn"]; | ||
| 284 | |||
| 285 | // Find the users dn | ||
| 286 | $userDn = $this->adldap->user()->dn($user, $isGUID); | ||
| 287 |         if ($userDn === false) { | ||
| 288 | return false; | ||
| 289 | } | ||
| 290 | |||
| 291 | $del = array(); | ||
| 292 | $del["member"] = $userDn; | ||
| 293 | |||
| 294 | $result = @ldap_mod_del($this->adldap->getLdapConnection(), $groupDn, $del); | ||
| 295 |         if ($result === false) { | ||
| 296 | return false; | ||
| 297 | } | ||
| 298 | return true; | ||
| 299 | } | ||
| 300 | |||
| 301 | /** | ||
| 302 | * Remove a contact from a group | ||
| 303 | * | ||
| 304 | * @param string $group The group to remove a user from | ||
| 305 | * @param string $contactDn The DN of a contact to remove from the group | ||
| 306 | * @return bool | ||
| 307 | */ | ||
| 308 |     public function removeContact($group, $contactDn) { | ||
| 309 | |||
| 310 | // Find the parent dn | ||
| 311 |         $groupInfo = $this->info($group, array("cn")); | ||
| 312 |         if ($groupInfo[0]["dn"] === NULL) {  | ||
| 313 | return false; | ||
| 314 | } | ||
| 315 | $groupDn = $groupInfo[0]["dn"]; | ||
| 316 | |||
| 317 | $del = array(); | ||
| 318 | $del["member"] = $contactDn; | ||
| 319 | |||
| 320 | $result = @ldap_mod_del($this->adldap->getLdapConnection(), $groupDn, $del); | ||
| 321 |         if ($result === false) {  | ||
| 322 | return false; | ||
| 323 | } | ||
| 324 | return true; | ||
| 325 | } | ||
| 326 | |||
| 327 | /** | ||
| 328 | * Return a list of groups in a group | ||
| 329 | * | ||
| 330 | * @param string $group The group to query | ||
| 331 | * @param bool $recursive Recursively get groups | ||
| 332 | * @return array | ||
| 333 | */ | ||
| 334 |     public function inGroup($group, $recursive = NULL) { | ||
| 335 |         if (!$this->adldap->getLdapBind()) { return false; } | ||
| 336 |         if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it  | ||
| 337 | |||
| 338 | // Search the directory for the members of a group | ||
| 339 |         $info = $this->info($group, array("member", "cn")); | ||
| 340 | $groups = $info[0]["member"]; | ||
| 341 |         if (!is_array($groups)) { | ||
| 342 | return false; | ||
| 343 | } | ||
| 344 | |||
| 345 | $groupArray = array(); | ||
| 346 | |||
| 347 |         for ($i = 0; $i < $groups["count"]; $i++) {  | ||
| 348 | $filter = "(&(objectCategory=group)(distinguishedName=".$this->adldap->utilities()->ldapSlashes($groups[$i])."))"; | ||
| 349 |                 $fields = array("samaccountname", "distinguishedname", "objectClass"); | ||
| 350 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 351 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 352 | |||
| 353 | // not a person, look for a group | ||
| 354 |                 if ($entries['count'] == 0 && $recursive === true) {   | ||
| 355 | $filter = "(&(objectCategory=group)(distinguishedName=".$this->adldap->utilities()->ldapSlashes($groups[$i])."))"; | ||
| 356 |                 $fields = array("distinguishedname");   | ||
| 357 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 358 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 359 |                 if (!isset($entries[0]['distinguishedname'][0])) { | ||
| 360 | continue; | ||
| 361 | } | ||
| 362 | $subGroups = $this->inGroup($entries[0]['distinguishedname'][0], $recursive); | ||
| 363 |                 if (is_array($subGroups)) { | ||
| 364 | $groupArray = array_merge($groupArray, $subGroups); | ||
| 365 | $groupArray = array_unique($groupArray); | ||
| 366 | } | ||
| 367 | continue; | ||
| 368 | } | ||
| 369 | $groupArray[] = $entries[0]['distinguishedname'][0]; | ||
| 370 | } | ||
| 371 | return $groupArray; | ||
| 372 | } | ||
| 373 | |||
| 374 | /** | ||
| 375 | * Return a list of members in a group | ||
| 376 | * | ||
| 377 | * @param string $group The group to query | ||
| 378 | * @param bool $recursive Recursively get group members | ||
| 379 | * @return array | ||
| 380 | */ | ||
| 381 |     public function members($group, $recursive = NULL) { | ||
| 382 |         if (!$this->adldap->getLdapBind()) { return false; } | ||
| 383 |         if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it  | ||
| 384 | // Search the directory for the members of a group | ||
| 385 |         $info = $this->info($group, array("member", "cn")); | ||
| 386 |         if (isset($info[0]["member"])) { | ||
| 387 | $users = $info[0]["member"]; | ||
| 388 |             if (!is_array($users)) { | ||
| 389 | return false; | ||
| 390 | } | ||
| 391 |         } else { | ||
| 392 | return false; | ||
| 393 | } | ||
| 394 | |||
| 395 | $userArray = array(); | ||
| 396 | |||
| 397 |         for ($i = 0; $i < $users["count"]; $i++) {  | ||
| 398 | $filter = "(&(objectCategory=person)(distinguishedName=".$this->adldap->utilities()->ldapSlashes($users[$i])."))"; | ||
| 399 |                 $fields = array("samaccountname", "distinguishedname", "objectClass"); | ||
| 400 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 401 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 402 | |||
| 403 | // not a person, look for a group | ||
| 404 |                 if ($entries['count'] == 0 && $recursive === true) {   | ||
| 405 | $filter = "(&(objectCategory=group)(distinguishedName=".$this->adldap->utilities()->ldapSlashes($users[$i])."))"; | ||
| 406 |                 $fields = array("samaccountname");   | ||
| 407 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 408 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 409 |                 if (!isset($entries[0]['samaccountname'][0])) { | ||
| 410 | continue; | ||
| 411 | } | ||
| 412 | $subUsers = $this->members($entries[0]['samaccountname'][0], $recursive); | ||
| 413 |                 if (is_array($subUsers)) { | ||
| 414 | $userArray = array_merge($userArray, $subUsers); | ||
| 415 | $userArray = array_unique($userArray); | ||
| 416 | } | ||
| 417 | continue; | ||
| 418 |                 } else if ($entries['count'] == 0) {    | ||
| 419 | continue; | ||
| 420 | } | ||
| 421 | |||
| 422 |                 if ((!isset($entries[0]['samaccountname'][0]) || $entries[0]['samaccountname'][0] === NULL) && $entries[0]['distinguishedname'][0] !== NULL) { | ||
| 423 | $userArray[] = $entries[0]['distinguishedname'][0]; | ||
| 424 |                 } else if ($entries[0]['samaccountname'][0] !== NULL) { | ||
| 425 | $userArray[] = $entries[0]['samaccountname'][0]; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | return $userArray; | ||
| 429 | } | ||
| 430 | |||
| 431 | /** | ||
| 432 | * Group Information. Returns an array of raw information about a group. | ||
| 433 | * The group name is case sensitive | ||
| 434 | * | ||
| 435 | * @param string $groupName The group name to retrieve info about | ||
| 436 | * @param array $fields Fields to retrieve | ||
| 437 | * @return array | ||
| 438 | */ | ||
| 439 |     public function info($groupName, $fields = NULL) { | ||
| 440 |         if ($groupName === NULL) { return false; } | ||
| 441 |         if (!$this->adldap->getLdapBind()) { return false; } | ||
| 442 | |||
| 443 |         if (stristr($groupName, '+')) { | ||
| 444 | $groupName = stripslashes($groupName); | ||
| 445 | } | ||
| 446 | |||
| 447 | $filter = "(&(objectCategory=group)(name=".$this->adldap->utilities()->ldapSlashes($groupName)."))"; | ||
| 448 |         if ($fields === NULL) {  | ||
| 449 |             $fields = array("member", "memberof", "cn", "description", "distinguishedname", "objectcategory", "samaccountname");  | ||
| 450 | } | ||
| 451 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 452 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 453 | |||
| 454 | // Windows 2003: Returns up to 1500 values (Windows 2000 only 1000 is not supported). | ||
| 455 |         if (isset($entries[0]['member;range=0-1499']) && $entries[0]['member;range=0-1499']['count'] == 1500) { | ||
| 456 | $entries[0]['member']['count'] = "0"; | ||
| 457 | $rangestep = 1499; // Step site | ||
| 458 | $rangelow = 0; // Initial low range | ||
| 459 | $rangehigh = $rangelow + $rangestep; // Initial high range | ||
| 460 | // do until array_keys($members[0])[0] ends with a '*', e. g. member;range=1499-*. It indicates end of the range | ||
| 461 |             do { | ||
| 462 |                 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, array("member;range=".$rangelow."-".$rangehigh)); | ||
| 463 | $members = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 464 | $memberrange = array_keys($members[0]); | ||
| 465 | $membercount = $members[0][$memberrange[0]]['count']; | ||
| 466 | // Copy range entries to member | ||
| 467 |                 for ($i = 0; $i <= $membercount - 1; $i++) { | ||
| 468 | $entries[0]['member'][] = $members[0][$memberrange[0]][$i]; | ||
| 469 | } | ||
| 470 | $entries[0]['member']['count'] += $membercount; | ||
| 471 | $rangelow += $rangestep + 1; | ||
| 472 | $rangehigh += $rangestep + 1; | ||
| 473 | } while (substr($memberrange[0], -1) != '*'); | ||
| 474 | } | ||
| 475 | return $entries; | ||
| 476 | } | ||
| 477 | |||
| 478 | /** | ||
| 479 | * Group Information. Returns an collection | ||
| 480 | * The group name is case sensitive | ||
| 481 | * | ||
| 482 | * @param string $groupName The group name to retrieve info about | ||
| 483 | * @param array $fields Fields to retrieve | ||
| 484 | * @return \adLDAP\collections\adLDAPGroupCollection | ||
| 485 | */ | ||
| 486 |     public function infoCollection($groupName, $fields = NULL) { | ||
| 487 |         if ($groupName === NULL) { return false; } | ||
| 488 |         if (!$this->adldap->getLdapBind()) { return false; } | ||
| 489 | |||
| 490 | $info = $this->info($groupName, $fields); | ||
| 491 |         if ($info !== false) { | ||
| 492 | $collection = new \adLDAP\collections\adLDAPGroupCollection($info, $this->adldap); | ||
| 493 | return $collection; | ||
| 494 | } | ||
| 495 | return false; | ||
| 496 | } | ||
| 497 | |||
| 498 | /** | ||
| 499 | * Return a complete list of "groups in groups" | ||
| 500 | * | ||
| 501 | * @param string $group The group to get the list from | ||
| 502 | * @return array | ||
| 503 | */ | ||
| 504 |     public function recursiveGroups($group) { | ||
| 505 |         if ($group === NULL) { return false; } | ||
| 506 | |||
| 507 | $stack = array(); | ||
| 508 | $processed = array(); | ||
| 509 | $retGroups = array(); | ||
| 510 | |||
| 511 | array_push($stack, $group); // Initial Group to Start with | ||
| 512 |         while (count($stack) > 0) { | ||
| 513 | $parent = array_pop($stack); | ||
| 514 | array_push($processed, $parent); | ||
| 515 | |||
| 516 |             $info = $this->info($parent, array("memberof")); | ||
| 517 | |||
| 518 |             if (isset($info[0]["memberof"]) && is_array($info[0]["memberof"])) { | ||
| 519 | $groups = $info[0]["memberof"]; | ||
| 520 |                 if ($groups) { | ||
| 521 | $groupNames = $this->adldap->utilities()->niceNames($groups); | ||
| 522 | $retGroups = array_merge($retGroups, $groupNames); //final groups to return | ||
| 523 |                     foreach ($groupNames as $id => $groupName) {  | ||
| 524 |                         if (!in_array($groupName, $processed)) { | ||
| 525 | array_push($stack, $groupName); | ||
| 526 | } | ||
| 527 | } | ||
| 528 | } | ||
| 529 | } | ||
| 530 | } | ||
| 531 | return $retGroups; | ||
| 532 | } | ||
| 533 | |||
| 534 | /** | ||
| 535 | * Returns a complete list of the groups in AD based on a SAM Account Type | ||
| 536 | * | ||
| 537 | * @param string $sAMAaccountType The account type to return | ||
| 538 | * @param bool $includeDescription Whether to return a description | ||
| 539 | * @param string $search Search parameters | ||
| 540 | * @param bool $sorted Whether to sort the results | ||
| 541 | * @return array | ||
| 542 | */ | ||
| 543 |     public function search($sAMAaccountType = adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription = false, $search = "*", $sorted = true) { | ||
| 544 |         if (!$this->adldap->getLdapBind()) { return false; } | ||
| 545 | |||
| 546 | $filter = '(&(objectCategory=group)'; | ||
| 547 |         if ($sAMAaccountType !== null) { | ||
| 548 | $filter .= '(samaccounttype='.$sAMAaccountType.')'; | ||
| 549 | } | ||
| 550 | $filter .= '(cn='.$search.'))'; | ||
| 551 | // Perform the search and grab all their details | ||
| 552 |         $fields = array("samaccountname", "description"); | ||
| 553 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 554 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 555 | |||
| 556 | $groupsArray = array(); | ||
| 557 |         for ($i = 0; $i < $entries["count"]; $i++) { | ||
| 558 |             if ($includeDescription && strlen($entries[$i]["description"][0]) > 0) { | ||
| 559 | $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["description"][0]; | ||
| 560 |             } else if ($includeDescription) { | ||
| 561 | $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0]; | ||
| 562 |             } else { | ||
| 563 | array_push($groupsArray, $entries[$i]["samaccountname"][0]); | ||
| 564 | } | ||
| 565 | } | ||
| 566 |         if ($sorted) {  | ||
| 567 | asort($groupsArray); | ||
| 568 | } | ||
| 569 | return $groupsArray; | ||
| 570 | } | ||
| 571 | |||
| 572 | /** | ||
| 573 | * Obtain the group's distinguished name based on their groupid | ||
| 574 | * | ||
| 575 | * | ||
| 576 | * @param string $groupname The groupname | ||
| 577 | * @return string | ||
| 578 | */ | ||
| 579 |     public function dn($groupname) { | ||
| 580 |         $group = $this->info($groupname, array("cn")); | ||
| 581 |         if ($group[0]["dn"] === NULL) { | ||
| 582 | return false; | ||
| 583 | } | ||
| 584 | $groupDn = $group[0]["dn"]; | ||
| 585 | return $groupDn; | ||
| 586 | } | ||
| 587 | |||
| 588 | /** | ||
| 589 | * Returns a complete list of all groups in AD | ||
| 590 | * | ||
| 591 | * @param bool $includeDescription Whether to return a description | ||
| 592 | * @param string $search Search parameters | ||
| 593 | * @param bool $sorted Whether to sort the results | ||
| 594 | * @return array | ||
| 595 | */ | ||
| 596 |     public function all($includeDescription = false, $search = "*", $sorted = true) { | ||
| 597 | $groupsArray = $this->search(null, $includeDescription, $search, $sorted); | ||
| 598 | return $groupsArray; | ||
| 599 | } | ||
| 600 | |||
| 601 | /** | ||
| 602 | * Returns a complete list of security groups in AD | ||
| 603 | * | ||
| 604 | * @param bool $includeDescription Whether to return a description | ||
| 605 | * @param string $search Search parameters | ||
| 606 | * @param bool $sorted Whether to sort the results | ||
| 607 | * @return array | ||
| 608 | */ | ||
| 609 |     public function allSecurity($includeDescription = false, $search = "*", $sorted = true) { | ||
| 610 | $groupsArray = $this->search(adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription, $search, $sorted); | ||
| 611 | return $groupsArray; | ||
| 612 | } | ||
| 613 | |||
| 614 | /** | ||
| 615 | * Returns a complete list of distribution lists in AD | ||
| 616 | * | ||
| 617 | * @param bool $includeDescription Whether to return a description | ||
| 618 | * @param string $search Search parameters | ||
| 619 | * @param bool $sorted Whether to sort the results | ||
| 620 | * @return array | ||
| 621 | */ | ||
| 622 |     public function allDistribution($includeDescription = false, $search = "*", $sorted = true) { | ||
| 623 | $groupsArray = $this->search(adLDAP::ADLDAP_DISTRIBUTION_GROUP, $includeDescription, $search, $sorted); | ||
| 624 | return $groupsArray; | ||
| 625 | } | ||
| 626 | |||
| 627 | /** | ||
| 628 | * Coping with AD not returning the primary group | ||
| 629 | * http://support.microsoft.com/?kbid=321360 | ||
| 630 | * | ||
| 631 | * This is a re-write based on code submitted by Bruce which prevents the | ||
| 632 | * need to search each security group to find the true primary group | ||
| 633 | * | ||
| 634 | * @param string $gid Group ID | ||
| 635 | * @param string $usersid User's Object SID | ||
| 636 | * @return mixed | ||
| 637 | */ | ||
| 638 |     public function getPrimaryGroup($gid, $usersid) { | ||
| 639 |         if ($gid === NULL || $usersid === NULL) { return false; } | ||
| 640 | $sr = false; | ||
| 641 | |||
| 642 |         $gsid = substr_replace($usersid, pack('V', $gid), strlen($usersid) - 4, 4); | ||
| 643 | $filter = '(objectsid='.$this->adldap->utilities()->getTextSID($gsid).')'; | ||
| 644 |         $fields = array("samaccountname", "distinguishedname"); | ||
| 645 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 646 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 647 | |||
| 648 |         if (isset($entries[0]['distinguishedname'][0])) { | ||
| 649 | return $entries[0]['distinguishedname'][0]; | ||
| 650 | } | ||
| 651 | return false; | ||
| 652 | } | ||
| 653 | |||
| 654 | /** | ||
| 655 | * Coping with AD not returning the primary group | ||
| 656 | * http://support.microsoft.com/?kbid=321360 | ||
| 657 | * | ||
| 658 | * For some reason it's not possible to search on primarygrouptoken=XXX | ||
| 659 | * If someone can show otherwise, I'd like to know about it :) | ||
| 660 | * this way is resource intensive and generally a pain in the @#%^ | ||
| 661 | * | ||
| 662 | * @deprecated deprecated since version 3.1, see get get_primary_group | ||
| 663 | * @param string $gid Group ID | ||
| 664 | * @return string | ||
| 665 | */ | ||
| 666 |     public function cn($gid) {     | ||
| 667 |         if ($gid === NULL) { return false; } | ||
| 668 | $sr = false; | ||
| 669 | $r = ''; | ||
| 670 | |||
| 671 | $filter = "(&(objectCategory=group)(samaccounttype=".adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP."))"; | ||
| 672 |         $fields = array("primarygrouptoken", "samaccountname", "distinguishedname"); | ||
| 673 | $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); | ||
| 674 | $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); | ||
| 675 | |||
| 676 |         for ($i = 0; $i < $entries["count"]; $i++) { | ||
| 677 |             if ($entries[$i]["primarygrouptoken"][0] == $gid) { | ||
| 678 | $r = $entries[$i]["distinguishedname"][0]; | ||
| 679 | $i = $entries["count"]; | ||
| 680 | } | ||
| 681 | } | ||
| 682 | return $r; | ||
| 683 | } | ||
| 684 | } | ||
| 685 | ?> | ||
| 686 |