xref: /dokuwiki/lib/plugins/authad/adLDAP/classes/adLDAPGroups.php (revision 0489c64b7de1b71fdd124114dd18525156f26327)
176ce1169SAndreas Gohr<?php
276ce1169SAndreas Gohr/**
376ce1169SAndreas Gohr * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
476ce1169SAndreas Gohr * Version 4.0.4
576ce1169SAndreas Gohr *
676ce1169SAndreas Gohr * PHP Version 5 with SSL and LDAP support
776ce1169SAndreas Gohr *
876ce1169SAndreas Gohr * Written by Scott Barnett, Richard Hyland
976ce1169SAndreas Gohr *   email: scott@wiggumworld.com, adldap@richardhyland.com
1076ce1169SAndreas Gohr *   http://adldap.sourceforge.net/
1176ce1169SAndreas Gohr *
1276ce1169SAndreas Gohr * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
1376ce1169SAndreas Gohr *
1476ce1169SAndreas Gohr * We'd appreciate any improvements or additions to be submitted back
1576ce1169SAndreas Gohr * to benefit the entire community :)
1676ce1169SAndreas Gohr *
1776ce1169SAndreas Gohr * This library is free software; you can redistribute it and/or
1876ce1169SAndreas Gohr * modify it under the terms of the GNU Lesser General Public
1976ce1169SAndreas Gohr * License as published by the Free Software Foundation; either
2076ce1169SAndreas Gohr * version 2.1 of the License.
2176ce1169SAndreas Gohr *
2276ce1169SAndreas Gohr * This library is distributed in the hope that it will be useful,
2376ce1169SAndreas Gohr * but WITHOUT ANY WARRANTY; without even the implied warranty of
2476ce1169SAndreas Gohr * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2576ce1169SAndreas Gohr * Lesser General Public License for more details.
2676ce1169SAndreas Gohr *
2776ce1169SAndreas Gohr * @category ToolsAndUtilities
2876ce1169SAndreas Gohr * @package adLDAP
2976ce1169SAndreas Gohr * @subpackage Groups
3076ce1169SAndreas Gohr * @author Scott Barnett, Richard Hyland
3176ce1169SAndreas Gohr * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
3276ce1169SAndreas Gohr * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
3376ce1169SAndreas Gohr * @revision $Revision: 97 $
3476ce1169SAndreas Gohr * @version 4.0.4
3576ce1169SAndreas Gohr * @link http://adldap.sourceforge.net/
3676ce1169SAndreas Gohr */
3776ce1169SAndreas Gohrrequire_once(dirname(__FILE__) . '/../adLDAP.php');
3876ce1169SAndreas Gohrrequire_once(dirname(__FILE__) . '/../collections/adLDAPGroupCollection.php');
3976ce1169SAndreas Gohr
40*0489c64bSMoisés Braga Ribeirouse dokuwiki\Utf8\Sort;
41*0489c64bSMoisés Braga Ribeiro
4276ce1169SAndreas Gohr/**
4376ce1169SAndreas Gohr* GROUP FUNCTIONS
4476ce1169SAndreas Gohr*/
4576ce1169SAndreas Gohrclass adLDAPGroups {
4676ce1169SAndreas Gohr    /**
4776ce1169SAndreas Gohr    * The current adLDAP connection via dependency injection
4876ce1169SAndreas Gohr    *
4976ce1169SAndreas Gohr    * @var adLDAP
5076ce1169SAndreas Gohr    */
5176ce1169SAndreas Gohr    protected $adldap;
5276ce1169SAndreas Gohr
5376ce1169SAndreas Gohr    public function __construct(adLDAP $adldap) {
5476ce1169SAndreas Gohr        $this->adldap = $adldap;
5576ce1169SAndreas Gohr    }
5676ce1169SAndreas Gohr
5776ce1169SAndreas Gohr    /**
5876ce1169SAndreas Gohr    * Add a group to a group
5976ce1169SAndreas Gohr    *
6076ce1169SAndreas Gohr    * @param string $parent The parent group name
6176ce1169SAndreas Gohr    * @param string $child The child group name
6276ce1169SAndreas Gohr    * @return bool
6376ce1169SAndreas Gohr    */
6476ce1169SAndreas Gohr    public function addGroup($parent,$child){
6576ce1169SAndreas Gohr
6676ce1169SAndreas Gohr        // Find the parent group's dn
6776ce1169SAndreas Gohr        $parentGroup = $this->ginfo($parent, array("cn"));
6876ce1169SAndreas Gohr        if ($parentGroup[0]["dn"] === NULL){
6976ce1169SAndreas Gohr            return false;
7076ce1169SAndreas Gohr        }
7176ce1169SAndreas Gohr        $parentDn = $parentGroup[0]["dn"];
7276ce1169SAndreas Gohr
7376ce1169SAndreas Gohr        // Find the child group's dn
7476ce1169SAndreas Gohr        $childGroup = $this->info($child, array("cn"));
7576ce1169SAndreas Gohr        if ($childGroup[0]["dn"] === NULL){
7676ce1169SAndreas Gohr            return false;
7776ce1169SAndreas Gohr        }
7876ce1169SAndreas Gohr        $childDn = $childGroup[0]["dn"];
7976ce1169SAndreas Gohr
8076ce1169SAndreas Gohr        $add = array();
8176ce1169SAndreas Gohr        $add["member"] = $childDn;
8276ce1169SAndreas Gohr
8376ce1169SAndreas Gohr        $result = @ldap_mod_add($this->adldap->getLdapConnection(), $parentDn, $add);
8476ce1169SAndreas Gohr        if ($result == false) {
8576ce1169SAndreas Gohr            return false;
8676ce1169SAndreas Gohr        }
8776ce1169SAndreas Gohr        return true;
8876ce1169SAndreas Gohr    }
8976ce1169SAndreas Gohr
9076ce1169SAndreas Gohr    /**
9176ce1169SAndreas Gohr    * Add a user to a group
9276ce1169SAndreas Gohr    *
9376ce1169SAndreas Gohr    * @param string $group The group to add the user to
9476ce1169SAndreas Gohr    * @param string $user The user to add to the group
9576ce1169SAndreas Gohr    * @param bool $isGUID Is the username passed a GUID or a samAccountName
9676ce1169SAndreas Gohr    * @return bool
9776ce1169SAndreas Gohr    */
9876ce1169SAndreas Gohr    public function addUser($group, $user, $isGUID = false)
9976ce1169SAndreas Gohr    {
10076ce1169SAndreas Gohr        // Adding a user is a bit fiddly, we need to get the full DN of the user
10176ce1169SAndreas Gohr        // and add it using the full DN of the group
10276ce1169SAndreas Gohr
10376ce1169SAndreas Gohr        // Find the user's dn
10476ce1169SAndreas Gohr        $userDn = $this->adldap->user()->dn($user, $isGUID);
10576ce1169SAndreas Gohr        if ($userDn === false) {
10676ce1169SAndreas Gohr            return false;
10776ce1169SAndreas Gohr        }
10876ce1169SAndreas Gohr
10976ce1169SAndreas Gohr        // Find the group's dn
11076ce1169SAndreas Gohr        $groupInfo = $this->info($group, array("cn"));
11176ce1169SAndreas Gohr        if ($groupInfo[0]["dn"] === NULL) {
11276ce1169SAndreas Gohr            return false;
11376ce1169SAndreas Gohr        }
11476ce1169SAndreas Gohr        $groupDn = $groupInfo[0]["dn"];
11576ce1169SAndreas Gohr
11676ce1169SAndreas Gohr        $add = array();
11776ce1169SAndreas Gohr        $add["member"] = $userDn;
11876ce1169SAndreas Gohr
11976ce1169SAndreas Gohr        $result = @ldap_mod_add($this->adldap->getLdapConnection(), $groupDn, $add);
12076ce1169SAndreas Gohr        if ($result == false) {
12176ce1169SAndreas Gohr            return false;
12276ce1169SAndreas Gohr        }
12376ce1169SAndreas Gohr        return true;
12476ce1169SAndreas Gohr    }
12576ce1169SAndreas Gohr
12676ce1169SAndreas Gohr    /**
12776ce1169SAndreas Gohr    * Add a contact to a group
12876ce1169SAndreas Gohr    *
12976ce1169SAndreas Gohr    * @param string $group The group to add the contact to
13076ce1169SAndreas Gohr    * @param string $contactDn The DN of the contact to add
13176ce1169SAndreas Gohr    * @return bool
13276ce1169SAndreas Gohr    */
13376ce1169SAndreas Gohr    public function addContact($group, $contactDn)
13476ce1169SAndreas Gohr    {
13576ce1169SAndreas Gohr        // To add a contact we take the contact's DN
13676ce1169SAndreas Gohr        // and add it using the full DN of the group
13776ce1169SAndreas Gohr
13876ce1169SAndreas Gohr        // Find the group's dn
13976ce1169SAndreas Gohr        $groupInfo = $this->info($group, array("cn"));
14076ce1169SAndreas Gohr        if ($groupInfo[0]["dn"] === NULL) {
14176ce1169SAndreas Gohr            return false;
14276ce1169SAndreas Gohr        }
14376ce1169SAndreas Gohr        $groupDn = $groupInfo[0]["dn"];
14476ce1169SAndreas Gohr
14576ce1169SAndreas Gohr        $add = array();
14676ce1169SAndreas Gohr        $add["member"] = $contactDn;
14776ce1169SAndreas Gohr
14876ce1169SAndreas Gohr        $result = @ldap_mod_add($this->adldap->getLdapConnection(), $groupDn, $add);
14976ce1169SAndreas Gohr        if ($result == false) {
15076ce1169SAndreas Gohr            return false;
15176ce1169SAndreas Gohr        }
15276ce1169SAndreas Gohr        return true;
15376ce1169SAndreas Gohr    }
15476ce1169SAndreas Gohr
15576ce1169SAndreas Gohr    /**
15676ce1169SAndreas Gohr    * Create a group
15776ce1169SAndreas Gohr    *
15876ce1169SAndreas Gohr    * @param array $attributes Default attributes of the group
15976ce1169SAndreas Gohr    * @return bool
16076ce1169SAndreas Gohr    */
16176ce1169SAndreas Gohr    public function create($attributes)
16276ce1169SAndreas Gohr    {
16376ce1169SAndreas Gohr        if (!is_array($attributes)){ return "Attributes must be an array"; }
16476ce1169SAndreas Gohr        if (!array_key_exists("group_name", $attributes)){ return "Missing compulsory field [group_name]"; }
16576ce1169SAndreas Gohr        if (!array_key_exists("container", $attributes)){ return "Missing compulsory field [container]"; }
16676ce1169SAndreas Gohr        if (!array_key_exists("description", $attributes)){ return "Missing compulsory field [description]"; }
16776ce1169SAndreas Gohr        if (!is_array($attributes["container"])){ return "Container attribute must be an array."; }
16876ce1169SAndreas Gohr        $attributes["container"] = array_reverse($attributes["container"]);
16976ce1169SAndreas Gohr
17076ce1169SAndreas Gohr        //$member_array = array();
17176ce1169SAndreas Gohr        //$member_array[0] = "cn=user1,cn=Users,dc=yourdomain,dc=com";
17276ce1169SAndreas Gohr        //$member_array[1] = "cn=administrator,cn=Users,dc=yourdomain,dc=com";
17376ce1169SAndreas Gohr
17476ce1169SAndreas Gohr        $add = array();
17576ce1169SAndreas Gohr        $add["cn"] = $attributes["group_name"];
17676ce1169SAndreas Gohr        $add["samaccountname"] = $attributes["group_name"];
17776ce1169SAndreas Gohr        $add["objectClass"] = "Group";
17876ce1169SAndreas Gohr        $add["description"] = $attributes["description"];
17976ce1169SAndreas Gohr        //$add["member"] = $member_array; UNTESTED
18076ce1169SAndreas Gohr
18176ce1169SAndreas Gohr        $container = "OU=" . implode(",OU=", $attributes["container"]);
18276ce1169SAndreas Gohr        $result = ldap_add($this->adldap->getLdapConnection(), "CN=" . $add["cn"] . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
18376ce1169SAndreas Gohr        if ($result != true) {
18476ce1169SAndreas Gohr            return false;
18576ce1169SAndreas Gohr        }
18676ce1169SAndreas Gohr        return true;
18776ce1169SAndreas Gohr    }
18876ce1169SAndreas Gohr
18976ce1169SAndreas Gohr    /**
19076ce1169SAndreas Gohr    * Delete a group account
19176ce1169SAndreas Gohr    *
19276ce1169SAndreas Gohr    * @param string $group The group to delete (please be careful here!)
19376ce1169SAndreas Gohr    *
19476ce1169SAndreas Gohr    * @return array
19576ce1169SAndreas Gohr    */
19676ce1169SAndreas Gohr    public function delete($group) {
19776ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()){ return false; }
19876ce1169SAndreas Gohr        if ($group === null){ return "Missing compulsory field [group]"; }
19976ce1169SAndreas Gohr
20076ce1169SAndreas Gohr        $groupInfo = $this->info($group, array("*"));
20176ce1169SAndreas Gohr        $dn = $groupInfo[0]['distinguishedname'][0];
20276ce1169SAndreas Gohr        $result = $this->adldap->folder()->delete($dn);
20376ce1169SAndreas Gohr        if ($result !== true) {
20476ce1169SAndreas Gohr            return false;
20576ce1169SAndreas Gohr        } return true;
20676ce1169SAndreas Gohr    }
20776ce1169SAndreas Gohr
20876ce1169SAndreas Gohr    /**
20976ce1169SAndreas Gohr    * Remove a group from a group
21076ce1169SAndreas Gohr    *
21176ce1169SAndreas Gohr    * @param string $parent The parent group name
21276ce1169SAndreas Gohr    * @param string $child The child group name
21376ce1169SAndreas Gohr    * @return bool
21476ce1169SAndreas Gohr    */
21576ce1169SAndreas Gohr    public function removeGroup($parent , $child)
21676ce1169SAndreas Gohr    {
21776ce1169SAndreas Gohr
21876ce1169SAndreas Gohr        // Find the parent dn
21976ce1169SAndreas Gohr        $parentGroup = $this->info($parent, array("cn"));
22076ce1169SAndreas Gohr        if ($parentGroup[0]["dn"] === NULL) {
22176ce1169SAndreas Gohr            return false;
22276ce1169SAndreas Gohr        }
22376ce1169SAndreas Gohr        $parentDn = $parentGroup[0]["dn"];
22476ce1169SAndreas Gohr
22576ce1169SAndreas Gohr        // Find the child dn
22676ce1169SAndreas Gohr        $childGroup = $this->info($child, array("cn"));
22776ce1169SAndreas Gohr        if ($childGroup[0]["dn"] === NULL) {
22876ce1169SAndreas Gohr            return false;
22976ce1169SAndreas Gohr        }
23076ce1169SAndreas Gohr        $childDn = $childGroup[0]["dn"];
23176ce1169SAndreas Gohr
23276ce1169SAndreas Gohr        $del = array();
23376ce1169SAndreas Gohr        $del["member"] = $childDn;
23476ce1169SAndreas Gohr
23576ce1169SAndreas Gohr        $result = @ldap_mod_del($this->adldap->getLdapConnection(), $parentDn, $del);
23676ce1169SAndreas Gohr        if ($result == false) {
23776ce1169SAndreas Gohr            return false;
23876ce1169SAndreas Gohr        }
23976ce1169SAndreas Gohr        return true;
24076ce1169SAndreas Gohr    }
24176ce1169SAndreas Gohr
24276ce1169SAndreas Gohr    /**
24376ce1169SAndreas Gohr    * Remove a user from a group
24476ce1169SAndreas Gohr    *
24576ce1169SAndreas Gohr    * @param string $group The group to remove a user from
24676ce1169SAndreas Gohr    * @param string $user The AD user to remove from the group
24776ce1169SAndreas Gohr    * @param bool $isGUID Is the username passed a GUID or a samAccountName
24876ce1169SAndreas Gohr    * @return bool
24976ce1169SAndreas Gohr    */
25076ce1169SAndreas Gohr    public function removeUser($group, $user, $isGUID = false)
25176ce1169SAndreas Gohr    {
25276ce1169SAndreas Gohr
25376ce1169SAndreas Gohr        // Find the parent dn
25476ce1169SAndreas Gohr        $groupInfo = $this->info($group, array("cn"));
25576ce1169SAndreas Gohr        if ($groupInfo[0]["dn"] === NULL){
25676ce1169SAndreas Gohr            return false;
25776ce1169SAndreas Gohr        }
25876ce1169SAndreas Gohr        $groupDn = $groupInfo[0]["dn"];
25976ce1169SAndreas Gohr
26076ce1169SAndreas Gohr        // Find the users dn
26176ce1169SAndreas Gohr        $userDn = $this->adldap->user()->dn($user, $isGUID);
26276ce1169SAndreas Gohr        if ($userDn === false) {
26376ce1169SAndreas Gohr            return false;
26476ce1169SAndreas Gohr        }
26576ce1169SAndreas Gohr
26676ce1169SAndreas Gohr        $del = array();
26776ce1169SAndreas Gohr        $del["member"] = $userDn;
26876ce1169SAndreas Gohr
26976ce1169SAndreas Gohr        $result = @ldap_mod_del($this->adldap->getLdapConnection(), $groupDn, $del);
27076ce1169SAndreas Gohr        if ($result == false) {
27176ce1169SAndreas Gohr            return false;
27276ce1169SAndreas Gohr        }
27376ce1169SAndreas Gohr        return true;
27476ce1169SAndreas Gohr    }
27576ce1169SAndreas Gohr
27676ce1169SAndreas Gohr    /**
27776ce1169SAndreas Gohr    * Remove a contact from a group
27876ce1169SAndreas Gohr    *
27976ce1169SAndreas Gohr    * @param string $group The group to remove a user from
28076ce1169SAndreas Gohr    * @param string $contactDn The DN of a contact to remove from the group
28176ce1169SAndreas Gohr    * @return bool
28276ce1169SAndreas Gohr    */
28376ce1169SAndreas Gohr    public function removeContact($group, $contactDn)
28476ce1169SAndreas Gohr    {
28576ce1169SAndreas Gohr
28676ce1169SAndreas Gohr        // Find the parent dn
28776ce1169SAndreas Gohr        $groupInfo = $this->info($group, array("cn"));
28876ce1169SAndreas Gohr        if ($groupInfo[0]["dn"] === NULL) {
28976ce1169SAndreas Gohr            return false;
29076ce1169SAndreas Gohr        }
29176ce1169SAndreas Gohr        $groupDn = $groupInfo[0]["dn"];
29276ce1169SAndreas Gohr
29376ce1169SAndreas Gohr        $del = array();
29476ce1169SAndreas Gohr        $del["member"] = $contactDn;
29576ce1169SAndreas Gohr
29676ce1169SAndreas Gohr        $result = @ldap_mod_del($this->adldap->getLdapConnection(), $groupDn, $del);
29776ce1169SAndreas Gohr        if ($result == false) {
29876ce1169SAndreas Gohr            return false;
29976ce1169SAndreas Gohr        }
30076ce1169SAndreas Gohr        return true;
30176ce1169SAndreas Gohr    }
30276ce1169SAndreas Gohr
30376ce1169SAndreas Gohr    /**
30476ce1169SAndreas Gohr    * Return a list of groups in a group
30576ce1169SAndreas Gohr    *
30676ce1169SAndreas Gohr    * @param string $group The group to query
30776ce1169SAndreas Gohr    * @param bool $recursive Recursively get groups
30876ce1169SAndreas Gohr    * @return array
30976ce1169SAndreas Gohr    */
31076ce1169SAndreas Gohr    public function inGroup($group, $recursive = NULL)
31176ce1169SAndreas Gohr    {
31276ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()){ return false; }
31376ce1169SAndreas Gohr        if ($recursive === NULL){ $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
31476ce1169SAndreas Gohr
31576ce1169SAndreas Gohr        // Search the directory for the members of a group
31676ce1169SAndreas Gohr        $info = $this->info($group, array("member","cn"));
31776ce1169SAndreas Gohr        $groups = $info[0]["member"];
31876ce1169SAndreas Gohr        if (!is_array($groups)) {
31976ce1169SAndreas Gohr            return false;
32076ce1169SAndreas Gohr        }
32176ce1169SAndreas Gohr
32276ce1169SAndreas Gohr        $groupArray = array();
32376ce1169SAndreas Gohr
32476ce1169SAndreas Gohr        for ($i=0; $i<$groups["count"]; $i++){
32576ce1169SAndreas Gohr             $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($groups[$i]) . "))";
32676ce1169SAndreas Gohr             $fields = array("samaccountname", "distinguishedname", "objectClass");
32776ce1169SAndreas Gohr             $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
32876ce1169SAndreas Gohr             $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
32976ce1169SAndreas Gohr
33076ce1169SAndreas Gohr             // not a person, look for a group
33176ce1169SAndreas Gohr             if ($entries['count'] == 0 && $recursive == true) {
33276ce1169SAndreas Gohr                $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($groups[$i]) . "))";
33376ce1169SAndreas Gohr                $fields = array("distinguishedname");
33476ce1169SAndreas Gohr                $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
33576ce1169SAndreas Gohr                $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
33676ce1169SAndreas Gohr                if (!isset($entries[0]['distinguishedname'][0])) {
33776ce1169SAndreas Gohr                    continue;
33876ce1169SAndreas Gohr                }
33976ce1169SAndreas Gohr                $subGroups = $this->inGroup($entries[0]['distinguishedname'][0], $recursive);
34076ce1169SAndreas Gohr                if (is_array($subGroups)) {
34176ce1169SAndreas Gohr                    $groupArray = array_merge($groupArray, $subGroups);
34276ce1169SAndreas Gohr                    $groupArray = array_unique($groupArray);
34376ce1169SAndreas Gohr                }
34476ce1169SAndreas Gohr                continue;
34576ce1169SAndreas Gohr             }
34676ce1169SAndreas Gohr
34776ce1169SAndreas Gohr             $groupArray[] = $entries[0]['distinguishedname'][0];
34876ce1169SAndreas Gohr        }
34976ce1169SAndreas Gohr        return $groupArray;
35076ce1169SAndreas Gohr    }
35176ce1169SAndreas Gohr
35276ce1169SAndreas Gohr    /**
35376ce1169SAndreas Gohr    * Return a list of members in a group
35476ce1169SAndreas Gohr    *
35576ce1169SAndreas Gohr    * @param string $group The group to query
35676ce1169SAndreas Gohr    * @param bool $recursive Recursively get group members
35776ce1169SAndreas Gohr    * @return array
35876ce1169SAndreas Gohr    */
35976ce1169SAndreas Gohr    public function members($group, $recursive = NULL)
36076ce1169SAndreas Gohr    {
36176ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()){ return false; }
36276ce1169SAndreas Gohr        if ($recursive === NULL){ $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
36376ce1169SAndreas Gohr        // Search the directory for the members of a group
36476ce1169SAndreas Gohr        $info = $this->info($group, array("member","cn"));
36576ce1169SAndreas Gohr        $users = $info[0]["member"];
36676ce1169SAndreas Gohr        if (!is_array($users)) {
36776ce1169SAndreas Gohr            return false;
36876ce1169SAndreas Gohr        }
36976ce1169SAndreas Gohr
37076ce1169SAndreas Gohr        $userArray = array();
37176ce1169SAndreas Gohr
37276ce1169SAndreas Gohr        for ($i=0; $i<$users["count"]; $i++){
37376ce1169SAndreas Gohr             $filter = "(&(objectCategory=person)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($users[$i]) . "))";
37476ce1169SAndreas Gohr             $fields = array("samaccountname", "distinguishedname", "objectClass");
37576ce1169SAndreas Gohr             $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
37676ce1169SAndreas Gohr             $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
37776ce1169SAndreas Gohr
37876ce1169SAndreas Gohr             // not a person, look for a group
37976ce1169SAndreas Gohr             if ($entries['count'] == 0 && $recursive == true) {
38076ce1169SAndreas Gohr                $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($users[$i]) . "))";
38176ce1169SAndreas Gohr                $fields = array("samaccountname");
38276ce1169SAndreas Gohr                $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
38376ce1169SAndreas Gohr                $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
38476ce1169SAndreas Gohr                if (!isset($entries[0]['samaccountname'][0])) {
38576ce1169SAndreas Gohr                    continue;
38676ce1169SAndreas Gohr                }
38776ce1169SAndreas Gohr                $subUsers = $this->members($entries[0]['samaccountname'][0], $recursive);
38876ce1169SAndreas Gohr                if (is_array($subUsers)) {
38976ce1169SAndreas Gohr                    $userArray = array_merge($userArray, $subUsers);
39076ce1169SAndreas Gohr                    $userArray = array_unique($userArray);
39176ce1169SAndreas Gohr                }
39276ce1169SAndreas Gohr                continue;
39376ce1169SAndreas Gohr             }
39476ce1169SAndreas Gohr             else if ($entries['count'] == 0) {
39576ce1169SAndreas Gohr                continue;
39676ce1169SAndreas Gohr             }
39776ce1169SAndreas Gohr
39876ce1169SAndreas Gohr             if ((!isset($entries[0]['samaccountname'][0]) || $entries[0]['samaccountname'][0] === NULL) && $entries[0]['distinguishedname'][0] !== NULL) {
39976ce1169SAndreas Gohr                 $userArray[] = $entries[0]['distinguishedname'][0];
40076ce1169SAndreas Gohr             }
40176ce1169SAndreas Gohr             else if ($entries[0]['samaccountname'][0] !== NULL) {
40276ce1169SAndreas Gohr                $userArray[] = $entries[0]['samaccountname'][0];
40376ce1169SAndreas Gohr             }
40476ce1169SAndreas Gohr        }
40576ce1169SAndreas Gohr        return $userArray;
40676ce1169SAndreas Gohr    }
40776ce1169SAndreas Gohr
40876ce1169SAndreas Gohr    /**
40976ce1169SAndreas Gohr    * Group Information.  Returns an array of raw information about a group.
41076ce1169SAndreas Gohr    * The group name is case sensitive
41176ce1169SAndreas Gohr    *
41276ce1169SAndreas Gohr    * @param string $groupName The group name to retrieve info about
41376ce1169SAndreas Gohr    * @param array $fields Fields to retrieve
41476ce1169SAndreas Gohr    * @return array
41576ce1169SAndreas Gohr    */
41676ce1169SAndreas Gohr    public function info($groupName, $fields = NULL)
41776ce1169SAndreas Gohr    {
41876ce1169SAndreas Gohr        if ($groupName === NULL) { return false; }
41976ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()) { return false; }
42076ce1169SAndreas Gohr
42176ce1169SAndreas Gohr        if (stristr($groupName, '+')) {
42276ce1169SAndreas Gohr            $groupName = stripslashes($groupName);
42376ce1169SAndreas Gohr        }
42476ce1169SAndreas Gohr
42576ce1169SAndreas Gohr        $filter = "(&(objectCategory=group)(name=" . $this->adldap->utilities()->ldapSlashes($groupName) . "))";
42676ce1169SAndreas Gohr        if ($fields === NULL) {
42776ce1169SAndreas Gohr            $fields = array("member","memberof","cn","description","distinguishedname","objectcategory","samaccountname");
42876ce1169SAndreas Gohr        }
42976ce1169SAndreas Gohr        $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
43076ce1169SAndreas Gohr        $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
43176ce1169SAndreas Gohr
43276ce1169SAndreas Gohr        return $entries;
43376ce1169SAndreas Gohr    }
43476ce1169SAndreas Gohr
43576ce1169SAndreas Gohr    /**
43676ce1169SAndreas Gohr    * Group Information.  Returns an collection
43776ce1169SAndreas Gohr    * The group name is case sensitive
43876ce1169SAndreas Gohr    *
43976ce1169SAndreas Gohr    * @param string $groupName The group name to retrieve info about
44076ce1169SAndreas Gohr    * @param array $fields Fields to retrieve
44176ce1169SAndreas Gohr    * @return adLDAPGroupCollection
44276ce1169SAndreas Gohr    */
44376ce1169SAndreas Gohr    public function infoCollection($groupName, $fields = NULL)
44476ce1169SAndreas Gohr    {
44576ce1169SAndreas Gohr        if ($groupName === NULL) { return false; }
44676ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()) { return false; }
44776ce1169SAndreas Gohr
44876ce1169SAndreas Gohr        $info = $this->info($groupName, $fields);
44976ce1169SAndreas Gohr        if ($info !== false) {
45076ce1169SAndreas Gohr            $collection = new adLDAPGroupCollection($info, $this->adldap);
45176ce1169SAndreas Gohr            return $collection;
45276ce1169SAndreas Gohr        }
45376ce1169SAndreas Gohr        return false;
45476ce1169SAndreas Gohr    }
45576ce1169SAndreas Gohr
45676ce1169SAndreas Gohr    /**
45776ce1169SAndreas Gohr    * Return a complete list of "groups in groups"
45876ce1169SAndreas Gohr    *
45976ce1169SAndreas Gohr    * @param string $group The group to get the list from
46076ce1169SAndreas Gohr    * @return array
46176ce1169SAndreas Gohr    */
46276ce1169SAndreas Gohr    public function recursiveGroups($group)
46376ce1169SAndreas Gohr    {
46476ce1169SAndreas Gohr        if ($group === NULL) { return false; }
46576ce1169SAndreas Gohr
46676ce1169SAndreas Gohr        $stack = array();
46776ce1169SAndreas Gohr        $processed = array();
46876ce1169SAndreas Gohr        $retGroups = array();
46976ce1169SAndreas Gohr
47076ce1169SAndreas Gohr        array_push($stack, $group); // Initial Group to Start with
47176ce1169SAndreas Gohr        while (count($stack) > 0) {
47276ce1169SAndreas Gohr            $parent = array_pop($stack);
47376ce1169SAndreas Gohr            array_push($processed, $parent);
47476ce1169SAndreas Gohr
47576ce1169SAndreas Gohr            $info = $this->info($parent, array("memberof"));
47676ce1169SAndreas Gohr
47776ce1169SAndreas Gohr            if (isset($info[0]["memberof"]) && is_array($info[0]["memberof"])) {
47876ce1169SAndreas Gohr                $groups = $info[0]["memberof"];
47976ce1169SAndreas Gohr                if ($groups) {
48076ce1169SAndreas Gohr                    $groupNames = $this->adldap->utilities()->niceNames($groups);
48176ce1169SAndreas Gohr                    $retGroups = array_merge($retGroups, $groupNames); //final groups to return
48276ce1169SAndreas Gohr                    foreach ($groupNames as $id => $groupName) {
48376ce1169SAndreas Gohr                        if (!in_array($groupName, $processed)) {
48476ce1169SAndreas Gohr                            array_push($stack, $groupName);
48576ce1169SAndreas Gohr                        }
48676ce1169SAndreas Gohr                    }
48776ce1169SAndreas Gohr                }
48876ce1169SAndreas Gohr            }
48976ce1169SAndreas Gohr        }
49076ce1169SAndreas Gohr
49176ce1169SAndreas Gohr        return $retGroups;
49276ce1169SAndreas Gohr    }
49376ce1169SAndreas Gohr
49476ce1169SAndreas Gohr    /**
49576ce1169SAndreas Gohr    * Returns a complete list of the groups in AD based on a SAM Account Type
49676ce1169SAndreas Gohr    *
49776ce1169SAndreas Gohr    * @param string $sAMAaccountType The account type to return
49876ce1169SAndreas Gohr    * @param bool $includeDescription Whether to return a description
49976ce1169SAndreas Gohr    * @param string $search Search parameters
50076ce1169SAndreas Gohr    * @param bool $sorted Whether to sort the results
50176ce1169SAndreas Gohr    * @return array
50276ce1169SAndreas Gohr    */
50376ce1169SAndreas Gohr    public function search($sAMAaccountType = adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription = false, $search = "*", $sorted = true) {
50476ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()) { return false; }
50576ce1169SAndreas Gohr
50676ce1169SAndreas Gohr        $filter = '(&(objectCategory=group)';
50776ce1169SAndreas Gohr        if ($sAMAaccountType !== null) {
50876ce1169SAndreas Gohr            $filter .= '(samaccounttype='. $sAMAaccountType .')';
50976ce1169SAndreas Gohr        }
51076ce1169SAndreas Gohr        $filter .= '(cn=' . $search . '))';
51176ce1169SAndreas Gohr        // Perform the search and grab all their details
51276ce1169SAndreas Gohr        $fields = array("samaccountname", "description");
51376ce1169SAndreas Gohr        $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
51476ce1169SAndreas Gohr        $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
51576ce1169SAndreas Gohr
51676ce1169SAndreas Gohr        $groupsArray = array();
51776ce1169SAndreas Gohr        for ($i=0; $i<$entries["count"]; $i++){
51876ce1169SAndreas Gohr            if ($includeDescription && strlen($entries[$i]["description"][0]) > 0 ) {
51976ce1169SAndreas Gohr                $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["description"][0];
52076ce1169SAndreas Gohr            }
52176ce1169SAndreas Gohr            else if ($includeDescription){
52276ce1169SAndreas Gohr                $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0];
52376ce1169SAndreas Gohr            }
52476ce1169SAndreas Gohr            else {
52576ce1169SAndreas Gohr                array_push($groupsArray, $entries[$i]["samaccountname"][0]);
52676ce1169SAndreas Gohr            }
52776ce1169SAndreas Gohr        }
52876ce1169SAndreas Gohr        if ($sorted) {
529*0489c64bSMoisés Braga Ribeiro            Sort::asort($groupsArray);
53076ce1169SAndreas Gohr        }
53176ce1169SAndreas Gohr        return $groupsArray;
53276ce1169SAndreas Gohr    }
53376ce1169SAndreas Gohr
53476ce1169SAndreas Gohr    /**
53576ce1169SAndreas Gohr    * Returns a complete list of all groups in AD
53676ce1169SAndreas Gohr    *
53776ce1169SAndreas Gohr    * @param bool $includeDescription Whether to return a description
53876ce1169SAndreas Gohr    * @param string $search Search parameters
53976ce1169SAndreas Gohr    * @param bool $sorted Whether to sort the results
54076ce1169SAndreas Gohr    * @return array
54176ce1169SAndreas Gohr    */
54276ce1169SAndreas Gohr    public function all($includeDescription = false, $search = "*", $sorted = true){
54376ce1169SAndreas Gohr        $groupsArray = $this->search(null, $includeDescription, $search, $sorted);
54476ce1169SAndreas Gohr        return $groupsArray;
54576ce1169SAndreas Gohr    }
54676ce1169SAndreas Gohr
54776ce1169SAndreas Gohr    /**
54876ce1169SAndreas Gohr    * Returns a complete list of security groups in AD
54976ce1169SAndreas Gohr    *
55076ce1169SAndreas Gohr    * @param bool $includeDescription Whether to return a description
55176ce1169SAndreas Gohr    * @param string $search Search parameters
55276ce1169SAndreas Gohr    * @param bool $sorted Whether to sort the results
55376ce1169SAndreas Gohr    * @return array
55476ce1169SAndreas Gohr    */
55576ce1169SAndreas Gohr    public function allSecurity($includeDescription = false, $search = "*", $sorted = true){
55676ce1169SAndreas Gohr        $groupsArray = $this->search(adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription, $search, $sorted);
55776ce1169SAndreas Gohr        return $groupsArray;
55876ce1169SAndreas Gohr    }
55976ce1169SAndreas Gohr
56076ce1169SAndreas Gohr    /**
56176ce1169SAndreas Gohr    * Returns a complete list of distribution lists in AD
56276ce1169SAndreas Gohr    *
56376ce1169SAndreas Gohr    * @param bool $includeDescription Whether to return a description
56476ce1169SAndreas Gohr    * @param string $search Search parameters
56576ce1169SAndreas Gohr    * @param bool $sorted Whether to sort the results
56676ce1169SAndreas Gohr    * @return array
56776ce1169SAndreas Gohr    */
56876ce1169SAndreas Gohr    public function allDistribution($includeDescription = false, $search = "*", $sorted = true){
56976ce1169SAndreas Gohr        $groupsArray = $this->search(adLDAP::ADLDAP_DISTRIBUTION_GROUP, $includeDescription, $search, $sorted);
57076ce1169SAndreas Gohr        return $groupsArray;
57176ce1169SAndreas Gohr    }
57276ce1169SAndreas Gohr
57376ce1169SAndreas Gohr    /**
57476ce1169SAndreas Gohr    * Coping with AD not returning the primary group
57576ce1169SAndreas Gohr    * http://support.microsoft.com/?kbid=321360
57676ce1169SAndreas Gohr    *
57776ce1169SAndreas Gohr    * This is a re-write based on code submitted by Bruce which prevents the
57876ce1169SAndreas Gohr    * need to search each security group to find the true primary group
57976ce1169SAndreas Gohr    *
58076ce1169SAndreas Gohr    * @param string $gid Group ID
58176ce1169SAndreas Gohr    * @param string $usersid User's Object SID
58276ce1169SAndreas Gohr    * @return mixed
58376ce1169SAndreas Gohr    */
58476ce1169SAndreas Gohr    public function getPrimaryGroup($gid, $usersid)
58576ce1169SAndreas Gohr    {
58676ce1169SAndreas Gohr        if ($gid === NULL || $usersid === NULL) { return false; }
58776ce1169SAndreas Gohr        $sr = false;
58876ce1169SAndreas Gohr
58976ce1169SAndreas Gohr        $gsid = substr_replace($usersid, pack('V',$gid), strlen($usersid)-4,4);
59076ce1169SAndreas Gohr        $filter = '(objectsid=' . $this->adldap->utilities()->getTextSID($gsid).')';
59176ce1169SAndreas Gohr        $fields = array("samaccountname","distinguishedname");
59276ce1169SAndreas Gohr        $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
59376ce1169SAndreas Gohr        $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
59476ce1169SAndreas Gohr
59576ce1169SAndreas Gohr        if (isset($entries[0]['distinguishedname'][0])) {
59676ce1169SAndreas Gohr            return $entries[0]['distinguishedname'][0];
59776ce1169SAndreas Gohr        }
59876ce1169SAndreas Gohr        return false;
59976ce1169SAndreas Gohr     }
60076ce1169SAndreas Gohr
60176ce1169SAndreas Gohr     /**
60276ce1169SAndreas Gohr    * Coping with AD not returning the primary group
60376ce1169SAndreas Gohr    * http://support.microsoft.com/?kbid=321360
60476ce1169SAndreas Gohr    *
60576ce1169SAndreas Gohr    * For some reason it's not possible to search on primarygrouptoken=XXX
60676ce1169SAndreas Gohr    * If someone can show otherwise, I'd like to know about it :)
60776ce1169SAndreas Gohr    * this way is resource intensive and generally a pain in the @#%^
60876ce1169SAndreas Gohr    *
60976ce1169SAndreas Gohr    * @deprecated deprecated since version 3.1, see get get_primary_group
61076ce1169SAndreas Gohr    * @param string $gid Group ID
61176ce1169SAndreas Gohr    * @return string
61276ce1169SAndreas Gohr    */
61376ce1169SAndreas Gohr    public function cn($gid){
61476ce1169SAndreas Gohr        if ($gid === NULL) { return false; }
61576ce1169SAndreas Gohr        $sr = false;
61676ce1169SAndreas Gohr        $r = '';
61776ce1169SAndreas Gohr
61876ce1169SAndreas Gohr        $filter = "(&(objectCategory=group)(samaccounttype=" . adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP . "))";
61976ce1169SAndreas Gohr        $fields = array("primarygrouptoken", "samaccountname", "distinguishedname");
62076ce1169SAndreas Gohr        $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
62176ce1169SAndreas Gohr        $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
62276ce1169SAndreas Gohr
62376ce1169SAndreas Gohr        for ($i=0; $i<$entries["count"]; $i++){
62476ce1169SAndreas Gohr            if ($entries[$i]["primarygrouptoken"][0] == $gid) {
62576ce1169SAndreas Gohr                $r = $entries[$i]["distinguishedname"][0];
62676ce1169SAndreas Gohr                $i = $entries["count"];
62776ce1169SAndreas Gohr            }
62876ce1169SAndreas Gohr        }
62976ce1169SAndreas Gohr
63076ce1169SAndreas Gohr        return $r;
63176ce1169SAndreas Gohr    }
63276ce1169SAndreas Gohr}
63376ce1169SAndreas Gohr?>
634