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 Exchange 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 */ 37require_once(dirname(__FILE__) . '/../adLDAP.php'); 38 39/** 40* MICROSOFT EXCHANGE FUNCTIONS 41*/ 42class adLDAPExchange { 43 /** 44 * The current adLDAP connection via dependency injection 45 * 46 * @var adLDAP 47 */ 48 protected $adldap; 49 50 public function __construct(adLDAP $adldap) { 51 $this->adldap = $adldap; 52 } 53 54 /** 55 * Create an Exchange account 56 * 57 * @param string $username The username of the user to add the Exchange account to 58 * @param array $storageGroup The mailbox, Exchange Storage Group, for the user account, this must be a full CN 59 * If the storage group has a different base_dn to the adLDAP configuration, set it using $base_dn 60 * @param string $emailAddress The primary email address to add to this user 61 * @param string $mailNickname The mail nick name. If mail nickname is blank, the username will be used 62 * @param bool $mdbUseDefaults Indicates whether the store should use the default quota, rather than the per-mailbox quota. 63 * @param string $baseDn Specify an alternative base_dn for the Exchange storage group 64 * @param bool $isGUID Is the username passed a GUID or a samAccountName 65 * @return bool 66 */ 67 public function createMailbox($username, $storageGroup, $emailAddress, $mailNickname=NULL, $useDefaults=TRUE, $baseDn=NULL, $isGUID=false) 68 { 69 if ($username === NULL){ return "Missing compulsory field [username]"; } 70 if ($storageGroup === NULL) { return "Missing compulsory array [storagegroup]"; } 71 if (!is_array($storageGroup)) { return "[storagegroup] must be an array"; } 72 if ($emailAddress === NULL) { return "Missing compulsory field [emailAddress]"; } 73 74 if ($baseDn === NULL) { 75 $baseDn = $this->adldap->getBaseDn(); 76 } 77 78 $container = "CN=" . implode(",CN=", $storageGroup); 79 80 if ($mailNickname === NULL) { 81 $mailNickname = $username; 82 } 83 $mdbUseDefaults = $this->adldap->utilities()->boolToString($useDefaults); 84 85 $attributes = array( 86 'exchange_homemdb'=>$container.",".$baseDn, 87 'exchange_proxyaddress'=>'SMTP:' . $emailAddress, 88 'exchange_mailnickname'=>$mailNickname, 89 'exchange_usedefaults'=>$mdbUseDefaults 90 ); 91 $result = $this->adldap->user()->modify($username, $attributes, $isGUID); 92 if ($result == false) { 93 return false; 94 } 95 return true; 96 } 97 98 /** 99 * Add an X400 address to Exchange 100 * See http://tools.ietf.org/html/rfc1685 for more information. 101 * An X400 Address looks similar to this X400:c=US;a= ;p=Domain;o=Organization;s=Doe;g=John; 102 * 103 * @param string $username The username of the user to add the X400 to to 104 * @param string $country Country 105 * @param string $admd Administration Management Domain 106 * @param string $pdmd Private Management Domain (often your AD domain) 107 * @param string $org Organization 108 * @param string $surname Surname 109 * @param string $givenName Given name 110 * @param bool $isGUID Is the username passed a GUID or a samAccountName 111 * @return bool 112 */ 113 public function addX400($username, $country, $admd, $pdmd, $org, $surname, $givenName, $isGUID=false) 114 { 115 if ($username === NULL){ return "Missing compulsory field [username]"; } 116 117 $proxyValue = 'X400:'; 118 119 // Find the dn of the user 120 $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID); 121 if ($user[0]["dn"] === NULL) { return false; } 122 $userDn = $user[0]["dn"]; 123 124 // We do not have to demote an email address from the default so we can just add the new proxy address 125 $attributes['exchange_proxyaddress'] = $proxyValue . 'c=' . $country . ';a=' . $admd . ';p=' . $pdmd . ';o=' . $org . ';s=' . $surname . ';g=' . $givenName . ';'; 126 127 // Translate the update to the LDAP schema 128 $add = $this->adldap->adldap_schema($attributes); 129 130 if (!$add) { return false; } 131 132 // Do the update 133 // Take out the @ to see any errors, usually this error might occur because the address already 134 // exists in the list of proxyAddresses 135 $result = @ldap_mod_add($this->adldap->getLdapConnection(), $userDn, $add); 136 if ($result == false) { 137 return false; 138 } 139 140 return true; 141 } 142 143 /** 144 * Add an address to Exchange 145 * 146 * @param string $username The username of the user to add the Exchange account to 147 * @param string $emailAddress The email address to add to this user 148 * @param bool $default Make this email address the default address, this is a bit more intensive as we have to demote any existing default addresses 149 * @param bool $isGUID Is the username passed a GUID or a samAccountName 150 * @return bool 151 */ 152 public function addAddress($username, $emailAddress, $default = FALSE, $isGUID = false) 153 { 154 if ($username === NULL) { return "Missing compulsory field [username]"; } 155 if ($emailAddress === NULL) { return "Missing compulsory fields [emailAddress]"; } 156 157 $proxyValue = 'smtp:'; 158 if ($default === true) { 159 $proxyValue = 'SMTP:'; 160 } 161 162 // Find the dn of the user 163 $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID); 164 if ($user[0]["dn"] === NULL){ return false; } 165 $userDn = $user[0]["dn"]; 166 167 // We need to scan existing proxy addresses and demote the default one 168 if (is_array($user[0]["proxyaddresses"]) && $default === true) { 169 $modAddresses = array(); 170 for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) { 171 if (strstr($user[0]['proxyaddresses'][$i], 'SMTP:') !== false) { 172 $user[0]['proxyaddresses'][$i] = str_replace('SMTP:', 'smtp:', $user[0]['proxyaddresses'][$i]); 173 } 174 if ($user[0]['proxyaddresses'][$i] != '') { 175 $modAddresses['proxyAddresses'][$i] = $user[0]['proxyaddresses'][$i]; 176 } 177 } 178 $modAddresses['proxyAddresses'][(sizeof($user[0]['proxyaddresses'])-1)] = 'SMTP:' . $emailAddress; 179 180 $result = @ldap_mod_replace($this->adldap->getLdapConnection(), $userDn, $modAddresses); 181 if ($result == false) { 182 return false; 183 } 184 185 return true; 186 } 187 else { 188 // We do not have to demote an email address from the default so we can just add the new proxy address 189 $attributes['exchange_proxyaddress'] = $proxyValue . $emailAddress; 190 191 // Translate the update to the LDAP schema 192 $add = $this->adldap->adldap_schema($attributes); 193 194 if (!$add) { 195 return false; 196 } 197 198 // Do the update 199 // Take out the @ to see any errors, usually this error might occur because the address already 200 // exists in the list of proxyAddresses 201 $result = @ldap_mod_add($this->adldap->getLdapConnection(), $userDn,$add); 202 if ($result == false) { 203 return false; 204 } 205 206 return true; 207 } 208 } 209 210 /** 211 * Remove an address to Exchange 212 * If you remove a default address the account will no longer have a default, 213 * we recommend changing the default address first 214 * 215 * @param string $username The username of the user to add the Exchange account to 216 * @param string $emailAddress The email address to add to this user 217 * @param bool $isGUID Is the username passed a GUID or a samAccountName 218 * @return bool 219 */ 220 public function deleteAddress($username, $emailAddress, $isGUID=false) 221 { 222 if ($username === NULL) { return "Missing compulsory field [username]"; } 223 if ($emailAddress === NULL) { return "Missing compulsory fields [emailAddress]"; } 224 225 // Find the dn of the user 226 $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID); 227 if ($user[0]["dn"] === NULL) { return false; } 228 $userDn = $user[0]["dn"]; 229 230 if (is_array($user[0]["proxyaddresses"])) { 231 $mod = array(); 232 for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) { 233 if (strstr($user[0]['proxyaddresses'][$i], 'SMTP:') !== false && $user[0]['proxyaddresses'][$i] == 'SMTP:' . $emailAddress) { 234 $mod['proxyAddresses'][0] = 'SMTP:' . $emailAddress; 235 } 236 elseif (strstr($user[0]['proxyaddresses'][$i], 'smtp:') !== false && $user[0]['proxyaddresses'][$i] == 'smtp:' . $emailAddress) { 237 $mod['proxyAddresses'][0] = 'smtp:' . $emailAddress; 238 } 239 } 240 241 $result = @ldap_mod_del($this->adldap->getLdapConnection(), $userDn,$mod); 242 if ($result == false) { 243 return false; 244 } 245 246 return true; 247 } 248 else { 249 return false; 250 } 251 } 252 /** 253 * Change the default address 254 * 255 * @param string $username The username of the user to add the Exchange account to 256 * @param string $emailAddress The email address to make default 257 * @param bool $isGUID Is the username passed a GUID or a samAccountName 258 * @return bool 259 */ 260 public function primaryAddress($username, $emailAddress, $isGUID = false) 261 { 262 if ($username === NULL) { return "Missing compulsory field [username]"; } 263 if ($emailAddress === NULL) { return "Missing compulsory fields [emailAddress]"; } 264 265 // Find the dn of the user 266 $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID); 267 if ($user[0]["dn"] === NULL){ return false; } 268 $userDn = $user[0]["dn"]; 269 270 if (is_array($user[0]["proxyaddresses"])) { 271 $modAddresses = array(); 272 for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) { 273 if (strstr($user[0]['proxyaddresses'][$i], 'SMTP:') !== false) { 274 $user[0]['proxyaddresses'][$i] = str_replace('SMTP:', 'smtp:', $user[0]['proxyaddresses'][$i]); 275 } 276 if ($user[0]['proxyaddresses'][$i] == 'smtp:' . $emailAddress) { 277 $user[0]['proxyaddresses'][$i] = str_replace('smtp:', 'SMTP:', $user[0]['proxyaddresses'][$i]); 278 } 279 if ($user[0]['proxyaddresses'][$i] != '') { 280 $modAddresses['proxyAddresses'][$i] = $user[0]['proxyaddresses'][$i]; 281 } 282 } 283 284 $result = @ldap_mod_replace($this->adldap->getLdapConnection(), $userDn, $modAddresses); 285 if ($result == false) { 286 return false; 287 } 288 289 return true; 290 } 291 292 } 293 294 /** 295 * Mail enable a contact 296 * Allows email to be sent to them through Exchange 297 * 298 * @param string $distinguishedName The contact to mail enable 299 * @param string $emailAddress The email address to allow emails to be sent through 300 * @param string $mailNickname The mailnickname for the contact in Exchange. If NULL this will be set to the display name 301 * @return bool 302 */ 303 public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL) 304 { 305 if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedName]"; } 306 if ($emailAddress === NULL) { return "Missing compulsory field [emailAddress]"; } 307 308 if ($mailNickname !== NULL) { 309 // Find the dn of the user 310 $user = $this->adldap->contact()->info($distinguishedName, array("cn","displayname")); 311 if ($user[0]["displayname"] === NULL) { return false; } 312 $mailNickname = $user[0]['displayname'][0]; 313 } 314 315 $attributes = array("email"=>$emailAddress,"contact_email"=>"SMTP:" . $emailAddress,"exchange_proxyaddress"=>"SMTP:" . $emailAddress,"exchange_mailnickname" => $mailNickname); 316 317 // Translate the update to the LDAP schema 318 $mod = $this->adldap->adldap_schema($attributes); 319 320 // Check to see if this is an enabled status update 321 if (!$mod) { return false; } 322 323 // Do the update 324 $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod); 325 if ($result == false) { return false; } 326 327 return true; 328 } 329 330 /** 331 * Returns a list of Exchange Servers in the ConfigurationNamingContext of the domain 332 * 333 * @param array $attributes An array of the AD attributes you wish to return 334 * @return array 335 */ 336 public function servers($attributes = array('cn','distinguishedname','serialnumber')) 337 { 338 if (!$this->adldap->getLdapBind()){ return false; } 339 340 $configurationNamingContext = $this->adldap->getRootDse(array('configurationnamingcontext')); 341 $sr = @ldap_search($this->adldap->getLdapConnection(), $configurationNamingContext[0]['configurationnamingcontext'][0],'(&(objectCategory=msExchExchangeServer))', $attributes); 342 $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr); 343 return $entries; 344 } 345 346 /** 347 * Returns a list of Storage Groups in Exchange for a given mail server 348 * 349 * @param string $exchangeServer The full DN of an Exchange server. You can use exchange_servers() to find the DN for your server 350 * @param array $attributes An array of the AD attributes you wish to return 351 * @param bool $recursive If enabled this will automatically query the databases within a storage group 352 * @return array 353 */ 354 public function storageGroups($exchangeServer, $attributes = array('cn','distinguishedname'), $recursive = NULL) 355 { 356 if (!$this->adldap->getLdapBind()){ return false; } 357 if ($exchangeServer === NULL) { return "Missing compulsory field [exchangeServer]"; } 358 if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } 359 360 $filter = '(&(objectCategory=msExchStorageGroup))'; 361 $sr = @ldap_search($this->adldap->getLdapConnection(), $exchangeServer, $filter, $attributes); 362 $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr); 363 364 if ($recursive === true) { 365 for ($i=0; $i<$entries['count']; $i++) { 366 $entries[$i]['msexchprivatemdb'] = $this->storageDatabases($entries[$i]['distinguishedname'][0]); 367 } 368 } 369 370 return $entries; 371 } 372 373 /** 374 * Returns a list of Databases within any given storage group in Exchange for a given mail server 375 * 376 * @param string $storageGroup The full DN of an Storage Group. You can use exchange_storage_groups() to find the DN 377 * @param array $attributes An array of the AD attributes you wish to return 378 * @return array 379 */ 380 public function storageDatabases($storageGroup, $attributes = array('cn','distinguishedname','displayname')) { 381 if (!$this->adldap->getLdapBind()){ return false; } 382 if ($storageGroup === NULL) { return "Missing compulsory field [storageGroup]"; } 383 384 $filter = '(&(objectCategory=msExchPrivateMDB))'; 385 $sr = @ldap_search($this->adldap->getLdapConnection(), $storageGroup, $filter, $attributes); 386 $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr); 387 return $entries; 388 } 389} 390?>