diff --git a/composer.json b/composer.json index 672316b..73a7e77 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,10 @@ { - "name": "adldap/adldap", + "name": "suqld/adldap", "type": "library", "description": "adLDAP, low-level library to query Active directory", "keywords": ["active directory","ldap","windows"], - "homepage": "http://adldap.sourceforge.net", - "license": "GNU", + "homepage": "https://github.com/suqld/adLDAP/", + "license": "LGPL", "authors": [ { "name": "Richard Hyland" diff --git a/lib/adLDAP/adLDAP.php b/lib/adLDAP/adLDAP.php index a692ead..8101d11 100644 --- a/lib/adLDAP/adLDAP.php +++ b/lib/adLDAP/adLDAP.php @@ -85,7 +85,7 @@ class adLDAP { * * @var string */ - protected $accountSuffix = "@mydomain.local"; + protected $accountSuffix = "@mydomain.local"; /** * The base dn for your domain @@ -94,7 +94,7 @@ class adLDAP { * * @var string */ - protected $baseDn = "DC=mydomain,DC=local"; + protected $baseDn = "DC=mydomain,DC=local"; /** * Port used to talk to the domain controllers. @@ -102,7 +102,7 @@ class adLDAP { * @var int */ protected $adPort = self::ADLDAP_LDAP_PORT; - + /** * Array of domain controllers. Specifiy multiple controllers if you * would like the class to balance the LDAP queries amongst multiple servers @@ -110,7 +110,7 @@ class adLDAP { * @var array */ protected $domainControllers = array("dc01.mydomain.local"); - + /** * Optional account with higher privileges for searching * This should be set to a domain admin account @@ -118,7 +118,7 @@ class adLDAP { * @var string * @var string */ - protected $adminUsername = null; + protected $adminUsername = null; protected $adminPassword = null; /** @@ -129,15 +129,15 @@ class adLDAP { * * @var bool */ - protected $realPrimaryGroup = true; - + protected $realPrimaryGroup = true; + /** * Use SSL (LDAPS), your server needs to be setup, please see * http://adldap.sourceforge.net/wiki/doku.php?id=ldap_over_ssl * * @var bool */ - protected $useSSL = false; + protected $useSSL = false; /** * Use TLS @@ -162,19 +162,19 @@ class adLDAP { * * @var bool */ - protected $recursiveGroups = true; - - // You should not need to edit anything below this line - //****************************************************************************************** - - /** + protected $recursiveGroups = true; + + // You should not need to edit anything below this line + //****************************************************************************************** + + /** * Connection and bind default variables * * @var mixed * @var mixed */ - protected $ldapConnection; - protected $ldapBind; + protected $ldapConnection; + protected $ldapBind; /** * Get the active LDAP Connection @@ -799,66 +799,64 @@ protected function ldapSaslSupported() 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"]; } + if (array_key_exists("address_city", $attributes)){ $mod["l"][0]=$attributes["address_city"]; } + if (array_key_exists("address_code", $attributes)){ $mod["postalCode"][0]=$attributes["address_code"]; } + //if (array_key_exists("address_country", $attributes)){ $mod["countryCode"][0]=$attributes["address_country"]; } // use country codes? + if (array_key_exists("address_country", $attributes)){ $mod["c"][0]=$attributes["address_country"]; } + if (array_key_exists("address_pobox", $attributes)){ $mod["postOfficeBox"][0]=$attributes["address_pobox"]; } + if (array_key_exists("address_state", $attributes)){ $mod["st"][0]=$attributes["address_state"]; } + if (array_key_exists("address_street", $attributes)){ $mod["streetAddress"][0]=$attributes["address_street"]; } + if (array_key_exists("company", $attributes)){ $mod["company"][0]=$attributes["company"]; } + if (array_key_exists("change_password", $attributes)){ $mod["pwdLastSet"][0]=0; } + if (array_key_exists("department", $attributes)){ $mod["department"][0]=$attributes["department"]; } + if (array_key_exists("description", $attributes)){ $mod["description"][0]=$attributes["description"]; } + if (array_key_exists("display_name", $attributes)){ $mod["displayName"][0]=$attributes["display_name"]; } + if (array_key_exists("email", $attributes)){ $mod["mail"][0]=$attributes["email"]; } + if (array_key_exists("expires", $attributes)){ $mod["accountExpires"][0]=$attributes["expires"]; } //unix epoch format? + if (array_key_exists("firstname", $attributes)){ $mod["givenName"][0]=$attributes["firstname"]; } + if (array_key_exists("home_directory", $attributes)){ $mod["homeDirectory"][0]=$attributes["home_directory"]; } + if (array_key_exists("home_drive", $attributes)){ $mod["homeDrive"][0]=$attributes["home_drive"]; } + if (array_key_exists("initials", $attributes)){ $mod["initials"][0]=$attributes["initials"]; } + if (array_key_exists("logon_name", $attributes)){ $mod["userPrincipalName"][0]=$attributes["logon_name"]; } + if (array_key_exists("manager", $attributes)){ $mod["manager"][0]=$attributes["manager"]; } //UNTESTED ***Use DistinguishedName*** + if (array_key_exists("office", $attributes)){ $mod["physicalDeliveryOfficeName"][0]=$attributes["office"]; } + if (array_key_exists("password", $attributes)){ $mod["unicodePwd"][0]=$this->user()->encodePassword($attributes["password"]); } + if (array_key_exists("profile_path", $attributes)){ $mod["profilepath"][0]=$attributes["profile_path"]; } + if (array_key_exists("script_path", $attributes)){ $mod["scriptPath"][0]=$attributes["script_path"]; } + if (array_key_exists("surname", $attributes)){ $mod["sn"][0]=$attributes["surname"]; } + if (array_key_exists("title", $attributes)){ $mod["title"][0]=$attributes["title"]; } + if (array_key_exists("telephone", $attributes)){ $mod["telephoneNumber"][0]=$attributes["telephone"]; } + if (array_key_exists("mobile", $attributes)){ $mod["mobile"][0]=$attributes["mobile"]; } + if (array_key_exists("pager", $attributes)){ $mod["pager"][0]=$attributes["pager"]; } + if (array_key_exists("ipphone", $attributes)){ $mod["ipphone"][0]=$attributes["ipphone"]; } + if (array_key_exists("web_page", $attributes)){ $mod["wWWHomePage"][0]=$attributes["web_page"]; } + if (array_key_exists("fax", $attributes)){ $mod["facsimileTelephoneNumber"][0]=$attributes["fax"]; } + if (array_key_exists("enabled", $attributes)){ $mod["userAccountControl"][0]=$attributes["enabled"]; } + if (array_key_exists("homephone", $attributes)){ $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"]; } + if (array_key_exists("group_sendpermission", $attributes)){ $mod["dlMemSubmitPerms"][0]=$attributes["group_sendpermission"]; } + if (array_key_exists("group_rejectpermission", $attributes)){ $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"]; } + if (array_key_exists("exchange_homemdb", $attributes)){ $mod["homeMDB"][0]=$attributes["exchange_homemdb"]; } + if (array_key_exists("exchange_mailnickname", $attributes)){ $mod["mailNickname"][0]=$attributes["exchange_mailnickname"]; } + if (array_key_exists("exchange_proxyaddress", $attributes)){ $mod["proxyAddresses"][0]=$attributes["exchange_proxyaddress"]; } + if (array_key_exists("exchange_usedefaults", $attributes)){ $mod["mDBUseDefaults"][0]=$attributes["exchange_usedefaults"]; } + if (array_key_exists("exchange_policyexclude", $attributes)){ $mod["msExchPoliciesExcluded"][0]=$attributes["exchange_policyexclude"]; } + if (array_key_exists("exchange_policyinclude", $attributes)){ $mod["msExchPoliciesIncluded"][0]=$attributes["exchange_policyinclude"]; } + if (array_key_exists("exchange_addressbook", $attributes)){ $mod["showInAddressBook"][0]=$attributes["exchange_addressbook"]; } + if (array_key_exists("exchange_altrecipient", $attributes)){ $mod["altRecipient"][0]=$attributes["exchange_altrecipient"]; } + if (array_key_exists("exchange_deliverandredirect", $attributes)){ $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"]; } + if (array_key_exists("exchange_hidefromlists", $attributes)){ $mod["msExchHideFromAddressLists"][0]=$attributes["exchange_hidefromlists"]; } + if (array_key_exists("contact_email", $attributes)){ $mod["targetAddress"][0]=$attributes["contact_email"]; } //echo ("
"); print_r($mod);
/*
@@ -870,8 +868,19 @@ public function adldap_schema($attributes){
}
*/
- if (count($mod)==0){ return (false); }
- return ($mod);
+ // Filter out attributes that are NULL so we can ldap_mod_del them
+ // instead
+ $del = array();
+ foreach ($mod as $attribute => $value) {
+ if ($value[0] == '') {
+ $del[$attribute] = array();
+ unset($mod[$attribute]);
+ }
+ }
+
+ if (count($mod)==0){ $mod = false; }
+ if (count($del)==0){ $del = false; }
+ return (array($mod, $del));
}
/**
@@ -949,4 +958,4 @@ protected function pingController($host) {
*/
class adLDAPException extends \Exception {}
-?>
\ No newline at end of file
+?>
diff --git a/lib/adLDAP/classes/adLDAPContacts.php b/lib/adLDAP/classes/adLDAPContacts.php
index ccf2356..c56a745 100644
--- a/lib/adLDAP/classes/adLDAPContacts.php
+++ b/lib/adLDAP/classes/adLDAPContacts.php
@@ -71,7 +71,7 @@ public function create($attributes)
if (!is_array($attributes["container"])) { return "Container attribute must be an array."; }
// Translate the schema
- $add = $this->adldap->adldap_schema($attributes);
+ list($add, ) = $this->adldap->adldap_schema($attributes);
// Additional stuff only used for adding contacts
$add["cn"][0] = $attributes["display_name"];
@@ -217,14 +217,24 @@ public function modify($distinguishedName, $attributes) {
$mod = $this->adldap->adldap_schema($attributes);
// Check to see if this is an enabled status update
- if (!$mod) {
+ if (!$mod && !$del) {
return false;
}
+
+ // Do the Delete updates
+ if ($del) {
+ $result = @ldap_mod_del($this->adldap->getLdapConnection(), $distinguishedName, $del);
+ if ($result == false) {
+ return false;
+ }
+ }
// Do the update
- $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
- if ($result == false) {
- return false;
+ if ($mod) {
+ $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
+ if ($result == false) {
+ return false;
+ }
}
return true;
diff --git a/lib/adLDAP/classes/adLDAPExchange.php b/lib/adLDAP/classes/adLDAPExchange.php
index b36813f..7476e4c 100644
--- a/lib/adLDAP/classes/adLDAPExchange.php
+++ b/lib/adLDAP/classes/adLDAPExchange.php
@@ -127,7 +127,7 @@ public function addX400($username, $country, $admd, $pdmd, $org, $surname, $give
$attributes['exchange_proxyaddress'] = $proxyValue . 'c=' . $country . ';a=' . $admd . ';p=' . $pdmd . ';o=' . $org . ';s=' . $surname . ';g=' . $givenName . ';';
// Translate the update to the LDAP schema
- $add = $this->adldap->adldap_schema($attributes);
+ list ($add,) = $this->adldap->adldap_schema($attributes);
if (!$add) { return false; }
@@ -191,7 +191,7 @@ public function addAddress($username, $emailAddress, $default = FALSE, $isGUID =
$attributes['exchange_proxyaddress'] = $proxyValue . $emailAddress;
// Translate the update to the LDAP schema
- $add = $this->adldap->adldap_schema($attributes);
+ list ($add,) = $this->adldap->adldap_schema($attributes);
if (!$add) {
return false;
@@ -317,14 +317,24 @@ public function contactMailEnable($distinguishedName, $emailAddress, $mailNickna
$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);
+ list($mod, $del) = $this->adldap->adldap_schema($attributes);
// Check to see if this is an enabled status update
- if (!$mod) { return false; }
+ if (!$mod && !$del) { return false; }
+
+ // Do the Delete updates
+ if ($del){
+ $result = @ldap_mod_del($this->adldap->getLdapConnection(), $userDn, $del);
+ if ($result == false) {
+ return false;
+ }
+ }
// Do the update
- $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
- if ($result == false) { return false; }
+ if ($mod) {
+ $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
+ if ($result == false) { return false; }
+ }
return true;
}
@@ -389,4 +399,4 @@ public function storageDatabases($storageGroup, $attributes = array('cn','distin
return $entries;
}
}
-?>
\ No newline at end of file
+?>
diff --git a/lib/adLDAP/classes/adLDAPGroups.php b/lib/adLDAP/classes/adLDAPGroups.php
index 1aea568..feb1e97 100644
--- a/lib/adLDAP/classes/adLDAPGroups.php
+++ b/lib/adLDAP/classes/adLDAPGroups.php
@@ -362,6 +362,12 @@ public function members($group, $recursive = null)
if ($recursive === null){ $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
// Search the directory for the members of a group
$info = $this->info($group, array("member","cn"));
+
+ if(!array_key_exists("member", $info[0]))
+ {
+ return false;
+ }
+
$users = $info[0]["member"];
if (!is_array($users)) {
return false;
@@ -422,7 +428,9 @@ public function info($groupName, $fields = null)
$groupName = stripslashes($groupName);
}
- $filter = "(&(objectCategory=group)(name=" . $this->adldap->utilities()->ldapSlashes($groupName) . "))";
+ $filter = "(&(objectCategory=group)";
+ $filter .= "(|(samaccountname=".$this->adldap->utilities()->ldapSlashes($groupName).")";
+ $filter .= "(name=".$this->adldap->utilities()->ldapSlashes($groupName).")))";
if ($fields === null) {
$fields = array("member","memberof","cn","description","distinguishedname","objectcategory","samaccountname");
}
@@ -513,9 +521,9 @@ public function search($sAMAaccountType = adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP,
$sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
$entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
- $groupsArray = array();
+ $groupsArray = array();
for ($i=0; $i<$entries["count"]; $i++){
- if ($includeDescription && strlen($entries[$i]["description"][0]) > 0 ) {
+ if ($includeDescription && array_key_exists("description", $entries[$i]) && ($entries[$i]["description"][0]) > 0 ) {
$groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["description"][0];
}
else if ($includeDescription){
diff --git a/lib/adLDAP/classes/adLDAPUsers.php b/lib/adLDAP/classes/adLDAPUsers.php
index 12d765e..0fed359 100644
--- a/lib/adLDAP/classes/adLDAPUsers.php
+++ b/lib/adLDAP/classes/adLDAPUsers.php
@@ -93,7 +93,7 @@ public function create($attributes)
}
// Translate the schema
- $add = $this->adldap->adldap_schema($attributes);
+ list($add, ) = $this->adldap->adldap_schema($attributes);
// Additional stuff only used for adding accounts
$add["cn"][0] = $attributes["display_name"];
@@ -405,10 +405,10 @@ public function modify($username, $attributes, $isGUID = false)
}
// Translate the update to the LDAP schema
- $mod = $this->adldap->adldap_schema($attributes);
+ list ($mod, $del) = $this->adldap->adldap_schema($attributes);
// Check to see if this is an enabled status update
- if (!$mod && !array_key_exists("enabled", $attributes)){
+ if (!$mod && !$del && !array_key_exists("enabled", $attributes)){
return false;
}
@@ -423,10 +423,20 @@ public function modify($username, $attributes, $isGUID = false)
$mod["userAccountControl"][0] = $this->accountControl($controlOptions);
}
+ // Do the Delete updates
+ if ($del) {
+ $result = @ldap_mod_del($this->adldap->getLdapConnection(), $userDn, $del);
+ if ($result == false) {
+ return false;
+ }
+ }
+
// Do the update
- $result = @ldap_modify($this->adldap->getLdapConnection(), $userDn, $mod);
- if ($result == false) {
- return false;
+ if ($mod) {
+ $result = @ldap_modify($this->adldap->getLdapConnection(), $userDn, $mod);
+ if ($result == false) {
+ return false;
+ }
}
return true;
diff --git a/lib/adLDAP/classes/adLDAPUtils.php b/lib/adLDAP/classes/adLDAPUtils.php
index 3d0290c..d2fc287 100644
--- a/lib/adLDAP/classes/adLDAPUtils.php
+++ b/lib/adLDAP/classes/adLDAPUtils.php
@@ -68,16 +68,21 @@ public function niceNames($groups)
$groupArray = array();
for ($i=0; $i<$groups["count"]; $i++){ // For each group
$line = $groups[$i];
-
+
if (strlen($line)>0) {
- // More presumptions, they're all prefixed with CN=
- // so we ditch the first three characters and the group
- // name goes up to the first comma
- $bits=explode(",", $line);
- $groupArray[] = substr($bits[0], 3, (strlen($bits[0])-3));
+ $fields = array("samaccountname");
+ $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($groups[$i]) . "))";
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ if (!isset($entries[0]['samaccountname'][0])) {
+ continue;
+ }
+
+ $groupArray[] = $entries[0]['samaccountname'][0];
}
}
- return $groupArray;
+ return $groupArray;
}
/**
@@ -263,4 +268,4 @@ public static function convertWindowsTimeToUnixTime($windowsTime) {
}
}
-?>
\ No newline at end of file
+?>