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 Contacts 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 Gohr 38*76ce1169SAndreas Gohrrequire_once(dirname(__FILE__) . '/../adLDAP.php'); 39*76ce1169SAndreas Gohrrequire_once(dirname(__FILE__) . '/../collections/adLDAPContactCollection.php'); 40*76ce1169SAndreas Gohr 41*76ce1169SAndreas Gohrclass adLDAPContacts { 42*76ce1169SAndreas Gohr /** 43*76ce1169SAndreas Gohr * The current adLDAP connection via dependency injection 44*76ce1169SAndreas Gohr * 45*76ce1169SAndreas Gohr * @var adLDAP 46*76ce1169SAndreas Gohr */ 47*76ce1169SAndreas Gohr protected $adldap; 48*76ce1169SAndreas Gohr 49*76ce1169SAndreas Gohr public function __construct(adLDAP $adldap) { 50*76ce1169SAndreas Gohr $this->adldap = $adldap; 51*76ce1169SAndreas Gohr } 52*76ce1169SAndreas Gohr 53*76ce1169SAndreas Gohr //***************************************************************************************************************** 54*76ce1169SAndreas Gohr // CONTACT FUNCTIONS 55*76ce1169SAndreas Gohr // * Still work to do in this area, and new functions to write 56*76ce1169SAndreas Gohr 57*76ce1169SAndreas Gohr /** 58*76ce1169SAndreas Gohr * Create a contact 59*76ce1169SAndreas Gohr * 60*76ce1169SAndreas Gohr * @param array $attributes The attributes to set to the contact 61*76ce1169SAndreas Gohr * @return bool 62*76ce1169SAndreas Gohr */ 63*76ce1169SAndreas Gohr public function create($attributes) 64*76ce1169SAndreas Gohr { 65*76ce1169SAndreas Gohr // Check for compulsory fields 66*76ce1169SAndreas Gohr if (!array_key_exists("display_name", $attributes)) { return "Missing compulsory field [display_name]"; } 67*76ce1169SAndreas Gohr if (!array_key_exists("email", $attributes)) { return "Missing compulsory field [email]"; } 68*76ce1169SAndreas Gohr if (!array_key_exists("container", $attributes)) { return "Missing compulsory field [container]"; } 69*76ce1169SAndreas Gohr if (!is_array($attributes["container"])) { return "Container attribute must be an array."; } 70*76ce1169SAndreas Gohr 71*76ce1169SAndreas Gohr // Translate the schema 72*76ce1169SAndreas Gohr $add = $this->adldap->adldap_schema($attributes); 73*76ce1169SAndreas Gohr 74*76ce1169SAndreas Gohr // Additional stuff only used for adding contacts 75*76ce1169SAndreas Gohr $add["cn"][0] = $attributes["display_name"]; 76*76ce1169SAndreas Gohr $add["objectclass"][0] = "top"; 77*76ce1169SAndreas Gohr $add["objectclass"][1] = "person"; 78*76ce1169SAndreas Gohr $add["objectclass"][2] = "organizationalPerson"; 79*76ce1169SAndreas Gohr $add["objectclass"][3] = "contact"; 80*76ce1169SAndreas Gohr if (!isset($attributes['exchange_hidefromlists'])) { 81*76ce1169SAndreas Gohr $add["msExchHideFromAddressLists"][0] = "TRUE"; 82*76ce1169SAndreas Gohr } 83*76ce1169SAndreas Gohr 84*76ce1169SAndreas Gohr // Determine the container 85*76ce1169SAndreas Gohr $attributes["container"] = array_reverse($attributes["container"]); 86*76ce1169SAndreas Gohr $container= "OU=" . implode(",OU=", $attributes["container"]); 87*76ce1169SAndreas Gohr 88*76ce1169SAndreas Gohr // Add the entry 89*76ce1169SAndreas Gohr $result = @ldap_add($this->adldap->getLdapConnection(), "CN=" . $this->adldap->utilities()->escapeCharacters($add["cn"][0]) . ", " . $container . "," . $this->adldap->getBaseDn(), $add); 90*76ce1169SAndreas Gohr if ($result != true) { 91*76ce1169SAndreas Gohr return false; 92*76ce1169SAndreas Gohr } 93*76ce1169SAndreas Gohr 94*76ce1169SAndreas Gohr return true; 95*76ce1169SAndreas Gohr } 96*76ce1169SAndreas Gohr 97*76ce1169SAndreas Gohr /** 98*76ce1169SAndreas Gohr * Determine the list of groups a contact is a member of 99*76ce1169SAndreas Gohr * 100*76ce1169SAndreas Gohr * @param string $distinguisedname The full DN of a contact 101*76ce1169SAndreas Gohr * @param bool $recursive Recursively check groups 102*76ce1169SAndreas Gohr * @return array 103*76ce1169SAndreas Gohr */ 104*76ce1169SAndreas Gohr public function groups($distinguishedName, $recursive = NULL) 105*76ce1169SAndreas Gohr { 106*76ce1169SAndreas Gohr if ($distinguishedName === NULL) { return false; } 107*76ce1169SAndreas Gohr if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it 108*76ce1169SAndreas Gohr if (!$this->adldap->getLdapBind()){ return false; } 109*76ce1169SAndreas Gohr 110*76ce1169SAndreas Gohr // Search the directory for their information 111*76ce1169SAndreas Gohr $info = @$this->info($distinguishedName, array("memberof", "primarygroupid")); 112*76ce1169SAndreas Gohr $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); //presuming the entry returned is our contact 113*76ce1169SAndreas Gohr 114*76ce1169SAndreas Gohr if ($recursive === true){ 115*76ce1169SAndreas Gohr foreach ($groups as $id => $groupName){ 116*76ce1169SAndreas Gohr $extraGroups = $this->adldap->group()->recursiveGroups($groupName); 117*76ce1169SAndreas Gohr $groups = array_merge($groups, $extraGroups); 118*76ce1169SAndreas Gohr } 119*76ce1169SAndreas Gohr } 120*76ce1169SAndreas Gohr 121*76ce1169SAndreas Gohr return $groups; 122*76ce1169SAndreas Gohr } 123*76ce1169SAndreas Gohr 124*76ce1169SAndreas Gohr /** 125*76ce1169SAndreas Gohr * Get contact information. Returned in a raw array format from AD 126*76ce1169SAndreas Gohr * 127*76ce1169SAndreas Gohr * @param string $distinguisedname The full DN of a contact 128*76ce1169SAndreas Gohr * @param array $fields Attributes to be returned 129*76ce1169SAndreas Gohr * @return array 130*76ce1169SAndreas Gohr */ 131*76ce1169SAndreas Gohr public function info($distinguishedName, $fields = NULL) 132*76ce1169SAndreas Gohr { 133*76ce1169SAndreas Gohr if ($distinguishedName === NULL) { return false; } 134*76ce1169SAndreas Gohr if (!$this->adldap->getLdapBind()) { return false; } 135*76ce1169SAndreas Gohr 136*76ce1169SAndreas Gohr $filter = "distinguishedName=" . $distinguishedName; 137*76ce1169SAndreas Gohr if ($fields === NULL) { 138*76ce1169SAndreas Gohr $fields = array("distinguishedname", "mail", "memberof", "department", "displayname", "telephonenumber", "primarygroupid", "objectsid"); 139*76ce1169SAndreas Gohr } 140*76ce1169SAndreas Gohr $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); 141*76ce1169SAndreas Gohr $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); 142*76ce1169SAndreas Gohr 143*76ce1169SAndreas Gohr if ($entries[0]['count'] >= 1) { 144*76ce1169SAndreas Gohr // AD does not return the primary group in the ldap query, we may need to fudge it 145*76ce1169SAndreas Gohr if ($this->adldap->getRealPrimaryGroup() && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["primarygroupid"][0])){ 146*76ce1169SAndreas Gohr //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]); 147*76ce1169SAndreas Gohr $entries[0]["memberof"][] = $this->adldap->group()->getPrimaryGroup($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]); 148*76ce1169SAndreas Gohr } else { 149*76ce1169SAndreas Gohr $entries[0]["memberof"][] = "CN=Domain Users,CN=Users," . $this->adldap->getBaseDn(); 150*76ce1169SAndreas Gohr } 151*76ce1169SAndreas Gohr } 152*76ce1169SAndreas Gohr 153*76ce1169SAndreas Gohr $entries[0]["memberof"]["count"]++; 154*76ce1169SAndreas Gohr return $entries; 155*76ce1169SAndreas Gohr } 156*76ce1169SAndreas Gohr 157*76ce1169SAndreas Gohr /** 158*76ce1169SAndreas Gohr * Find information about the contacts. Returned in a raw array format from AD 159*76ce1169SAndreas Gohr * 160*76ce1169SAndreas Gohr * @param string $distinguishedName The full DN of a contact 161*76ce1169SAndreas Gohr * @param array $fields Array of parameters to query 162*76ce1169SAndreas Gohr * @return mixed 163*76ce1169SAndreas Gohr */ 164*76ce1169SAndreas Gohr public function infoCollection($distinguishedName, $fields = NULL) 165*76ce1169SAndreas Gohr { 166*76ce1169SAndreas Gohr if ($distinguishedName === NULL) { return false; } 167*76ce1169SAndreas Gohr if (!$this->adldap->getLdapBind()) { return false; } 168*76ce1169SAndreas Gohr 169*76ce1169SAndreas Gohr $info = $this->info($distinguishedName, $fields); 170*76ce1169SAndreas Gohr 171*76ce1169SAndreas Gohr if ($info !== false) { 172*76ce1169SAndreas Gohr $collection = new adLDAPContactCollection($info, $this->adldap); 173*76ce1169SAndreas Gohr return $collection; 174*76ce1169SAndreas Gohr } 175*76ce1169SAndreas Gohr return false; 176*76ce1169SAndreas Gohr } 177*76ce1169SAndreas Gohr 178*76ce1169SAndreas Gohr /** 179*76ce1169SAndreas Gohr * Determine if a contact is a member of a group 180*76ce1169SAndreas Gohr * 181*76ce1169SAndreas Gohr * @param string $distinguisedName The full DN of a contact 182*76ce1169SAndreas Gohr * @param string $group The group name to query 183*76ce1169SAndreas Gohr * @param bool $recursive Recursively check groups 184*76ce1169SAndreas Gohr * @return bool 185*76ce1169SAndreas Gohr */ 186*76ce1169SAndreas Gohr public function inGroup($distinguisedName, $group, $recursive = NULL) 187*76ce1169SAndreas Gohr { 188*76ce1169SAndreas Gohr if ($distinguisedName === NULL) { return false; } 189*76ce1169SAndreas Gohr if ($group === NULL) { return false; } 190*76ce1169SAndreas Gohr if (!$this->adldap->getLdapBind()) { return false; } 191*76ce1169SAndreas Gohr if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it 192*76ce1169SAndreas Gohr 193*76ce1169SAndreas Gohr // Get a list of the groups 194*76ce1169SAndreas Gohr $groups = $this->groups($distinguisedName, array("memberof"), $recursive); 195*76ce1169SAndreas Gohr 196*76ce1169SAndreas Gohr // Return true if the specified group is in the group list 197*76ce1169SAndreas Gohr if (in_array($group, $groups)){ 198*76ce1169SAndreas Gohr return true; 199*76ce1169SAndreas Gohr } 200*76ce1169SAndreas Gohr 201*76ce1169SAndreas Gohr return false; 202*76ce1169SAndreas Gohr } 203*76ce1169SAndreas Gohr 204*76ce1169SAndreas Gohr /** 205*76ce1169SAndreas Gohr * Modify a contact 206*76ce1169SAndreas Gohr * 207*76ce1169SAndreas Gohr * @param string $distinguishedName The contact to query 208*76ce1169SAndreas Gohr * @param array $attributes The attributes to modify. Note if you set the enabled attribute you must not specify any other attributes 209*76ce1169SAndreas Gohr * @return bool 210*76ce1169SAndreas Gohr */ 211*76ce1169SAndreas Gohr public function modify($distinguishedName, $attributes) { 212*76ce1169SAndreas Gohr if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedname]"; } 213*76ce1169SAndreas Gohr 214*76ce1169SAndreas Gohr // Translate the update to the LDAP schema 215*76ce1169SAndreas Gohr $mod = $this->adldap->adldap_schema($attributes); 216*76ce1169SAndreas Gohr 217*76ce1169SAndreas Gohr // Check to see if this is an enabled status update 218*76ce1169SAndreas Gohr if (!$mod) { 219*76ce1169SAndreas Gohr return false; 220*76ce1169SAndreas Gohr } 221*76ce1169SAndreas Gohr 222*76ce1169SAndreas Gohr // Do the update 223*76ce1169SAndreas Gohr $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod); 224*76ce1169SAndreas Gohr if ($result == false) { 225*76ce1169SAndreas Gohr return false; 226*76ce1169SAndreas Gohr } 227*76ce1169SAndreas Gohr 228*76ce1169SAndreas Gohr return true; 229*76ce1169SAndreas Gohr } 230*76ce1169SAndreas Gohr 231*76ce1169SAndreas Gohr /** 232*76ce1169SAndreas Gohr * Delete a contact 233*76ce1169SAndreas Gohr * 234*76ce1169SAndreas Gohr * @param string $distinguishedName The contact dn to delete (please be careful here!) 235*76ce1169SAndreas Gohr * @return array 236*76ce1169SAndreas Gohr */ 237*76ce1169SAndreas Gohr public function delete($distinguishedName) 238*76ce1169SAndreas Gohr { 239*76ce1169SAndreas Gohr $result = $this->folder()->delete($distinguishedName); 240*76ce1169SAndreas Gohr if ($result != true) { 241*76ce1169SAndreas Gohr return false; 242*76ce1169SAndreas Gohr } 243*76ce1169SAndreas Gohr return true; 244*76ce1169SAndreas Gohr } 245*76ce1169SAndreas Gohr 246*76ce1169SAndreas Gohr /** 247*76ce1169SAndreas Gohr * Return a list of all contacts 248*76ce1169SAndreas Gohr * 249*76ce1169SAndreas Gohr * @param bool $includeDescription Include a description of a contact 250*76ce1169SAndreas Gohr * @param string $search The search parameters 251*76ce1169SAndreas Gohr * @param bool $sorted Whether to sort the results 252*76ce1169SAndreas Gohr * @return array 253*76ce1169SAndreas Gohr */ 254*76ce1169SAndreas Gohr public function all($includeDescription = false, $search = "*", $sorted = true) { 255*76ce1169SAndreas Gohr if (!$this->adldap->getLdapBind()) { return false; } 256*76ce1169SAndreas Gohr 257*76ce1169SAndreas Gohr // Perform the search and grab all their details 258*76ce1169SAndreas Gohr $filter = "(&(objectClass=contact)(cn=" . $search . "))"; 259*76ce1169SAndreas Gohr $fields = array("displayname","distinguishedname"); 260*76ce1169SAndreas Gohr $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); 261*76ce1169SAndreas Gohr $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); 262*76ce1169SAndreas Gohr 263*76ce1169SAndreas Gohr $usersArray = array(); 264*76ce1169SAndreas Gohr for ($i=0; $i<$entries["count"]; $i++){ 265*76ce1169SAndreas Gohr if ($includeDescription && strlen($entries[$i]["displayname"][0])>0){ 266*76ce1169SAndreas Gohr $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["displayname"][0]; 267*76ce1169SAndreas Gohr } elseif ($includeDescription){ 268*76ce1169SAndreas Gohr $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["distinguishedname"][0]; 269*76ce1169SAndreas Gohr } else { 270*76ce1169SAndreas Gohr array_push($usersArray, $entries[$i]["distinguishedname"][0]); 271*76ce1169SAndreas Gohr } 272*76ce1169SAndreas Gohr } 273*76ce1169SAndreas Gohr if ($sorted) { 274*76ce1169SAndreas Gohr asort($usersArray); 275*76ce1169SAndreas Gohr } 276*76ce1169SAndreas Gohr return $usersArray; 277*76ce1169SAndreas Gohr } 278*76ce1169SAndreas Gohr 279*76ce1169SAndreas Gohr /** 280*76ce1169SAndreas Gohr * Mail enable a contact 281*76ce1169SAndreas Gohr * Allows email to be sent to them through Exchange 282*76ce1169SAndreas Gohr * 283*76ce1169SAndreas Gohr * @param string $distinguishedname The contact to mail enable 284*76ce1169SAndreas Gohr * @param string $emailaddress The email address to allow emails to be sent through 285*76ce1169SAndreas Gohr * @param string $mailnickname The mailnickname for the contact in Exchange. If NULL this will be set to the display name 286*76ce1169SAndreas Gohr * @return bool 287*76ce1169SAndreas Gohr */ 288*76ce1169SAndreas Gohr public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL){ 289*76ce1169SAndreas Gohr return $this->adldap->exchange()->contactMailEnable($distinguishedName, $emailAddress, $mailNickname); 290*76ce1169SAndreas Gohr } 291*76ce1169SAndreas Gohr 292*76ce1169SAndreas Gohr 293*76ce1169SAndreas Gohr} 294*76ce1169SAndreas Gohr?> 295