1<?php 2/** 3 * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY 4 * Version 4.0.4 5 * 6 * PHP Version 5 with SSL and LDAP support 7 * 8 * Written by Scott Barnett, Richard Hyland 9 * email: scott@wiggumworld.com, adldap@richardhyland.com 10 * http://adldap.sourceforge.net/ 11 * 12 * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland 13 * 14 * We'd appreciate any improvements or additions to be submitted back 15 * to benefit the entire community :) 16 * 17 * This library is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU Lesser General Public 19 * License as published by the Free Software Foundation; either 20 * version 2.1 of the License. 21 * 22 * This library is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25 * Lesser General Public License for more details. 26 * 27 * @category ToolsAndUtilities 28 * @package adLDAP 29 * @subpackage Contacts 30 * @author Scott Barnett, Richard Hyland 31 * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland 32 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1 33 * @revision $Revision: 97 $ 34 * @version 4.0.4 35 * @link http://adldap.sourceforge.net/ 36 */ 37 38require_once(dirname(__FILE__) . '/../adLDAP.php'); 39require_once(dirname(__FILE__) . '/../collections/adLDAPContactCollection.php'); 40 41use dokuwiki\Utf8\Sort; 42 43class adLDAPContacts { 44 /** 45 * The current adLDAP connection via dependency injection 46 * 47 * @var adLDAP 48 */ 49 protected $adldap; 50 51 public function __construct(adLDAP $adldap) { 52 $this->adldap = $adldap; 53 } 54 55 //***************************************************************************************************************** 56 // CONTACT FUNCTIONS 57 // * Still work to do in this area, and new functions to write 58 59 /** 60 * Create a contact 61 * 62 * @param array $attributes The attributes to set to the contact 63 * @return bool 64 */ 65 public function create($attributes) 66 { 67 // Check for compulsory fields 68 if (!array_key_exists("display_name", $attributes)) { return "Missing compulsory field [display_name]"; } 69 if (!array_key_exists("email", $attributes)) { return "Missing compulsory field [email]"; } 70 if (!array_key_exists("container", $attributes)) { return "Missing compulsory field [container]"; } 71 if (!is_array($attributes["container"])) { return "Container attribute must be an array."; } 72 73 // Translate the schema 74 $add = $this->adldap->adldap_schema($attributes); 75 76 // Additional stuff only used for adding contacts 77 $add["cn"][0] = $attributes["display_name"]; 78 $add["objectclass"][0] = "top"; 79 $add["objectclass"][1] = "person"; 80 $add["objectclass"][2] = "organizationalPerson"; 81 $add["objectclass"][3] = "contact"; 82 if (!isset($attributes['exchange_hidefromlists'])) { 83 $add["msExchHideFromAddressLists"][0] = "TRUE"; 84 } 85 86 // Determine the container 87 $attributes["container"] = array_reverse($attributes["container"]); 88 $container= "OU=" . implode(",OU=", $attributes["container"]); 89 90 // Add the entry 91 $result = @ldap_add($this->adldap->getLdapConnection(), "CN=" . $this->adldap->utilities()->escapeCharacters($add["cn"][0]) . ", " . $container . "," . $this->adldap->getBaseDn(), $add); 92 if ($result != true) { 93 return false; 94 } 95 96 return true; 97 } 98 99 /** 100 * Determine the list of groups a contact is a member of 101 * 102 * @param string $distinguisedname The full DN of a contact 103 * @param bool $recursive Recursively check groups 104 * @return array 105 */ 106 public function groups($distinguishedName, $recursive = NULL) 107 { 108 if ($distinguishedName === NULL) { return false; } 109 if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it 110 if (!$this->adldap->getLdapBind()){ return false; } 111 112 // Search the directory for their information 113 $info = @$this->info($distinguishedName, array("memberof", "primarygroupid")); 114 $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); //presuming the entry returned is our contact 115 116 if ($recursive === true){ 117 foreach ($groups as $id => $groupName){ 118 $extraGroups = $this->adldap->group()->recursiveGroups($groupName); 119 $groups = array_merge($groups, $extraGroups); 120 } 121 } 122 123 return $groups; 124 } 125 126 /** 127 * Get contact information. Returned in a raw array format from AD 128 * 129 * @param string $distinguisedname The full DN of a contact 130 * @param array $fields Attributes to be returned 131 * @return array 132 */ 133 public function info($distinguishedName, $fields = NULL) 134 { 135 if ($distinguishedName === NULL) { return false; } 136 if (!$this->adldap->getLdapBind()) { return false; } 137 138 $filter = "distinguishedName=" . $distinguishedName; 139 if ($fields === NULL) { 140 $fields = array("distinguishedname", "mail", "memberof", "department", "displayname", "telephonenumber", "primarygroupid", "objectsid"); 141 } 142 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); 143 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); 144 145 if ($entries[0]['count'] >= 1) { 146 // AD does not return the primary group in the ldap query, we may need to fudge it 147 if ($this->adldap->getRealPrimaryGroup() && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["primarygroupid"][0])){ 148 //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]); 149 $entries[0]["memberof"][] = $this->adldap->group()->getPrimaryGroup($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]); 150 } else { 151 $entries[0]["memberof"][] = "CN=Domain Users,CN=Users," . $this->adldap->getBaseDn(); 152 } 153 } 154 155 $entries[0]["memberof"]["count"]++; 156 return $entries; 157 } 158 159 /** 160 * Find information about the contacts. Returned in a raw array format from AD 161 * 162 * @param string $distinguishedName The full DN of a contact 163 * @param array $fields Array of parameters to query 164 * @return mixed 165 */ 166 public function infoCollection($distinguishedName, $fields = NULL) 167 { 168 if ($distinguishedName === NULL) { return false; } 169 if (!$this->adldap->getLdapBind()) { return false; } 170 171 $info = $this->info($distinguishedName, $fields); 172 173 if ($info !== false) { 174 $collection = new adLDAPContactCollection($info, $this->adldap); 175 return $collection; 176 } 177 return false; 178 } 179 180 /** 181 * Determine if a contact is a member of a group 182 * 183 * @param string $distinguisedName The full DN of a contact 184 * @param string $group The group name to query 185 * @param bool $recursive Recursively check groups 186 * @return bool 187 */ 188 public function inGroup($distinguisedName, $group, $recursive = NULL) 189 { 190 if ($distinguisedName === NULL) { return false; } 191 if ($group === NULL) { return false; } 192 if (!$this->adldap->getLdapBind()) { return false; } 193 if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it 194 195 // Get a list of the groups 196 $groups = $this->groups($distinguisedName, array("memberof"), $recursive); 197 198 // Return true if the specified group is in the group list 199 if (in_array($group, $groups)){ 200 return true; 201 } 202 203 return false; 204 } 205 206 /** 207 * Modify a contact 208 * 209 * @param string $distinguishedName The contact to query 210 * @param array $attributes The attributes to modify. Note if you set the enabled attribute you must not specify any other attributes 211 * @return bool 212 */ 213 public function modify($distinguishedName, $attributes) { 214 if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedname]"; } 215 216 // Translate the update to the LDAP schema 217 $mod = $this->adldap->adldap_schema($attributes); 218 219 // Check to see if this is an enabled status update 220 if (!$mod) { 221 return false; 222 } 223 224 // Do the update 225 $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod); 226 if ($result == false) { 227 return false; 228 } 229 230 return true; 231 } 232 233 /** 234 * Delete a contact 235 * 236 * @param string $distinguishedName The contact dn to delete (please be careful here!) 237 * @return array 238 */ 239 public function delete($distinguishedName) 240 { 241 $result = $this->folder()->delete($distinguishedName); 242 if ($result != true) { 243 return false; 244 } 245 return true; 246 } 247 248 /** 249 * Return a list of all contacts 250 * 251 * @param bool $includeDescription Include a description of a contact 252 * @param string $search The search parameters 253 * @param bool $sorted Whether to sort the results 254 * @return array 255 */ 256 public function all($includeDescription = false, $search = "*", $sorted = true) { 257 if (!$this->adldap->getLdapBind()) { return false; } 258 259 // Perform the search and grab all their details 260 $filter = "(&(objectClass=contact)(cn=" . $search . "))"; 261 $fields = array("displayname","distinguishedname"); 262 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); 263 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); 264 265 $usersArray = array(); 266 for ($i=0; $i<$entries["count"]; $i++){ 267 if ($includeDescription && strlen($entries[$i]["displayname"][0])>0){ 268 $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["displayname"][0]; 269 } elseif ($includeDescription){ 270 $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["distinguishedname"][0]; 271 } else { 272 array_push($usersArray, $entries[$i]["distinguishedname"][0]); 273 } 274 } 275 if ($sorted) { 276 Sort::asort($usersArray); 277 } 278 return $usersArray; 279 } 280 281 /** 282 * Mail enable a contact 283 * Allows email to be sent to them through Exchange 284 * 285 * @param string $distinguishedname The contact to mail enable 286 * @param string $emailaddress The email address to allow emails to be sent through 287 * @param string $mailnickname The mailnickname for the contact in Exchange. If NULL this will be set to the display name 288 * @return bool 289 */ 290 public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL){ 291 return $this->adldap->exchange()->contactMailEnable($distinguishedName, $emailAddress, $mailNickname); 292 } 293 294 295} 296?> 297