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