adldap->getLdapConnection(), $userDn, $modAddresses);
if ($result == false) {
return false;
}
return true;
}
}
/**
* Mail enable a contact
* Allows email to be sent to them through Exchange
*
* @param string $distinguishedName The contact to mail enable
* @param string $emailAddress The email address to allow emails to be sent through
* @param string $mailNickname The mailnickname for the contact in Exchange. If NULL this will be set to the display name
* @return bool
*/
public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL)
{
if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedName]"; }
if ($emailAddress === NULL) { return "Missing compulsory field [emailAddress]"; }
if ($mailNickname !== NULL) {
// Find the dn of the user
$user = $this->adldap->contact()->info($distinguishedName, array("cn","displayname"));
if ($user[0]["displayname"] === NULL) { return false; }
$mailNickname = $user[0]['displayname'][0];
}
$attributes = array("email"=>$emailAddress,"contact_email"=>"SMTP:" . $emailAddress,"exchange_proxyaddress"=>"SMTP:" . $emailAddress,"exchange_mailnickname" => $mailNickname);
// Translate the update to the LDAP schema
$mod = $this->adldap->adldap_schema($attributes);
// Check to see if this is an enabled status update
if (!$mod) { return false; }
// Do the update
$result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
if ($result == false) { return false; }
return true;
}
/**
* Returns a list of Exchange Servers in the ConfigurationNamingContext of the domain
*
* @param array $attributes An array of the AD attributes you wish to return
* @return array
*/
public function servers($attributes = array('cn','distinguishedname','serialnumber'))
{
if (!$this->adldap->getLdapBind()){ return false; }
$configurationNamingContext = $this->adldap->getRootDse(array('configurationnamingcontext'));
$sr = @ldap_search($this->adldap->getLdapConnection(), $configurationNamingContext[0]['configurationnamingcontext'][0],'(&(objectCategory=msExchExchangeServer))', $attributes);
$entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
return $entries;
}
/**
* Returns a list of Storage Groups in Exchange for a given mail server
*
* @param string $exchangeServer The full DN of an Exchange server. You can use exchange_servers() to find the DN for your server
* @param array $attributes An array of the AD attributes you wish to return
* @param bool $recursive If enabled this will automatically query the databases within a storage group
* @return array
*/
public function storageGroups($exchangeServer, $attributes = array('cn','distinguishedname'), $recursive = NULL)
{
if (!$this->adldap->getLdapBind()){ return false; }
if ($exchangeServer === NULL) { return "Missing compulsory field [exchangeServer]"; }
if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); }
$filter = '(&(objectCategory=msExchStorageGroup))';
$sr = @ldap_search($this->adldap->getLdapConnection(), $exchangeServer, $filter, $attributes);
$entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
if ($recursive === true) {
for ($i=0; $i<$entries['count']; $i++) {
$entries[$i]['msexchprivatemdb'] = $this->storageDatabases($entries[$i]['distinguishedname'][0]);
}
}
return $entries;
}
/**
* Returns a list of Databases within any given storage group in Exchange for a given mail server
*
* @param string $storageGroup The full DN of an Storage Group. You can use exchange_storage_groups() to find the DN
* @param array $attributes An array of the AD attributes you wish to return
* @return array
*/
public function storageDatabases($storageGroup, $attributes = array('cn','distinguishedname','displayname')) {
if (!$this->adldap->getLdapBind()){ return false; }
if ($storageGroup === NULL) { return "Missing compulsory field [storageGroup]"; }
$filter = '(&(objectCategory=msExchPrivateMDB))';
$sr = @ldap_search($this->adldap->getLdapConnection(), $storageGroup, $filter, $attributes);
$entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
return $entries;
}
}
?>PK ! D, D, classes/adLDAPContacts.phpnu [ adldap = $adldap;
}
//*****************************************************************************************************************
// CONTACT FUNCTIONS
// * Still work to do in this area, and new functions to write
/**
* Create a contact
*
* @param array $attributes The attributes to set to the contact
* @return bool
*/
public function create($attributes)
{
// Check for compulsory fields
if (!array_key_exists("display_name", $attributes)) { return "Missing compulsory field [display_name]"; }
if (!array_key_exists("email", $attributes)) { return "Missing compulsory field [email]"; }
if (!array_key_exists("container", $attributes)) { return "Missing compulsory field [container]"; }
if (!is_array($attributes["container"])) { return "Container attribute must be an array."; }
// Translate the schema
$add = $this->adldap->adldap_schema($attributes);
// Additional stuff only used for adding contacts
$add["cn"][0] = $attributes["display_name"];
$add["objectclass"][0] = "top";
$add["objectclass"][1] = "person";
$add["objectclass"][2] = "organizationalPerson";
$add["objectclass"][3] = "contact";
if (!isset($attributes['exchange_hidefromlists'])) {
$add["msExchHideFromAddressLists"][0] = "TRUE";
}
// Determine the container
$attributes["container"] = array_reverse($attributes["container"]);
$container= "OU=" . implode(",OU=", $attributes["container"]);
// Add the entry
$result = @ldap_add($this->adldap->getLdapConnection(), "CN=" . $this->adldap->utilities()->escapeCharacters($add["cn"][0]) . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
if ($result != true) {
return false;
}
return true;
}
/**
* Determine the list of groups a contact is a member of
*
* @param string $distinguisedname The full DN of a contact
* @param bool $recursive Recursively check groups
* @return array
*/
public function groups($distinguishedName, $recursive = NULL)
{
if ($distinguishedName === NULL) { return false; }
if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
if (!$this->adldap->getLdapBind()){ return false; }
// Search the directory for their information
$info = @$this->info($distinguishedName, array("memberof", "primarygroupid"));
$groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); //presuming the entry returned is our contact
if ($recursive === true){
foreach ($groups as $id => $groupName){
$extraGroups = $this->adldap->group()->recursiveGroups($groupName);
$groups = array_merge($groups, $extraGroups);
}
}
return $groups;
}
/**
* Get contact information. Returned in a raw array format from AD
*
* @param string $distinguisedname The full DN of a contact
* @param array $fields Attributes to be returned
* @return array
*/
public function info($distinguishedName, $fields = NULL)
{
if ($distinguishedName === NULL) { return false; }
if (!$this->adldap->getLdapBind()) { return false; }
$filter = "distinguishedName=" . $distinguishedName;
if ($fields === NULL) {
$fields = array("distinguishedname", "mail", "memberof", "department", "displayname", "telephonenumber", "primarygroupid", "objectsid");
}
$sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
$entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
if ($entries[0]['count'] >= 1) {
// AD does not return the primary group in the ldap query, we may need to fudge it
if ($this->adldap->getRealPrimaryGroup() && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["primarygroupid"][0])){
//$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]);
$entries[0]["memberof"][] = $this->adldap->group()->getPrimaryGroup($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]);
} else {
$entries[0]["memberof"][] = "CN=Domain Users,CN=Users," . $this->adldap->getBaseDn();
}
}
$entries[0]["memberof"]["count"]++;
return $entries;
}
/**
* Find information about the contacts. Returned in a raw array format from AD
*
* @param string $distinguishedName The full DN of a contact
* @param array $fields Array of parameters to query
* @return mixed
*/
public function infoCollection($distinguishedName, $fields = NULL)
{
if ($distinguishedName === NULL) { return false; }
if (!$this->adldap->getLdapBind()) { return false; }
$info = $this->info($distinguishedName, $fields);
if ($info !== false) {
$collection = new adLDAPContactCollection($info, $this->adldap);
return $collection;
}
return false;
}
/**
* Determine if a contact is a member of a group
*
* @param string $distinguisedName The full DN of a contact
* @param string $group The group name to query
* @param bool $recursive Recursively check groups
* @return bool
*/
public function inGroup($distinguisedName, $group, $recursive = NULL)
{
if ($distinguisedName === NULL) { return false; }
if ($group === NULL) { return false; }
if (!$this->adldap->getLdapBind()) { return false; }
if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
// Get a list of the groups
$groups = $this->groups($distinguisedName, array("memberof"), $recursive);
// Return true if the specified group is in the group list
if (in_array($group, $groups)){
return true;
}
return false;
}
/**
* Modify a contact
*
* @param string $distinguishedName The contact to query
* @param array $attributes The attributes to modify. Note if you set the enabled attribute you must not specify any other attributes
* @return bool
*/
public function modify($distinguishedName, $attributes) {
if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedname]"; }
// Translate the update to the LDAP schema
$mod = $this->adldap->adldap_schema($attributes);
// Check to see if this is an enabled status update
if (!$mod) {
return false;
}
// Do the update
$result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
if ($result == false) {
return false;
}
return true;
}
/**
* Delete a contact
*
* @param string $distinguishedName The contact dn to delete (please be careful here!)
* @return array
*/
public function delete($distinguishedName)
{
$result = $this->folder()->delete($distinguishedName);
if ($result != true) {
return false;
}
return true;
}
/**
* Return a list of all contacts
*
* @param bool $includeDescription Include a description of a contact
* @param string $search The search parameters
* @param bool $sorted Whether to sort the results
* @return array
*/
public function all($includeDescription = false, $search = "*", $sorted = true) {
if (!$this->adldap->getLdapBind()) { return false; }
// Perform the search and grab all their details
$filter = "(&(objectClass=contact)(cn=" . $search . "))";
$fields = array("displayname","distinguishedname");
$sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
$entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
$usersArray = array();
for ($i=0; $i<$entries["count"]; $i++){
if ($includeDescription && strlen($entries[$i]["displayname"][0])>0){
$usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["displayname"][0];
} elseif ($includeDescription){
$usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["distinguishedname"][0];
} else {
array_push($usersArray, $entries[$i]["distinguishedname"][0]);
}
}
if ($sorted) {
asort($usersArray);
}
return $usersArray;
}
/**
* Mail enable a contact
* Allows email to be sent to them through Exchange
*
* @param string $distinguishedname The contact to mail enable
* @param string $emailaddress The email address to allow emails to be sent through
* @param string $mailnickname The mailnickname for the contact in Exchange. If NULL this will be set to the display name
* @return bool
*/
public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL){
return $this->adldap->exchange()->contactMailEnable($distinguishedName, $emailAddress, $mailNickname);
}
}
?>
PK ! r classes/adLDAPFolders.phpnu [ adldap = $adldap;
}
/**
* Delete a distinguished name from Active Directory
* You should never need to call this yourself, just use the wrapper functions user_delete and contact_delete
*
* @param string $dn The distinguished name to delete
* @return bool
*/
public function delete($dn){
$result = ldap_delete($this->adldap->getLdapConnection(), $dn);
if ($result != true) {
return false;
}
return true;
}
/**
* Returns a folder listing for a specific OU
* See http://adldap.sourceforge.net/wiki/doku.php?id=api_folder_functions
*
* @param array $folderName An array to the OU you wish to list.
* If set to NULL will list the root, strongly recommended to set
* $recursive to false in that instance!
* @param string $dnType The type of record to list. This can be ADLDAP_FOLDER or ADLDAP_CONTAINER.
* @param bool $recursive Recursively search sub folders
* @param bool $type Specify a type of object to search for
* @return array
*/
public function listing($folderName = NULL, $dnType = adLDAP::ADLDAP_FOLDER, $recursive = NULL, $type = NULL)
{
if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
if (!$this->adldap->getLdapBind()) { return false; }
$filter = '(&';
if ($type !== NULL) {
switch ($type) {
case 'contact':
$filter .= '(objectClass=contact)';
break;
case 'computer':
$filter .= '(objectClass=computer)';
break;
case 'group':
$filter .= '(objectClass=group)';
break;
case 'folder':
$filter .= '(objectClass=organizationalUnit)';
break;
case 'container':
$filter .= '(objectClass=container)';
break;
case 'domain':
$filter .= '(objectClass=builtinDomain)';
break;
default:
$filter .= '(objectClass=user)';
break;
}
}
else {
$filter .= '(objectClass=*)';
}
// If the folder name is null then we will search the root level of AD
// This requires us to not have an OU= part, just the base_dn
$searchOu = $this->adldap->getBaseDn();
if (is_array($folderName)) {
$ou = $dnType . "=" . implode("," . $dnType . "=", $folderName);
$filter .= '(!(distinguishedname=' . $ou . ',' . $this->adldap->getBaseDn() . ')))';
$searchOu = $ou . ',' . $this->adldap->getBaseDn();
}
else {
$filter .= '(!(distinguishedname=' . $this->adldap->getBaseDn() . ')))';
}
if ($recursive === true) {
$sr = ldap_search($this->adldap->getLdapConnection(), $searchOu, $filter, array('objectclass', 'distinguishedname', 'samaccountname'));
$entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
if (is_array($entries)) {
return $entries;
}
}
else {
$sr = ldap_list($this->adldap->getLdapConnection(), $searchOu, $filter, array('objectclass', 'distinguishedname', 'samaccountname'));
$entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
if (is_array($entries)) {
return $entries;
}
}
return false;
}
/**
* Create an organizational unit
*
* @param array $attributes Default attributes of the ou
* @return bool
*/
public function create($attributes)
{
if (!is_array($attributes)){ return "Attributes must be an array"; }
if (!is_array($attributes["container"])) { return "Container attribute must be an array."; }
if (!array_key_exists("ou_name",$attributes)) { return "Missing compulsory field [ou_name]"; }
if (!array_key_exists("container",$attributes)) { return "Missing compulsory field [container]"; }
$attributes["container"] = array_reverse($attributes["container"]);
$add=array();
$add["objectClass"] = "organizationalUnit";
$add["OU"] = $attributes['ou_name'];
$containers = "";
if (count($attributes['container']) > 0) {
$containers = "OU=" . implode(",OU=", $attributes["container"]) . ",";
}
$containers = "OU=" . implode(",OU=", $attributes["container"]);
$result = ldap_add($this->adldap->getLdapConnection(), "OU=" . $add["OU"] . ", " . $containers . $this->adldap->getBaseDn(), $add);
if ($result != true) {
return false;
}
return true;
}
}
?>PK ! v v
adLDAP.phpnu [ ldapConnection) {
return $this->ldapConnection;
}
return false;
}
/**
* Get the bind status
*
* @return bool
*/
public function getLdapBind() {
return $this->ldapBind;
}
/**
* Get the current base DN
*
* @return string
*/
public function getBaseDn() {
return $this->baseDn;
}
/**
* The group class
*
* @var adLDAPGroups
*/
protected $groupClass;
/**
* Get the group class interface
*
* @return adLDAPGroups
*/
public function group() {
if (!$this->groupClass) {
$this->groupClass = new adLDAPGroups($this);
}
return $this->groupClass;
}
/**
* The user class
*
* @var adLDAPUsers
*/
protected $userClass;
/**
* Get the userclass interface
*
* @return adLDAPUsers
*/
public function user() {
if (!$this->userClass) {
$this->userClass = new adLDAPUsers($this);
}
return $this->userClass;
}
/**
* The folders class
*
* @var adLDAPFolders
*/
protected $folderClass;
/**
* Get the folder class interface
*
* @return adLDAPFolders
*/
public function folder() {
if (!$this->folderClass) {
$this->folderClass = new adLDAPFolders($this);
}
return $this->folderClass;
}
/**
* The utils class
*
* @var adLDAPUtils
*/
protected $utilClass;
/**
* Get the utils class interface
*
* @return adLDAPUtils
*/
public function utilities() {
if (!$this->utilClass) {
$this->utilClass = new adLDAPUtils($this);
}
return $this->utilClass;
}
/**
* The contacts class
*
* @var adLDAPContacts
*/
protected $contactClass;
/**
* Get the contacts class interface
*
* @return adLDAPContacts
*/
public function contact() {
if (!$this->contactClass) {
$this->contactClass = new adLDAPContacts($this);
}
return $this->contactClass;
}
/**
* The exchange class
*
* @var adLDAPExchange
*/
protected $exchangeClass;
/**
* Get the exchange class interface
*
* @return adLDAPExchange
*/
public function exchange() {
if (!$this->exchangeClass) {
$this->exchangeClass = new adLDAPExchange($this);
}
return $this->exchangeClass;
}
/**
* The computers class
*
* @var adLDAPComputers
*/
protected $computersClass;
/**
* Get the computers class interface
*
* @return adLDAPComputers
*/
public function computer() {
if (!$this->computerClass) {
$this->computerClass = new adLDAPComputers($this);
}
return $this->computerClass;
}
/**
* Getters and Setters
*/
/**
* Set the account suffix
*
* @param string $accountSuffix
* @return void
*/
public function setAccountSuffix($accountSuffix)
{
$this->accountSuffix = $accountSuffix;
}
/**
* Get the account suffix
*
* @return string
*/
public function getAccountSuffix()
{
return $this->accountSuffix;
}
/**
* Set the domain controllers array
*
* @param array $domainControllers
* @return void
*/
public function setDomainControllers(array $domainControllers)
{
$this->domainControllers = $domainControllers;
}
/**
* Get the list of domain controllers
*
* @return void
*/
public function getDomainControllers()
{
return $this->domainControllers;
}
/**
* Sets the port number your domain controller communicates over
*
* @param int $adPort
*/
public function setPort($adPort)
{
$this->adPort = $adPort;
}
/**
* Gets the port number your domain controller communicates over
*
* @return int
*/
public function getPort()
{
return $this->adPort;
}
/**
* Set the username of an account with higher priviledges
*
* @param string $adminUsername
* @return void
*/
public function setAdminUsername($adminUsername)
{
$this->adminUsername = $adminUsername;
}
/**
* Get the username of the account with higher priviledges
*
* This will throw an exception for security reasons
*/
public function getAdminUsername()
{
throw new adLDAPException('For security reasons you cannot access the domain administrator account details');
}
/**
* Set the password of an account with higher priviledges
*
* @param string $adminPassword
* @return void
*/
public function setAdminPassword($adminPassword)
{
$this->adminPassword = $adminPassword;
}
/**
* Get the password of the account with higher priviledges
*
* This will throw an exception for security reasons
*/
public function getAdminPassword()
{
throw new adLDAPException('For security reasons you cannot access the domain administrator account details');
}
/**
* Set whether to detect the true primary group
*
* @param bool $realPrimaryGroup
* @return void
*/
public function setRealPrimaryGroup($realPrimaryGroup)
{
$this->realPrimaryGroup = $realPrimaryGroup;
}
/**
* Get the real primary group setting
*
* @return bool
*/
public function getRealPrimaryGroup()
{
return $this->realPrimaryGroup;
}
/**
* Set whether to use SSL
*
* @param bool $useSSL
* @return void
*/
public function setUseSSL($useSSL)
{
$this->useSSL = $useSSL;
// Set the default port correctly
if($this->useSSL) {
$this->setPort(self::ADLDAP_LDAPS_PORT);
}
else {
$this->setPort(self::ADLDAP_LDAP_PORT);
}
}
/**
* Get the SSL setting
*
* @return bool
*/
public function getUseSSL()
{
return $this->useSSL;
}
/**
* Set whether to use TLS
*
* @param bool $useTLS
* @return void
*/
public function setUseTLS($useTLS)
{
$this->useTLS = $useTLS;
}
/**
* Get the TLS setting
*
* @return bool
*/
public function getUseTLS()
{
return $this->useTLS;
}
/**
* Set whether to use SSO
* Requires ldap_sasl_bind support. Be sure --with-ldap-sasl is used when configuring PHP otherwise this function will be undefined.
*
* @param bool $useSSO
* @return void
*/
public function setUseSSO($useSSO)
{
if ($useSSO === true && !$this->ldapSaslSupported()) {
throw new adLDAPException('No LDAP SASL support for PHP. See: http://php.net/ldap_sasl_bind');
}
$this->useSSO = $useSSO;
}
/**
* Get the SSO setting
*
* @return bool
*/
public function getUseSSO()
{
return $this->useSSO;
}
/**
* Set whether to lookup recursive groups
*
* @param bool $recursiveGroups
* @return void
*/
public function setRecursiveGroups($recursiveGroups)
{
$this->recursiveGroups = $recursiveGroups;
}
/**
* Get the recursive groups setting
*
* @return bool
*/
public function getRecursiveGroups()
{
return $this->recursiveGroups;
}
/**
* Default Constructor
*
* Tries to bind to the AD domain over LDAP or LDAPs
*
* @param array $options Array of options to pass to the constructor
* @throws Exception - if unable to bind to Domain Controller
* @return bool
*/
function __construct($options = array()) {
// You can specifically overide any of the default configuration options setup above
if (count($options) > 0) {
if (array_key_exists("account_suffix",$options)){ $this->accountSuffix = $options["account_suffix"]; }
if (array_key_exists("base_dn",$options)){ $this->baseDn = $options["base_dn"]; }
if (array_key_exists("domain_controllers",$options)){
if (!is_array($options["domain_controllers"])) {
throw new adLDAPException('[domain_controllers] option must be an array');
}
$this->domainControllers = $options["domain_controllers"];
}
if (array_key_exists("admin_username",$options)){ $this->adminUsername = $options["admin_username"]; }
if (array_key_exists("admin_password",$options)){ $this->adminPassword = $options["admin_password"]; }
if (array_key_exists("real_primarygroup",$options)){ $this->realPrimaryGroup = $options["real_primarygroup"]; }
if (array_key_exists("use_ssl",$options)){ $this->setUseSSL($options["use_ssl"]); }
if (array_key_exists("use_tls",$options)){ $this->useTLS = $options["use_tls"]; }
if (array_key_exists("recursive_groups",$options)){ $this->recursiveGroups = $options["recursive_groups"]; }
if (array_key_exists("ad_port",$options)){ $this->setPort($options["ad_port"]); }
if (array_key_exists("sso",$options)) {
$this->setUseSSO($options["sso"]);
if (!$this->ldapSaslSupported()) {
$this->setUseSSO(false);
}
}
}
if ($this->ldapSupported() === false) {
throw new adLDAPException('No LDAP support for PHP. See: http://php.net/ldap');
}
return $this->connect();
}
/**
* Default Destructor
*
* Closes the LDAP connection
*
* @return void
*/
function __destruct() {
$this->close();
}
/**
* Connects and Binds to the Domain Controller
*
* @return bool
*/
public function connect()
{
// Connect to the AD/LDAP server as the username/password
$domainController = $this->randomController();
if ($this->useSSL) {
$this->ldapConnection = ldap_connect("ldaps://" . $domainController, $this->adPort);
} else {
$this->ldapConnection = ldap_connect($domainController, $this->adPort);
}
// Set some ldap options for talking to AD
ldap_set_option($this->ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($this->ldapConnection, LDAP_OPT_REFERRALS, 0);
if ($this->useTLS) {
ldap_start_tls($this->ldapConnection);
}
// Bind as a domain admin if they've set it up
if ($this->adminUsername !== NULL && $this->adminPassword !== NULL) {
$this->ldapBind = @ldap_bind($this->ldapConnection, $this->adminUsername . $this->accountSuffix, $this->adminPassword);
if (!$this->ldapBind) {
if ($this->useSSL && !$this->useTLS) {
// If you have problems troubleshooting, remove the @ character from the ldapldapBind command above to get the actual error message
throw new adLDAPException('Bind to Active Directory failed. Either the LDAPs connection failed or the login credentials are incorrect. AD said: ' . $this->getLastError());
}
else {
throw new adLDAPException('Bind to Active Directory failed. Check the login credentials and/or server details. AD said: ' . $this->getLastError());
}
}
}
if ($this->useSSO && $_SERVER['REMOTE_USER'] && $this->adminUsername === null && $_SERVER['KRB5CCNAME']) {
putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']);
$this->ldapBind = @ldap_sasl_bind($this->ldapConnection, NULL, NULL, "GSSAPI");
if (!$this->ldapBind){
throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError());
}
else {
return true;
}
}
if ($this->baseDn == NULL) {
$this->baseDn = $this->findBaseDn();
}
return true;
}
/**
* Closes the LDAP connection
*
* @return void
*/
public function close() {
if ($this->ldapConnection) {
@ldap_close($this->ldapConnection);
}
}
/**
* Validate a user's login credentials
*
* @param string $username A user's AD username
* @param string $password A user's AD password
* @param bool optional $preventRebind
* @return bool
*/
public function authenticate($username, $password, $preventRebind = false) {
// Prevent null binding
if ($username === NULL || $password === NULL) { return false; }
if (empty($username) || empty($password)) { return false; }
// Allow binding over SSO for Kerberos
if ($this->useSSO && $_SERVER['REMOTE_USER'] && $_SERVER['REMOTE_USER'] == $username && $this->adminUsername === NULL && $_SERVER['KRB5CCNAME']) {
putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']);
$this->ldapBind = @ldap_sasl_bind($this->ldapConnection, NULL, NULL, "GSSAPI");
if (!$this->ldapBind) {
throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError());
}
else {
return true;
}
}
// Bind as the user
$ret = true;
$this->ldapBind = @ldap_bind($this->ldapConnection, $username . $this->accountSuffix, $password);
if (!$this->ldapBind){
$ret = false;
}
// Cnce we've checked their details, kick back into admin mode if we have it
if ($this->adminUsername !== NULL && !$preventRebind) {
$this->ldapBind = @ldap_bind($this->ldapConnection, $this->adminUsername . $this->accountSuffix , $this->adminPassword);
if (!$this->ldapBind){
// This should never happen in theory
throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError());
}
}
return $ret;
}
/**
* Find the Base DN of your domain controller
*
* @return string
*/
public function findBaseDn()
{
$namingContext = $this->getRootDse(array('defaultnamingcontext'));
return $namingContext[0]['defaultnamingcontext'][0];
}
/**
* Get the RootDSE properties from a domain controller
*
* @param array $attributes The attributes you wish to query e.g. defaultnamingcontext
* @return array
*/
public function getRootDse($attributes = array("*", "+")) {
if (!$this->ldapBind){ return (false); }
$sr = @ldap_read($this->ldapConnection, NULL, 'objectClass=*', $attributes);
$entries = @ldap_get_entries($this->ldapConnection, $sr);
return $entries;
}
/**
* Get last error from Active Directory
*
* This function gets the last message from Active Directory
* This may indeed be a 'Success' message but if you get an unknown error
* it might be worth calling this function to see what errors were raised
*
* return string
*/
public function getLastError() {
return @ldap_error($this->ldapConnection);
}
/**
* Detect LDAP support in php
*
* @return bool
*/
protected function ldapSupported()
{
if (!function_exists('ldap_connect')) {
return false;
}
return true;
}
/**
* Detect ldap_sasl_bind support in PHP
*
* @return bool
*/
protected function ldapSaslSupported()
{
if (!function_exists('ldap_sasl_bind')) {
return false;
}
return true;
}
/**
* Schema
*
* @param array $attributes Attributes to be queried
* @return array
*/
public function adldap_schema($attributes){
// LDAP doesn't like NULL attributes, only set them if they have values
// If you wish to remove an attribute you should set it to a space
// TO DO: Adapt user_modify to use ldap_mod_delete to remove a NULL attribute
$mod=array();
// Check every attribute to see if it contains 8bit characters and then UTF8 encode them
array_walk($attributes, array($this, 'encode8bit'));
if ($attributes["address_city"]){ $mod["l"][0]=$attributes["address_city"]; }
if ($attributes["address_code"]){ $mod["postalCode"][0]=$attributes["address_code"]; }
//if ($attributes["address_country"]){ $mod["countryCode"][0]=$attributes["address_country"]; } // use country codes?
if ($attributes["address_country"]){ $mod["c"][0]=$attributes["address_country"]; }
if ($attributes["address_pobox"]){ $mod["postOfficeBox"][0]=$attributes["address_pobox"]; }
if ($attributes["address_state"]){ $mod["st"][0]=$attributes["address_state"]; }
if ($attributes["address_street"]){ $mod["streetAddress"][0]=$attributes["address_street"]; }
if ($attributes["company"]){ $mod["company"][0]=$attributes["company"]; }
if ($attributes["change_password"]){ $mod["pwdLastSet"][0]=0; }
if ($attributes["department"]){ $mod["department"][0]=$attributes["department"]; }
if ($attributes["description"]){ $mod["description"][0]=$attributes["description"]; }
if ($attributes["display_name"]){ $mod["displayName"][0]=$attributes["display_name"]; }
if ($attributes["email"]){ $mod["mail"][0]=$attributes["email"]; }
if ($attributes["expires"]){ $mod["accountExpires"][0]=$attributes["expires"]; } //unix epoch format?
if ($attributes["firstname"]){ $mod["givenName"][0]=$attributes["firstname"]; }
if ($attributes["home_directory"]){ $mod["homeDirectory"][0]=$attributes["home_directory"]; }
if ($attributes["home_drive"]){ $mod["homeDrive"][0]=$attributes["home_drive"]; }
if ($attributes["initials"]){ $mod["initials"][0]=$attributes["initials"]; }
if ($attributes["logon_name"]){ $mod["userPrincipalName"][0]=$attributes["logon_name"]; }
if ($attributes["manager"]){ $mod["manager"][0]=$attributes["manager"]; } //UNTESTED ***Use DistinguishedName***
if ($attributes["office"]){ $mod["physicalDeliveryOfficeName"][0]=$attributes["office"]; }
if ($attributes["password"]){ $mod["unicodePwd"][0]=$this->user()->encodePassword($attributes["password"]); }
if ($attributes["profile_path"]){ $mod["profilepath"][0]=$attributes["profile_path"]; }
if ($attributes["script_path"]){ $mod["scriptPath"][0]=$attributes["script_path"]; }
if ($attributes["surname"]){ $mod["sn"][0]=$attributes["surname"]; }
if ($attributes["title"]){ $mod["title"][0]=$attributes["title"]; }
if ($attributes["telephone"]){ $mod["telephoneNumber"][0]=$attributes["telephone"]; }
if ($attributes["mobile"]){ $mod["mobile"][0]=$attributes["mobile"]; }
if ($attributes["pager"]){ $mod["pager"][0]=$attributes["pager"]; }
if ($attributes["ipphone"]){ $mod["ipphone"][0]=$attributes["ipphone"]; }
if ($attributes["web_page"]){ $mod["wWWHomePage"][0]=$attributes["web_page"]; }
if ($attributes["fax"]){ $mod["facsimileTelephoneNumber"][0]=$attributes["fax"]; }
if ($attributes["enabled"]){ $mod["userAccountControl"][0]=$attributes["enabled"]; }
if ($attributes["homephone"]){ $mod["homephone"][0]=$attributes["homephone"]; }
// Distribution List specific schema
if ($attributes["group_sendpermission"]){ $mod["dlMemSubmitPerms"][0]=$attributes["group_sendpermission"]; }
if ($attributes["group_rejectpermission"]){ $mod["dlMemRejectPerms"][0]=$attributes["group_rejectpermission"]; }
// Exchange Schema
if ($attributes["exchange_homemdb"]){ $mod["homeMDB"][0]=$attributes["exchange_homemdb"]; }
if ($attributes["exchange_mailnickname"]){ $mod["mailNickname"][0]=$attributes["exchange_mailnickname"]; }
if ($attributes["exchange_proxyaddress"]){ $mod["proxyAddresses"][0]=$attributes["exchange_proxyaddress"]; }
if ($attributes["exchange_usedefaults"]){ $mod["mDBUseDefaults"][0]=$attributes["exchange_usedefaults"]; }
if ($attributes["exchange_policyexclude"]){ $mod["msExchPoliciesExcluded"][0]=$attributes["exchange_policyexclude"]; }
if ($attributes["exchange_policyinclude"]){ $mod["msExchPoliciesIncluded"][0]=$attributes["exchange_policyinclude"]; }
if ($attributes["exchange_addressbook"]){ $mod["showInAddressBook"][0]=$attributes["exchange_addressbook"]; }
if ($attributes["exchange_altrecipient"]){ $mod["altRecipient"][0]=$attributes["exchange_altrecipient"]; }
if ($attributes["exchange_deliverandredirect"]){ $mod["deliverAndRedirect"][0]=$attributes["exchange_deliverandredirect"]; }
// This schema is designed for contacts
if ($attributes["exchange_hidefromlists"]){ $mod["msExchHideFromAddressLists"][0]=$attributes["exchange_hidefromlists"]; }
if ($attributes["contact_email"]){ $mod["targetAddress"][0]=$attributes["contact_email"]; }
//echo (""); print_r($mod);
/*
// modifying a name is a bit fiddly
if ($attributes["firstname"] && $attributes["surname"]){
$mod["cn"][0]=$attributes["firstname"]." ".$attributes["surname"];
$mod["displayname"][0]=$attributes["firstname"]." ".$attributes["surname"];
$mod["name"][0]=$attributes["firstname"]." ".$attributes["surname"];
}
*/
if (count($mod)==0){ return (false); }
return ($mod);
}
/**
* Convert 8bit characters e.g. accented characters to UTF8 encoded characters
*/
protected function encode8Bit(&$item, $key) {
$encode = false;
if (is_string($item)) {
for ($i=0; $i> 7) {
$encode = true;
}
}
}
if ($encode === true && $key != 'password') {
$item = utf8_encode($item);
}
}
/**
* Select a random domain controller from your domain controller array
*
* @return string
*/
protected function randomController()
{
mt_srand(doubleval(microtime()) * 100000000); // For older PHP versions
/*if (sizeof($this->domainControllers) > 1) {
$adController = $this->domainControllers[array_rand($this->domainControllers)];
// Test if the controller is responding to pings
$ping = $this->pingController($adController);
if ($ping === false) {
// Find the current key in the domain controllers array
$key = array_search($adController, $this->domainControllers);
// Remove it so that we don't end up in a recursive loop
unset($this->domainControllers[$key]);
// Select a new controller
return $this->randomController();
}
else {
return ($adController);
}
} */
return $this->domainControllers[array_rand($this->domainControllers)];
}
/**
* Test basic connectivity to controller
*
* @return bool
*/
protected function pingController($host) {
$port = $this->adPort;
fsockopen($host, $port, $errno, $errstr, 10);
if ($errno > 0) {
return false;
}
return true;
}
}
/**
* adLDAP Exception Handler
*
* Exceptions of this type are thrown on bind failure or when SSL is required but not configured
* Example:
* try {
* $adldap = new adLDAP();
* }
* catch (adLDAPException $e) {
* echo $e;
* exit();
* }
*/
class adLDAPException extends Exception {}
PK ! Y{ { % collections/adLDAPGroupCollection.phpnu [
PK ! hV ' collections/adLDAPContactCollection.phpnu [
PK ! (y y $ collections/adLDAPUserCollection.phpnu [
PK ! J𮝁 ( collections/adLDAPComputerCollection.phpnu [
PK ! ZkJ/ / collections/adLDAPCollection.phpnu [ setInfo($info);
$this->adldap = $adldap;
}
/**
* Set the raw info array from Active Directory
*
* @param array $info
*/
public function setInfo(array $info)
{
if ($this->info && sizeof($info) >= 1) {
unset($this->info);
}
$this->info = $info;
}
/**
* Magic get method to retrieve data from the raw array in a formatted way
*
* @param string $attribute
* @return mixed
*/
public function __get($attribute)
{
if (isset($this->info[0]) && is_array($this->info[0])) {
foreach ($this->info[0] as $keyAttr => $valueAttr) {
if (strtolower($keyAttr) == strtolower($attribute)) {
if ($this->info[0][strtolower($attribute)]['count'] == 1) {
return $this->info[0][strtolower($attribute)][0];
}
else {
$array = array();
foreach ($this->info[0][strtolower($attribute)] as $key => $value) {
if ((string)$key != 'count') {
$array[$key] = $value;
}
}
return $array;
}
}
}
}
else {
return NULL;
}
}
/**
* Magic set method to update an attribute
*
* @param string $attribute
* @param string $value
* @return bool
*/
abstract public function __set($attribute, $value);
/**
* Magic isset method to check for the existence of an attribute
*
* @param string $attribute
* @return bool
*/
public function __isset($attribute) {
if (isset($this->info[0]) && is_array($this->info[0])) {
foreach ($this->info[0] as $keyAttr => $valueAttr) {
if (strtolower($keyAttr) == strtolower($attribute)) {
return true;
}
}
}
return false;
}
}
?>
PK ! kN classes/adLDAPComputers.phpnu [ PK ! D classes/adLDAPUtils.phpnu [ PK ! C uY uY n4 classes/adLDAPGroups.phpnu [ PK ! 0l l + classes/adLDAPUsers.phpnu [ PK ! Nj~B B classes/adLDAPExchange.phpnu [ PK ! D, D, = classes/adLDAPContacts.phpnu [ PK ! r Sj classes/adLDAPFolders.phpnu [ PK ! v v
adLDAP.phpnu [ PK ! Y{ { % t collections/adLDAPGroupCollection.phpnu [ PK ! hV ' D collections/adLDAPContactCollection.phpnu [ PK ! (y y $ collections/adLDAPUserCollection.phpnu [ PK ! J𮝁 ( collections/adLDAPComputerCollection.phpnu [ PK ! ZkJ/ / collections/adLDAPCollection.phpnu [ PK
?"