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