"Fossies" - the Fresh Open Source Software Archive 
Member "adLDAP-4.0.4/src/classes/adLDAPGroups.php" (13 Apr 2013, 23532 Bytes) of package /linux/www/old/adLDAP-4.0.4.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "adLDAPGroups.php" see the
Fossies "Dox" file reference documentation.
1 <?php
2 /**
3 * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
4 * Version 4.0.4
5 *
6 * PHP Version 5 with SSL and LDAP support
7 *
8 * Written by Scott Barnett, Richard Hyland
9 * email: scott@wiggumworld.com, adldap@richardhyland.com
10 * http://adldap.sourceforge.net/
11 *
12 * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
13 *
14 * We'd appreciate any improvements or additions to be submitted back
15 * to benefit the entire community :)
16 *
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License.
21 *
22 * This library is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * @category ToolsAndUtilities
28 * @package adLDAP
29 * @subpackage Groups
30 * @author Scott Barnett, Richard Hyland
31 * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
32 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
33 * @revision $Revision: 97 $
34 * @version 4.0.4
35 * @link http://adldap.sourceforge.net/
36 */
37 require_once(dirname(__FILE__) . '/../adLDAP.php');
38 require_once(dirname(__FILE__) . '/../collections/adLDAPGroupCollection.php');
39
40 /**
41 * GROUP FUNCTIONS
42 */
43 class adLDAPGroups {
44 /**
45 * The current adLDAP connection via dependency injection
46 *
47 * @var adLDAP
48 */
49 protected $adldap;
50
51 public function __construct(adLDAP $adldap) {
52 $this->adldap = $adldap;
53 }
54
55 /**
56 * Add a group to a group
57 *
58 * @param string $parent The parent group name
59 * @param string $child The child group name
60 * @return bool
61 */
62 public function addGroup($parent,$child){
63
64 // Find the parent group's dn
65 $parentGroup = $this->ginfo($parent, array("cn"));
66 if ($parentGroup[0]["dn"] === NULL){
67 return false;
68 }
69 $parentDn = $parentGroup[0]["dn"];
70
71 // Find the child group's dn
72 $childGroup = $this->info($child, array("cn"));
73 if ($childGroup[0]["dn"] === NULL){
74 return false;
75 }
76 $childDn = $childGroup[0]["dn"];
77
78 $add = array();
79 $add["member"] = $childDn;
80
81 $result = @ldap_mod_add($this->adldap->getLdapConnection(), $parentDn, $add);
82 if ($result == false) {
83 return false;
84 }
85 return true;
86 }
87
88 /**
89 * Add a user to a group
90 *
91 * @param string $group The group to add the user to
92 * @param string $user The user to add to the group
93 * @param bool $isGUID Is the username passed a GUID or a samAccountName
94 * @return bool
95 */
96 public function addUser($group, $user, $isGUID = false)
97 {
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 bool
158 */
159 public function create($attributes)
160 {
161 if (!is_array($attributes)){ return "Attributes must be an array"; }
162 if (!array_key_exists("group_name", $attributes)){ return "Missing compulsory field [group_name]"; }
163 if (!array_key_exists("container", $attributes)){ return "Missing compulsory field [container]"; }
164 if (!array_key_exists("description", $attributes)){ return "Missing compulsory field [description]"; }
165 if (!is_array($attributes["container"])){ return "Container attribute must be an array."; }
166 $attributes["container"] = array_reverse($attributes["container"]);
167
168 //$member_array = array();
169 //$member_array[0] = "cn=user1,cn=Users,dc=yourdomain,dc=com";
170 //$member_array[1] = "cn=administrator,cn=Users,dc=yourdomain,dc=com";
171
172 $add = array();
173 $add["cn"] = $attributes["group_name"];
174 $add["samaccountname"] = $attributes["group_name"];
175 $add["objectClass"] = "Group";
176 $add["description"] = $attributes["description"];
177 //$add["member"] = $member_array; UNTESTED
178
179 $container = "OU=" . implode(",OU=", $attributes["container"]);
180 $result = ldap_add($this->adldap->getLdapConnection(), "CN=" . $add["cn"] . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
181 if ($result != true) {
182 return false;
183 }
184 return true;
185 }
186
187 /**
188 * Delete a group account
189 *
190 * @param string $group The group to delete (please be careful here!)
191 *
192 * @return array
193 */
194 public function delete($group) {
195 if (!$this->adldap->getLdapBind()){ return false; }
196 if ($group === null){ return "Missing compulsory field [group]"; }
197
198 $groupInfo = $this->info($group, array("*"));
199 $dn = $groupInfo[0]['distinguishedname'][0];
200 $result = $this->adldap->folder()->delete($dn);
201 if ($result !== true) {
202 return false;
203 } return true;
204 }
205
206 /**
207 * Remove a group from a group
208 *
209 * @param string $parent The parent group name
210 * @param string $child The child group name
211 * @return bool
212 */
213 public function removeGroup($parent , $child)
214 {
215
216 // Find the parent dn
217 $parentGroup = $this->info($parent, array("cn"));
218 if ($parentGroup[0]["dn"] === NULL) {
219 return false;
220 }
221 $parentDn = $parentGroup[0]["dn"];
222
223 // Find the child dn
224 $childGroup = $this->info($child, array("cn"));
225 if ($childGroup[0]["dn"] === NULL) {
226 return false;
227 }
228 $childDn = $childGroup[0]["dn"];
229
230 $del = array();
231 $del["member"] = $childDn;
232
233 $result = @ldap_mod_del($this->adldap->getLdapConnection(), $parentDn, $del);
234 if ($result == false) {
235 return false;
236 }
237 return true;
238 }
239
240 /**
241 * Remove a user from a group
242 *
243 * @param string $group The group to remove a user from
244 * @param string $user The AD user to remove from the group
245 * @param bool $isGUID Is the username passed a GUID or a samAccountName
246 * @return bool
247 */
248 public function removeUser($group, $user, $isGUID = false)
249 {
250
251 // Find the parent dn
252 $groupInfo = $this->info($group, array("cn"));
253 if ($groupInfo[0]["dn"] === NULL){
254 return false;
255 }
256 $groupDn = $groupInfo[0]["dn"];
257
258 // Find the users dn
259 $userDn = $this->adldap->user()->dn($user, $isGUID);
260 if ($userDn === false) {
261 return false;
262 }
263
264 $del = array();
265 $del["member"] = $userDn;
266
267 $result = @ldap_mod_del($this->adldap->getLdapConnection(), $groupDn, $del);
268 if ($result == false) {
269 return false;
270 }
271 return true;
272 }
273
274 /**
275 * Remove a contact from a group
276 *
277 * @param string $group The group to remove a user from
278 * @param string $contactDn The DN of a contact to remove from the group
279 * @return bool
280 */
281 public function removeContact($group, $contactDn)
282 {
283
284 // Find the parent dn
285 $groupInfo = $this->info($group, array("cn"));
286 if ($groupInfo[0]["dn"] === NULL) {
287 return false;
288 }
289 $groupDn = $groupInfo[0]["dn"];
290
291 $del = array();
292 $del["member"] = $contactDn;
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 * Return a list of groups in a group
303 *
304 * @param string $group The group to query
305 * @param bool $recursive Recursively get groups
306 * @return array
307 */
308 public function inGroup($group, $recursive = NULL)
309 {
310 if (!$this->adldap->getLdapBind()){ return false; }
311 if ($recursive === NULL){ $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
312
313 // Search the directory for the members of a group
314 $info = $this->info($group, array("member","cn"));
315 $groups = $info[0]["member"];
316 if (!is_array($groups)) {
317 return false;
318 }
319
320 $groupArray = array();
321
322 for ($i=0; $i<$groups["count"]; $i++){
323 $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($groups[$i]) . "))";
324 $fields = array("samaccountname", "distinguishedname", "objectClass");
325 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
326 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
327
328 // not a person, look for a group
329 if ($entries['count'] == 0 && $recursive == true) {
330 $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($groups[$i]) . "))";
331 $fields = array("distinguishedname");
332 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
333 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
334 if (!isset($entries[0]['distinguishedname'][0])) {
335 continue;
336 }
337 $subGroups = $this->inGroup($entries[0]['distinguishedname'][0], $recursive);
338 if (is_array($subGroups)) {
339 $groupArray = array_merge($groupArray, $subGroups);
340 $groupArray = array_unique($groupArray);
341 }
342 continue;
343 }
344
345 $groupArray[] = $entries[0]['distinguishedname'][0];
346 }
347 return $groupArray;
348 }
349
350 /**
351 * Return a list of members in a group
352 *
353 * @param string $group The group to query
354 * @param bool $recursive Recursively get group members
355 * @return array
356 */
357 public function members($group, $recursive = NULL)
358 {
359 if (!$this->adldap->getLdapBind()){ return false; }
360 if ($recursive === NULL){ $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
361 // Search the directory for the members of a group
362 $info = $this->info($group, array("member","cn"));
363 $users = $info[0]["member"];
364 if (!is_array($users)) {
365 return false;
366 }
367
368 $userArray = array();
369
370 for ($i=0; $i<$users["count"]; $i++){
371 $filter = "(&(objectCategory=person)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($users[$i]) . "))";
372 $fields = array("samaccountname", "distinguishedname", "objectClass");
373 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
374 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
375
376 // not a person, look for a group
377 if ($entries['count'] == 0 && $recursive == true) {
378 $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($users[$i]) . "))";
379 $fields = array("samaccountname");
380 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
381 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
382 if (!isset($entries[0]['samaccountname'][0])) {
383 continue;
384 }
385 $subUsers = $this->members($entries[0]['samaccountname'][0], $recursive);
386 if (is_array($subUsers)) {
387 $userArray = array_merge($userArray, $subUsers);
388 $userArray = array_unique($userArray);
389 }
390 continue;
391 }
392 else if ($entries['count'] == 0) {
393 continue;
394 }
395
396 if ((!isset($entries[0]['samaccountname'][0]) || $entries[0]['samaccountname'][0] === NULL) && $entries[0]['distinguishedname'][0] !== NULL) {
397 $userArray[] = $entries[0]['distinguishedname'][0];
398 }
399 else if ($entries[0]['samaccountname'][0] !== NULL) {
400 $userArray[] = $entries[0]['samaccountname'][0];
401 }
402 }
403 return $userArray;
404 }
405
406 /**
407 * Group Information. Returns an array of raw information about a group.
408 * The group name is case sensitive
409 *
410 * @param string $groupName The group name to retrieve info about
411 * @param array $fields Fields to retrieve
412 * @return array
413 */
414 public function info($groupName, $fields = NULL)
415 {
416 if ($groupName === NULL) { return false; }
417 if (!$this->adldap->getLdapBind()) { return false; }
418
419 if (stristr($groupName, '+')) {
420 $groupName = stripslashes($groupName);
421 }
422
423 $filter = "(&(objectCategory=group)(name=" . $this->adldap->utilities()->ldapSlashes($groupName) . "))";
424 if ($fields === NULL) {
425 $fields = array("member","memberof","cn","description","distinguishedname","objectcategory","samaccountname");
426 }
427 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
428 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
429
430 return $entries;
431 }
432
433 /**
434 * Group Information. Returns an collection
435 * The group name is case sensitive
436 *
437 * @param string $groupName The group name to retrieve info about
438 * @param array $fields Fields to retrieve
439 * @return adLDAPGroupCollection
440 */
441 public function infoCollection($groupName, $fields = NULL)
442 {
443 if ($groupName === NULL) { return false; }
444 if (!$this->adldap->getLdapBind()) { return false; }
445
446 $info = $this->info($groupName, $fields);
447 if ($info !== false) {
448 $collection = new adLDAPGroupCollection($info, $this->adldap);
449 return $collection;
450 }
451 return false;
452 }
453
454 /**
455 * Return a complete list of "groups in groups"
456 *
457 * @param string $group The group to get the list from
458 * @return array
459 */
460 public function recursiveGroups($group)
461 {
462 if ($group === NULL) { return false; }
463
464 $stack = array();
465 $processed = array();
466 $retGroups = array();
467
468 array_push($stack, $group); // Initial Group to Start with
469 while (count($stack) > 0) {
470 $parent = array_pop($stack);
471 array_push($processed, $parent);
472
473 $info = $this->info($parent, array("memberof"));
474
475 if (isset($info[0]["memberof"]) && is_array($info[0]["memberof"])) {
476 $groups = $info[0]["memberof"];
477 if ($groups) {
478 $groupNames = $this->adldap->utilities()->niceNames($groups);
479 $retGroups = array_merge($retGroups, $groupNames); //final groups to return
480 foreach ($groupNames as $id => $groupName) {
481 if (!in_array($groupName, $processed)) {
482 array_push($stack, $groupName);
483 }
484 }
485 }
486 }
487 }
488
489 return $retGroups;
490 }
491
492 /**
493 * Returns a complete list of the groups in AD based on a SAM Account Type
494 *
495 * @param string $sAMAaccountType The account type to return
496 * @param bool $includeDescription Whether to return a description
497 * @param string $search Search parameters
498 * @param bool $sorted Whether to sort the results
499 * @return array
500 */
501 public function search($sAMAaccountType = adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription = false, $search = "*", $sorted = true) {
502 if (!$this->adldap->getLdapBind()) { return false; }
503
504 $filter = '(&(objectCategory=group)';
505 if ($sAMAaccountType !== null) {
506 $filter .= '(samaccounttype='. $sAMAaccountType .')';
507 }
508 $filter .= '(cn=' . $search . '))';
509 // Perform the search and grab all their details
510 $fields = array("samaccountname", "description");
511 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
512 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
513
514 $groupsArray = array();
515 for ($i=0; $i<$entries["count"]; $i++){
516 if ($includeDescription && strlen($entries[$i]["description"][0]) > 0 ) {
517 $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["description"][0];
518 }
519 else if ($includeDescription){
520 $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0];
521 }
522 else {
523 array_push($groupsArray, $entries[$i]["samaccountname"][0]);
524 }
525 }
526 if ($sorted) {
527 asort($groupsArray);
528 }
529 return $groupsArray;
530 }
531
532 /**
533 * Returns a complete list of all groups in AD
534 *
535 * @param bool $includeDescription Whether to return a description
536 * @param string $search Search parameters
537 * @param bool $sorted Whether to sort the results
538 * @return array
539 */
540 public function all($includeDescription = false, $search = "*", $sorted = true){
541 $groupsArray = $this->search(null, $includeDescription, $search, $sorted);
542 return $groupsArray;
543 }
544
545 /**
546 * Returns a complete list of security groups in AD
547 *
548 * @param bool $includeDescription Whether to return a description
549 * @param string $search Search parameters
550 * @param bool $sorted Whether to sort the results
551 * @return array
552 */
553 public function allSecurity($includeDescription = false, $search = "*", $sorted = true){
554 $groupsArray = $this->search(adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription, $search, $sorted);
555 return $groupsArray;
556 }
557
558 /**
559 * Returns a complete list of distribution lists in AD
560 *
561 * @param bool $includeDescription Whether to return a description
562 * @param string $search Search parameters
563 * @param bool $sorted Whether to sort the results
564 * @return array
565 */
566 public function allDistribution($includeDescription = false, $search = "*", $sorted = true){
567 $groupsArray = $this->search(adLDAP::ADLDAP_DISTRIBUTION_GROUP, $includeDescription, $search, $sorted);
568 return $groupsArray;
569 }
570
571 /**
572 * Coping with AD not returning the primary group
573 * http://support.microsoft.com/?kbid=321360
574 *
575 * This is a re-write based on code submitted by Bruce which prevents the
576 * need to search each security group to find the true primary group
577 *
578 * @param string $gid Group ID
579 * @param string $usersid User's Object SID
580 * @return mixed
581 */
582 public function getPrimaryGroup($gid, $usersid)
583 {
584 if ($gid === NULL || $usersid === NULL) { return false; }
585 $sr = false;
586
587 $gsid = substr_replace($usersid, pack('V',$gid), strlen($usersid)-4,4);
588 $filter = '(objectsid=' . $this->adldap->utilities()->getTextSID($gsid).')';
589 $fields = array("samaccountname","distinguishedname");
590 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
591 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
592
593 if (isset($entries[0]['distinguishedname'][0])) {
594 return $entries[0]['distinguishedname'][0];
595 }
596 return false;
597 }
598
599 /**
600 * Coping with AD not returning the primary group
601 * http://support.microsoft.com/?kbid=321360
602 *
603 * For some reason it's not possible to search on primarygrouptoken=XXX
604 * If someone can show otherwise, I'd like to know about it :)
605 * this way is resource intensive and generally a pain in the @#%^
606 *
607 * @deprecated deprecated since version 3.1, see get get_primary_group
608 * @param string $gid Group ID
609 * @return string
610 */
611 public function cn($gid){
612 if ($gid === NULL) { return false; }
613 $sr = false;
614 $r = '';
615
616 $filter = "(&(objectCategory=group)(samaccounttype=" . adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP . "))";
617 $fields = array("primarygrouptoken", "samaccountname", "distinguishedname");
618 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
619 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
620
621 for ($i=0; $i<$entries["count"]; $i++){
622 if ($entries[$i]["primarygrouptoken"][0] == $gid) {
623 $r = $entries[$i]["distinguishedname"][0];
624 $i = $entries["count"];
625 }
626 }
627
628 return $r;
629 }
630 }
631 ?>