diff options
Diffstat (limited to 'inc/adLDAP.php')
-rw-r--r-- | inc/adLDAP.php | 580 |
1 files changed, 290 insertions, 290 deletions
diff --git a/inc/adLDAP.php b/inc/adLDAP.php index 5ec485b61..209daf37f 100644 --- a/inc/adLDAP.php +++ b/inc/adLDAP.php @@ -1,29 +1,29 @@ <?php /** - * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY + * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY * Version 3.1 - * + * * PHP Version 5 with SSL and LDAP support - * + * * Written by Scott Barnett, Richard Hyland * email: scott@wiggumworld.com, adldap@richardhyland.com * http://adldap.sourceforge.net/ - * + * * Copyright (c) 2006-2009 Scott Barnett, Richard Hyland - * + * * We'd appreciate any improvements or additions to be submitted back * to benefit the entire community :) - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * @category ToolsAndUtilities * @package adLDAP * @author Scott Barnett, Richard Hyland @@ -47,93 +47,93 @@ define ('ADLDAP_DISTRIBUTION_LOCAL_GROUP', 536870913); /** * Main adLDAP class -* +* * Can be initialised using $adldap = new adLDAP(); -* +* * Something to keep in mind is that Active Directory is a permissions * based directory. If you bind as a domain user, you can't fetch as * much information on other users as you could as a domain admin. -* +* * Before asking questions, please read the Documentation at * http://adldap.sourceforge.net/wiki/doku.php?id=api */ class adLDAP { /** * The account suffix for your domain, can be set when the class is invoked - * + * * @var string */ - protected $_account_suffix="@mydomain.local"; - + protected $_account_suffix="@mydomain.local"; + /** * The base dn for your domain - * + * * @var string */ - protected $_base_dn = "DC=mydomain,DC=local"; - + protected $_base_dn = "DC=mydomain,DC=local"; + /** * Array of domain controllers. Specifiy multiple controllers if you * would like the class to balance the LDAP queries amongst multiple servers - * + * * @var array */ - protected $_domain_controllers = array ("dc01.mydomain.local"); - + protected $_domain_controllers = array ("dc01.mydomain.local"); + /** * Optional account with higher privileges for searching * This should be set to a domain admin account - * + * * @var string * @var string */ - protected $_ad_username=NULL; + protected $_ad_username=NULL; protected $_ad_password=NULL; - + /** * AD does not return the primary group. http://support.microsoft.com/?kbid=321360 - * This tweak will resolve the real primary group. + * This tweak will resolve the real primary group. * Setting to false will fudge "Domain Users" and is much faster. Keep in mind though that if * someone's primary group is NOT domain users, this is obviously going to mess up the results - * + * * @var bool */ - protected $_real_primarygroup=true; - + protected $_real_primarygroup=true; + /** * Use SSL, your server needs to be setup, please see * http://adldap.sourceforge.net/wiki/doku.php?id=ldap_over_ssl - * + * * @var bool */ - protected $_use_ssl=false; - + protected $_use_ssl=false; + /** - * When querying group memberships, do it recursively + * When querying group memberships, do it recursively * eg. User Fred is a member of Group A, which is a member of Group B, which is a member of Group C - * user_ingroup("Fred","C") will returns true with this option turned on, false if turned off - * + * user_ingroup("Fred","C") will returns true with this option turned on, false if turned off + * * @var bool */ - protected $_recursive_groups=true; - - // You should not need to edit anything below this line - //****************************************************************************************** - - /** + protected $_recursive_groups=true; + + // You should not need to edit anything below this line + //****************************************************************************************** + + /** * Connection and bind default variables - * + * * @var mixed * @var mixed */ - protected $_conn; - protected $_bind; + protected $_conn; + protected $_bind; /** * 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 @@ -158,11 +158,11 @@ class adLDAP { } else { $this->_conn = ldap_connect($dc); } - + // Set some ldap options for talking to AD ldap_set_option($this->_conn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($this->_conn, LDAP_OPT_REFERRALS, 0); - + // Bind as a domain admin if they've set it up if ($this->_ad_username!=NULL && $this->_ad_password!=NULL){ $this->_bind = @ldap_bind($this->_conn,$this->_ad_username.$this->_account_suffix,$this->_ad_password); @@ -175,22 +175,22 @@ class adLDAP { } } } - + return (true); } /** * Default Destructor - * + * * Closes the LDAP connection - * + * * @return void */ function __destruct(){ ldap_close ($this->_conn); } /** * 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 $prevent_rebind @@ -198,21 +198,21 @@ class adLDAP { */ public function authenticate($username,$password,$prevent_rebind=false){ // Prevent null binding - if ($username==NULL || $password==NULL){ return (false); } - - // Bind as the user + if ($username==NULL || $password==NULL){ return (false); } + + // Bind as the user $this->_bind = @ldap_bind($this->_conn,$username.$this->_account_suffix,$password); if (!$this->_bind){ return (false); } - + // Cnce we've checked their details, kick back into admin mode if we have it if ($this->_ad_username!=NULL && !$prevent_rebind){ $this->_bind = @ldap_bind($this->_conn,$this->_ad_username.$this->_account_suffix,$this->_ad_password); if (!$this->_bind){ // This should never happen in theory throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->get_last_error()); - } + } } - + return (true); } @@ -221,7 +221,7 @@ class adLDAP { /** * Add a group to a group - * + * * @param string $parent The parent group name * @param string $child The child group name * @return bool @@ -232,23 +232,23 @@ class adLDAP { $parent_group=$this->group_info($parent,array("cn")); if ($parent_group[0]["dn"]==NULL){ return (false); } $parent_dn=$parent_group[0]["dn"]; - + // Find the child group's dn $child_group=$this->group_info($child,array("cn")); if ($child_group[0]["dn"]==NULL){ return (false); } $child_dn=$child_group[0]["dn"]; - + $add=array(); $add["member"] = $child_dn; - + $result=@ldap_mod_add($this->_conn,$parent_dn,$add); if ($result==false){ return (false); } return (true); } - + /** * Add a user to a group - * + * * @param string $group The group to add the user to * @param string $user The user to add to the group * @return bool @@ -256,27 +256,27 @@ class adLDAP { public function group_add_user($group,$user){ // Adding a user is a bit fiddly, we need to get the full DN of the user // and add it using the full DN of the group - + // Find the user's dn $user_dn=$this->user_dn($user); if ($user_dn===false){ return (false); } - + // Find the group's dn $group_info=$this->group_info($group,array("cn")); if ($group_info[0]["dn"]==NULL){ return (false); } $group_dn=$group_info[0]["dn"]; - + $add=array(); $add["member"] = $user_dn; - + $result=@ldap_mod_add($this->_conn,$group_dn,$add); if ($result==false){ return (false); } return (true); } - + /** * Add a contact to a group - * + * * @param string $group The group to add the contact to * @param string $contact_dn The DN of the contact to add * @return bool @@ -284,15 +284,15 @@ class adLDAP { public function group_add_contact($group,$contact_dn){ // To add a contact we take the contact's DN // and add it using the full DN of the group - + // Find the group's dn $group_info=$this->group_info($group,array("cn")); if ($group_info[0]["dn"]==NULL){ return (false); } $group_dn=$group_info[0]["dn"]; - + $add=array(); $add["member"] = $contact_dn; - + $result=@ldap_mod_add($this->_conn,$group_dn,$add); if ($result==false){ return (false); } return (true); @@ -300,7 +300,7 @@ class adLDAP { /** * Create a group - * + * * @param array $attributes Default attributes of the group * @return bool */ @@ -315,7 +315,7 @@ class adLDAP { //$member_array = array(); //$member_array[0] = "cn=user1,cn=Users,dc=yourdomain,dc=com"; //$member_array[1] = "cn=administrator,cn=Users,dc=yourdomain,dc=com"; - + $add=array(); $add["cn"] = $attributes["group_name"]; $add["samaccountname"] = $attributes["group_name"]; @@ -326,88 +326,88 @@ class adLDAP { $container="OU=".implode(",OU=",$attributes["container"]); $result=ldap_add($this->_conn,"CN=".$add["cn"].", ".$container.",".$this->_base_dn,$add); if ($result!=true){ return (false); } - + return (true); } /** * Remove a group from a group - * + * * @param string $parent The parent group name * @param string $child The child group name * @return bool */ public function group_del_group($parent,$child){ - + // Find the parent dn $parent_group=$this->group_info($parent,array("cn")); if ($parent_group[0]["dn"]==NULL){ return (false); } $parent_dn=$parent_group[0]["dn"]; - + // Find the child dn $child_group=$this->group_info($child,array("cn")); if ($child_group[0]["dn"]==NULL){ return (false); } $child_dn=$child_group[0]["dn"]; - + $del=array(); $del["member"] = $child_dn; - + $result=@ldap_mod_del($this->_conn,$parent_dn,$del); if ($result==false){ return (false); } return (true); } - + /** * Remove a user from a group - * + * * @param string $group The group to remove a user from * @param string $user The AD user to remove from the group * @return bool */ public function group_del_user($group,$user){ - + // Find the parent dn $group_info=$this->group_info($group,array("cn")); if ($group_info[0]["dn"]==NULL){ return (false); } $group_dn=$group_info[0]["dn"]; - + // Find the users dn $user_dn=$this->user_dn($user); if ($user_dn===false){ return (false); } $del=array(); $del["member"] = $user_dn; - + $result=@ldap_mod_del($this->_conn,$group_dn,$del); if ($result==false){ return (false); } return (true); } - + /** * Remove a contact from a group - * + * * @param string $group The group to remove a user from * @param string $contact_dn The DN of a contact to remove from the group * @return bool */ public function group_del_contact($group,$contact_dn){ - + // Find the parent dn $group_info=$this->group_info($group,array("cn")); if ($group_info[0]["dn"]==NULL){ return (false); } $group_dn=$group_info[0]["dn"]; - + $del=array(); $del["member"] = $contact_dn; - + $result=@ldap_mod_del($this->_conn,$group_dn,$del); if ($result==false){ return (false); } return (true); } - + /** * Return a list of members in a group - * + * * @param string $group The group to query * @return array */ @@ -417,12 +417,12 @@ class adLDAP { $info=$this->group_info($group,array("member","cn")); $users=$info[0]["member"]; if (!is_array($users)) { - return (false); + return (false); } - + $user_array=array(); - for ($i=0; $i<$users["count"]; $i++){ + for ($i=0; $i<$users["count"]; $i++){ $filter="(&(objectCategory=person)(distinguishedName=".$this->ldap_slashes($users[$i])."))"; $fields = array("samaccountname", "distinguishedname"); $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); @@ -436,11 +436,11 @@ class adLDAP { } return ($user_array); } - + /** * Group Information. Returns an array of information about a group. * The group name is case sensitive - * + * * @param string $group_name The group name to retrieve info about * @param array $fields Fields to retrieve * @return array @@ -448,7 +448,7 @@ class adLDAP { public function group_info($group_name,$fields=NULL){ if ($group_name==NULL){ return (false); } if (!$this->_bind){ return (false); } - + $filter="(&(objectCategory=group)(name=".$this->ldap_slashes($group_name)."))"; //echo ($filter."!!!<br>"); if ($fields==NULL){ $fields=array("member","memberof","cn","description","distinguishedname","objectcategory","samaccountname"); } @@ -457,10 +457,10 @@ class adLDAP { //print_r($entries); return ($entries); } - + /** * Return a complete list of "groups in groups" - * + * * @param string $group The group to get the list from * @return array */ @@ -468,14 +468,14 @@ class adLDAP { if ($group==NULL){ return (false); } $ret_groups=array(); - + $groups=$this->group_info($group,array("memberof")); $groups=$groups[0]["memberof"]; if ($groups){ $group_names=$this->nice_names($groups); $ret_groups=array_merge($ret_groups,$group_names); //final groups to return - + foreach ($group_names as $id => $group_name){ $child_groups=$this->recursive_groups($group_name); $ret_groups=array_merge($ret_groups,$child_groups); @@ -484,10 +484,10 @@ class adLDAP { return ($ret_groups); } - + /** - * Returns a complete list of the groups in AD based on a SAM Account Type - * + * Returns a complete list of the groups in AD based on a SAM Account Type + * * @param string $samaccounttype The account type to return * @param bool $include_desc Whether to return a description * @param string $search Search parameters @@ -496,14 +496,14 @@ class adLDAP { */ public function search_groups($samaccounttype = ADLDAP_SECURITY_GLOBAL_GROUP, $include_desc = false, $search = "*", $sorted = true) { if (!$this->_bind){ return (false); } - + // Perform the search and grab all their details $filter = "(&(objectCategory=group)(samaccounttype=". $samaccounttype .")(cn=".$search."))"; $fields=array("samaccountname","description"); $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $sr); - $groups_array = array(); + $groups_array = array(); for ($i=0; $i<$entries["count"]; $i++){ if ($include_desc && strlen($entries[$i]["description"][0]) > 0 ){ $groups_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["description"][0]; @@ -516,10 +516,10 @@ class adLDAP { if( $sorted ){ asort($groups_array); } return ($groups_array); } - + /** * Returns a complete list of security groups in AD - * + * * @param bool $include_desc Whether to return a description * @param string $search Search parameters * @param bool $sorted Whether to sort the results @@ -529,10 +529,10 @@ class adLDAP { $groups_array = $this->search_groups(ADLDAP_SECURITY_GLOBAL_GROUP, $include_desc, $search, $sorted); return ($groups_array); } - + /** * Returns a complete list of distribution lists in AD - * + * * @param bool $include_desc Whether to return a description * @param string $search Search parameters * @param bool $sorted Whether to sort the results @@ -542,15 +542,15 @@ class adLDAP { $groups_array = $this->search_groups(ADLDAP_DISTRIBUTION_GROUP, $include_desc, $search, $sorted); return ($groups_array); } - + //***************************************************************************************************************** // USER FUNCTIONS /** * Create a user - * + * * If you specify a password here, this can only be performed over SSL - * + * * @param array $attributes The attributes to set to the user account * @return bool */ @@ -563,7 +563,7 @@ class adLDAP { if (!array_key_exists("container",$attributes)){ return ("Missing compulsory field [container]"); } if (!is_array($attributes["container"])){ return ("Container attribute must be an array."); } - if (array_key_exists("password",$attributes) && !$this->_use_ssl){ + if (array_key_exists("password",$attributes) && !$this->_use_ssl){ throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.'); } @@ -571,7 +571,7 @@ class adLDAP { // Translate the schema $add=$this->adldap_schema($attributes); - + // Additional stuff only used for adding accounts $add["cn"][0]=$attributes["display_name"]; $add["samaccountname"][0]=$attributes["username"]; @@ -594,27 +594,27 @@ class adLDAP { // Add the entry $result=@ldap_add($this->_conn, "CN=".$add["cn"][0].", ".$container.",".$this->_base_dn, $add); if ($result!=true){ return (false); } - + return (true); } - + /** * Delete a user account - * + * * @param string $username The username to delete (please be careful here!) * @return array */ - public function user_delete($username) { + public function user_delete($username) { $userinfo = $this->user_info($username, array("*")); $dn = $userinfo[0]['distinguishedname'][0]; $result=$this->dn_delete($dn); - if ($result!=true){ return (false); } + if ($result!=true){ return (false); } return (true); } - + /** * Groups the user is a member of - * + * * @param string $username The username to query * @param bool $recursive Recursive list of groups * @return array @@ -623,7 +623,7 @@ class adLDAP { if ($username==NULL){ return (false); } if ($recursive==NULL){ $recursive=$this->_recursive_groups; } // Use the default option if they haven't set it if (!$this->_bind){ return (false); } - + // Search the directory for their information $info=@$this->user_info($username,array("memberof","primarygroupid")); $groups=$this->nice_names($info[0]["memberof"]); // Presuming the entry returned is our guy (unique usernames) @@ -634,13 +634,13 @@ class adLDAP { $groups=array_merge($groups,$extra_groups); } } - + return ($groups); } - + /** * Find information about the users - * + * * @param string $username The username to query * @param array $fields Array of parameters to query * @return array @@ -653,7 +653,7 @@ class adLDAP { if ($fields==NULL){ $fields=array("samaccountname","mail","memberof","department","displayname","telephonenumber","primarygroupid","objectsid"); } $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $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->_real_primarygroup && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["objectsid"][0])){ @@ -663,14 +663,14 @@ class adLDAP { $entries[0]["memberof"][]="CN=Domain Users,CN=Users,".$this->_base_dn; } } - + $entries[0]["memberof"]["count"]++; return ($entries); } - + /** * Determine if a user is in a specific group - * + * * @param string $username The username to query * @param string $group The name of the group to check against * @param bool $recursive Check groups recursively @@ -681,26 +681,26 @@ class adLDAP { if ($group==NULL){ return (false); } if (!$this->_bind){ return (false); } if ($recursive==NULL){ $recursive=$this->_recursive_groups; } // Use the default option if they haven't set it - + // Get a list of the groups $groups=$this->user_groups($username,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 user - * + * * @param string $username The username 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 user_modify($username,$attributes){ if ($username==NULL){ return ("Missing compulsory field [username]"); } - if (array_key_exists("password",$attributes) && !$this->_use_ssl){ + if (array_key_exists("password",$attributes) && !$this->_use_ssl){ throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.'); } //if (array_key_exists("container",$attributes)){ @@ -711,13 +711,13 @@ class adLDAP { // Find the dn of the user $user_dn=$this->user_dn($username); if ($user_dn===false){ return (false); } - - // Translate the update to the LDAP schema + + // Translate the update to the LDAP schema $mod=$this->adldap_schema($attributes); - + // Check to see if this is an enabled status update if (!$mod && !array_key_exists("enabled", $attributes)){ return (false); } - + // Set the account control attribute (only if specified) if (array_key_exists("enabled",$attributes)){ if ($attributes["enabled"]){ $control_options=array("NORMAL_ACCOUNT"); } @@ -728,13 +728,13 @@ class adLDAP { // Do the update $result=@ldap_modify($this->_conn,$user_dn,$mod); if ($result==false){ return (false); } - + return (true); } - + /** * Disable a user account - * + * * @param string $username The username to disable * @return bool */ @@ -743,13 +743,13 @@ class adLDAP { $attributes=array("enabled"=>0); $result = $this->user_modify($username, $attributes); if ($result==false){ return (false); } - + return (true); } - + /** * Enable a user account - * + * * @param string $username The username to enable * @return bool */ @@ -758,13 +758,13 @@ class adLDAP { $attributes=array("enabled"=>1); $result = $this->user_modify($username, $attributes); if ($result==false){ return (false); } - + return (true); } - + /** * Set the password of a user - This must be performed over SSL - * + * * @param string $username The username to modify * @param string $password The new password * @return bool @@ -773,25 +773,25 @@ class adLDAP { if ($username==NULL){ return (false); } if ($password==NULL){ return (false); } if (!$this->_bind){ return (false); } - if (!$this->_use_ssl){ + if (!$this->_use_ssl){ throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.'); } - + $user_dn=$this->user_dn($username); if ($user_dn===false){ return (false); } - + $add=array(); $add["unicodePwd"][0]=$this->encode_password($password); - + $result=ldap_mod_replace($this->_conn,$user_dn,$add); if ($result==false){ return (false); } - + return (true); } - + /** * Return a list of all users in AD - * + * * @param bool $include_desc Return a description of the user * @param string $search Search parameter * @param bool $sorted Sort the user accounts @@ -799,7 +799,7 @@ class adLDAP { */ public function all_users($include_desc = false, $search = "*", $sorted = true){ if (!$this->_bind){ return (false); } - + // Perform the search and grab all their details $filter = "(&(objectClass=user)(samaccounttype=". ADLDAP_NORMAL_ACCOUNT .")(objectCategory=person)(cn=".$search."))"; $fields=array("samaccountname","displayname"); @@ -819,14 +819,14 @@ class adLDAP { if ($sorted){ asort($users_array); } return ($users_array); } - + //***************************************************************************************************************** // 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 */ @@ -839,13 +839,13 @@ class adLDAP { // Translate the schema $add=$this->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"; + $add["objectclass"][3]="contact"; if (!isset($attributes['exchange_hidefromlists'])) { $add["msExchHideFromAddressLists"][0]="TRUE"; } @@ -857,13 +857,13 @@ class adLDAP { // Add the entry $result=@ldap_add($this->_conn, "CN=".$add["cn"][0].", ".$container.",".$this->_base_dn, $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 @@ -872,7 +872,7 @@ class adLDAP { if ($distinguishedname==NULL){ return (false); } if ($recursive==NULL){ $recursive=$this->_recursive_groups; } //use the default option if they haven't set it if (!$this->_bind){ return (false); } - + // Search the directory for their information $info=@$this->contact_info($distinguishedname,array("memberof","primarygroupid")); $groups=$this->nice_names($info[0]["memberof"]); //presuming the entry returned is our contact @@ -883,13 +883,13 @@ class adLDAP { $groups=array_merge($groups,$extra_groups); } } - + return ($groups); } - + /** * Get contact information - * + * * @param string $distinguisedname The full DN of a contact * @param array $fields Attributes to be returned * @return array @@ -902,7 +902,7 @@ class adLDAP { if ($fields==NULL){ $fields=array("distinguishedname","mail","memberof","department","displayname","telephonenumber","primarygroupid","objectsid"); } $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $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->_real_primarygroup && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["primarygroupid"][0])){ @@ -912,14 +912,14 @@ class adLDAP { $entries[0]["memberof"][]="CN=Domain Users,CN=Users,".$this->_base_dn; } } - + $entries[0]["memberof"]["count"]++; return ($entries); } - + /** * 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 @@ -930,54 +930,54 @@ class adLDAP { if ($group==NULL){ return (false); } if (!$this->_bind){ return (false); } if ($recursive==NULL){ $recursive=$this->_recursive_groups; } //use the default option if they haven't set it - + // Get a list of the groups $groups=$this->contact_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 contact_modify($distinguishedname,$attributes){ if ($distinguishedname==NULL){ return ("Missing compulsory field [distinguishedname]"); } - - // Translate the update to the LDAP schema + + // Translate the update to the LDAP schema $mod=$this->adldap_schema($attributes); - + // Check to see if this is an enabled status update if (!$mod){ return (false); } - + // Do the update $result=ldap_modify($this->_conn,$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 contact_delete($distinguishedname) { $result = $this->dn_delete($distinguishedname); - if ($result!=true){ return (false); } + if ($result!=true){ return (false); } return (true); } - + /** * Return a list of all contacts - * + * * @param bool $include_desc Include a description of a contact * @param string $search The search parameters * @param bool $sorted Whether to sort the results @@ -985,10 +985,10 @@ class adLDAP { */ public function all_contacts($include_desc = false, $search = "*", $sorted = true){ if (!$this->_bind){ return (false); } - + // Perform the search and grab all their details $filter = "(&(objectClass=contact)(cn=".$search."))"; - $fields=array("displayname","distinguishedname"); + $fields=array("displayname","distinguishedname"); $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $sr); @@ -1008,10 +1008,10 @@ class adLDAP { //***************************************************************************************************************** // COMPUTER FUNCTIONS - + /** * Get information about a specific computer - * + * * @param string $computer_name The name of the computer * @param array $fields Attributes to return * @return array @@ -1024,16 +1024,16 @@ class adLDAP { if ($fields==NULL){ $fields=array("memberof","cn","displayname","dnshostname","distinguishedname","objectcategory","operatingsystem","operatingsystemservicepack","operatingsystemversion"); } $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $sr); - + return ($entries); } - + //************************************************************************************************************ // EXCHANGE FUNCTIONS - + /** * Create an Exchange account - * + * * @param string $username The username of the user to add the Exchange account to * @param array $storagegroup The mailbox, Exchange Storage Group, for the user account, this must be a full CN * If the storage group has a different base_dn to the adLDAP configuration, set it using $base_dn @@ -1044,20 +1044,20 @@ class adLDAP { * @return bool */ public function exchange_create_mailbox($username, $storagegroup, $emailaddress, $mailnickname=NULL, $usedefaults=TRUE, $base_dn=NULL){ - if ($username==NULL){ return ("Missing compulsory field [username]"); } + if ($username==NULL){ return ("Missing compulsory field [username]"); } if ($storagegroup==NULL){ return ("Missing compulsory array [storagegroup]"); } if (!is_array($storagegroup)){ return ("[storagegroup] must be an array"); } if ($emailaddress==NULL){ return ("Missing compulsory field [emailaddress]"); } - + if ($base_dn==NULL) { - $base_dn = $this->_base_dn; + $base_dn = $this->_base_dn; } - + $container="CN=".implode(",CN=",$storagegroup); - + if ($mailnickname==NULL) { $mailnickname=$username; } $mdbUseDefaults = $this->bool2str($usedefaults); - + $attributes = array( 'exchange_homemdb'=>$container.",".$base_dn, 'exchange_proxyaddress'=>'SMTP:' . $emailaddress, @@ -1068,29 +1068,29 @@ class adLDAP { if ($result==false){ return (false); } return (true); } - + /** * Add an address to Exchange - * + * * @param string $username The username of the user to add the Exchange account to * @param string $emailaddress The email address to add to this user * @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 * @return bool */ public function exchange_add_address($username, $emailaddress, $default=FALSE) { - if ($username==NULL){ return ("Missing compulsory field [username]"); } + if ($username==NULL){ return ("Missing compulsory field [username]"); } if ($emailaddress==NULL) { return ("Missing compulsory fields [emailaddress]"); } - + $proxyvalue = 'smtp:'; if ($default === true) { $proxyvalue = 'SMTP:'; } - + // Find the dn of the user $user=$this->user_info($username,array("cn","proxyaddresses")); if ($user[0]["dn"]==NULL){ return (false); } $user_dn=$user[0]["dn"]; - + // We need to scan existing proxy addresses and demote the default one if (is_array($user[0]["proxyaddresses"]) && $default===true) { $modaddresses = array(); @@ -1103,49 +1103,49 @@ class adLDAP { } } $modaddresses['proxyAddresses'][(sizeof($user[0]['proxyaddresses'])-1)] = 'SMTP:' . $emailaddress; - + $result=@ldap_mod_replace($this->_conn,$user_dn,$modaddresses); if ($result==false){ return (false); } - + return (true); } else { // We do not have to demote an email address from the default so we can just add the new proxy address $attributes['exchange_proxyaddress'] = $proxyvalue . $emailaddress; - - // Translate the update to the LDAP schema + + // Translate the update to the LDAP schema $add=$this->adldap_schema($attributes); - + if (!$add){ return (false); } - + // Do the update // Take out the @ to see any errors, usually this error might occur because the address already // exists in the list of proxyAddresses $result=@ldap_mod_add($this->_conn,$user_dn,$add); if ($result==false){ return (false); } - + return (true); } } - + /** * Remove an address to Exchange - * If you remove a default address the account will no longer have a default, + * If you remove a default address the account will no longer have a default, * we recommend changing the default address first - * + * * @param string $username The username of the user to add the Exchange account to * @param string $emailaddress The email address to add to this user * @return bool */ public function exchange_del_address($username, $emailaddress) { - if ($username==NULL){ return ("Missing compulsory field [username]"); } + if ($username==NULL){ return ("Missing compulsory field [username]"); } if ($emailaddress==NULL) { return ("Missing compulsory fields [emailaddress]"); } - + // Find the dn of the user $user=$this->user_info($username,array("cn","proxyaddresses")); if ($user[0]["dn"]==NULL){ return (false); } $user_dn=$user[0]["dn"]; - + if (is_array($user[0]["proxyaddresses"])) { $mod = array(); for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) { @@ -1156,10 +1156,10 @@ class adLDAP { $mod['proxyAddresses'][0] = 'smtp:' . $emailaddress; } } - + $result=@ldap_mod_del($this->_conn,$user_dn,$mod); if ($result==false){ return (false); } - + return (true); } else { @@ -1168,20 +1168,20 @@ class adLDAP { } /** * Change the default address - * + * * @param string $username The username of the user to add the Exchange account to * @param string $emailaddress The email address to make default * @return bool */ public function exchange_primary_address($username, $emailaddress) { - if ($username==NULL){ return ("Missing compulsory field [username]"); } + if ($username==NULL){ return ("Missing compulsory field [username]"); } if ($emailaddress==NULL) { return ("Missing compulsory fields [emailaddress]"); } - + // Find the dn of the user $user=$this->user_info($username,array("cn","proxyaddresses")); if ($user[0]["dn"]==NULL){ return (false); } $user_dn=$user[0]["dn"]; - + if (is_array($user[0]["proxyaddresses"])) { $modaddresses = array(); for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) { @@ -1195,47 +1195,47 @@ class adLDAP { $modaddresses['proxyAddresses'][$i] = $user[0]['proxyaddresses'][$i]; } } - + $result=@ldap_mod_replace($this->_conn,$user_dn,$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 exchange_contact_mailenable($distinguishedname, $emailaddress, $mailnickname=NULL){ - if ($distinguishedname==NULL){ return ("Missing compulsory field [distinguishedname]"); } - if ($emailaddress==NULL){ return ("Missing compulsory field [emailaddress]"); } - + 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->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 + + // Translate the update to the LDAP schema $mod=$this->adldap_schema($attributes); - + // Check to see if this is an enabled status update if (!$mod){ return (false); } - + // Do the update $result=ldap_modify($this->_conn,$distinguishedname,$mod); if ($result==false){ return (false); } - + return (true); } @@ -1244,30 +1244,30 @@ class adLDAP { /** * 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 get_last_error() { return @ldap_error($this->_conn); } - + /** * Schema - * + * * @param array $attributes Attributes to be queried * @return array - */ + */ protected 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')); @@ -1304,21 +1304,21 @@ class adLDAP { 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"]; } - + // 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"]; } - + // 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 ("<pre>"); print_r($mod); /* // modifying a name is a bit fiddly @@ -1335,25 +1335,25 @@ class adLDAP { /** * Coping with AD not returning the primary group - * http://support.microsoft.com/?kbid=321360 - * + * http://support.microsoft.com/?kbid=321360 + * * For some reason it's not possible to search on primarygrouptoken=XXX * If someone can show otherwise, I'd like to know about it :) * this way is resource intensive and generally a pain in the @#%^ - * + * * @deprecated deprecated since version 3.1, see get get_primary_group * @param string $gid Group ID * @return string */ - protected function group_cn($gid){ + protected function group_cn($gid){ if ($gid==NULL){ return (false); } $r=false; - + $filter="(&(objectCategory=group)(samaccounttype=". ADLDAP_SECURITY_GLOBAL_GROUP ."))"; $fields=array("primarygrouptoken","samaccountname","distinguishedname"); $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $sr); - + for ($i=0; $i<$entries["count"]; $i++){ if ($entries[$i]["primarygrouptoken"][0]==$gid){ $r=$entries[$i]["distinguishedname"][0]; @@ -1363,14 +1363,14 @@ class adLDAP { return ($r); } - + /** * Coping with AD not returning the primary group - * http://support.microsoft.com/?kbid=321360 - * - * This is a re-write based on code submitted by Bruce which prevents the + * http://support.microsoft.com/?kbid=321360 + * + * This is a re-write based on code submitted by Bruce which prevents the * need to search each security group to find the true primary group - * + * * @param string $gid Group ID * @param string $usersid User's Object SID * @return string @@ -1387,10 +1387,10 @@ class adLDAP { return $entries[0]['distinguishedname'][0]; } - + /** * Convert a binary SID to a text SID - * + * * @param string $binsid A Binary SID * @return string */ @@ -1410,10 +1410,10 @@ class adLDAP { // Cheat by tacking on the S- return 'S-' . $result; } - + /** * Converts a little-endian hex number to one that hexdec() can convert - * + * * @param string $hex A hex code * @return string */ @@ -1424,11 +1424,11 @@ class adLDAP { } return $result; } - + /** - * Obtain the user's distinguished name based on their userid - * - * + * Obtain the user's distinguished name based on their userid + * + * * @param string $username The username * @return string */ @@ -1451,10 +1451,10 @@ class adLDAP { for ($i=0; $i <strlen($password); $i++){ $encoded.="{$password{$i}}\000"; } return ($encoded); } - + /** * Escape strings for the use in LDAP filters - * + * * Ported from Perl's Net::LDAP::Util escape_filter_value * * @author Andreas Gohr <andi@splitbrain.org> @@ -1466,21 +1466,21 @@ class adLDAP { '"\\\\\".join("",unpack("H2","$1"))', $string); } - + /** * Select a random domain controller from your domain controller array - * + * * @return string */ protected function random_controller(){ mt_srand(doubleval(microtime()) * 100000000); // For older PHP versions return ($this->_domain_controllers[array_rand($this->_domain_controllers)]); } - + /** * Account control options * - * @param array $options The options to convert to int + * @param array $options The options to convert to int * @return int */ protected function account_control($options){ @@ -1506,13 +1506,13 @@ class adLDAP { if (in_array("TRUSTED_FOR_DELEGATION",$options)){ $val=$val+524288; } if (in_array("NOT_DELEGATED",$options)){ $val=$val+1048576; } if (in_array("USE_DES_KEY_ONLY",$options)){ $val=$val+2097152; } - if (in_array("DONT_REQ_PREAUTH",$options)){ $val=$val+4194304; } + if (in_array("DONT_REQ_PREAUTH",$options)){ $val=$val+4194304; } if (in_array("PASSWORD_EXPIRED",$options)){ $val=$val+8388608; } if (in_array("TRUSTED_TO_AUTH_FOR_DELEGATION",$options)){ $val=$val+16777216; } } return ($val); } - + /** * Take an LDAP query and return the nice names, without all the LDAP prefixes (eg. CN, DN) * @@ -1524,8 +1524,8 @@ class adLDAP { $group_array=array(); for ($i=0; $i<$groups["count"]; $i++){ // For each group $line=$groups[$i]; - - if (strlen($line)>0){ + + 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 @@ -1533,9 +1533,9 @@ class adLDAP { $group_array[]=substr($bits[0],3,(strlen($bits[0])-3)); } } - return ($group_array); + return ($group_array); } - + /** * 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 @@ -1543,12 +1543,12 @@ class adLDAP { * @param string $dn The distinguished name to delete * @return bool */ - protected function dn_delete($dn){ + protected function dn_delete($dn){ $result=ldap_delete($this->_conn, $dn); if ($result!=true){ return (false); } return (true); } - + /** * Convert a boolean value to a string * You should never need to call this yourself @@ -1559,7 +1559,7 @@ class adLDAP { protected function bool2str($bool) { return ($bool) ? 'TRUE' : 'FALSE'; } - + /** * Convert 8bit characters e.g. accented characters to UTF8 encoded characters */ @@ -1573,14 +1573,14 @@ class adLDAP { } } if ($encode === true && $key != 'password') { - $item = utf8_encode($item); + $item = utf8_encode($item); } - } + } } /** * adLDAP Exception Handler -* +* * Exceptions of this type are thrown on bind failure or when SSL is required but not configured * Example: * try { @@ -1593,4 +1593,4 @@ class adLDAP { */ class adLDAPException extends Exception {} -?>
\ No newline at end of file +?> |