[SOLVED] Â LDAP authentication II - The questions |
10/6/2006 6:35:38 PM |
PHPRunner General questions | |
T
thesofa author
Hi |
|
![]() |
Alexey admin 10/9/2006 |
Hi, |
T
|
thesofa author 10/10/2006 |
well , its working, still in the testing stage tho, I may have a solution if you want it. |
![]() |
Sergey Kornilov admin 10/11/2006 |
Sure, when you have it ready feel free to share this code. |
T
|
thesofa author 10/11/2006 |
OK, here we go. if(function_exists("BeforeLogin")) if(!BeforeLogin(@$_POST["username"],@$_POST["password"])) $strSQL="select * from ".AddTableWrappers($cLoginTable)." where 1<0";
################################################################################ LDAP AUTHENTICATION MODIFICATION #################################################################################
if ($adldap -> user_ingroup($strlUsername,$ldap_group)){ # Group Authentication Only $ldap_auth = 1; } #Group Authentication Only} END OF MODIFICATION #################################################################################
$ldap_group ="usergroup"; # Specified group for group authentication holds the group for group membership checking. |
G
|
gdude66 10/18/2006 |
Great. |
T
|
thesofa author 10/18/2006 |
Great. So where do you add the bind and the dn? Does this work with active dirctory? Willing to test.
<?php /* PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY Version 1.5 Written by Scott Barnett email: scott@wiggumworld.com http://adldap.sourceforge.net/ Copyright © 2006 Scott Barnett I'd appreciate any improvements or additions to be submitted back to benefit the entire community <img src='https://asprunner.com/forums/file.php?topicimage=1&fieldname=reply&id=11936&image=1&table=forumreplies' class='bbc_emoticon' alt=':)' /> Works with both PHP 4 and PHP 5 The examples should be pretty self explanatory. If you require more information, please visit http://adldap.sourceforge.net/ 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, or (at your option) any later version. 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. **** 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. **** FUNCTIONS: authenticate($username,$password) Authenticate to the directory with a specific username and password user_info($user,$fields=NULL) Returns an array of information for a specific user user_groups($user,$recursive=NULL) Returns an array of groups that a user is a member off user_ingroup($user,$group,$recursive=NULL) Returns true if the user is a member of the group group_info($group) Returns an array of information for a specific group all_users($include_desc = false, $search = "", $sorted = true) Returns all AD users (expensive on resources) all_groups($include_desc = false, $search = "", $sorted = true) Returns all AD groups (expensive on resources) */ // Different type of accounts in AD define ('ADLDAP_NORMAL_ACCOUNT', 805306368); define ('ADLDAP_WORKSTATION_TRUST', 805306369); define ('ADLDAP_INTERDOMAIN_TRUST', 805306370); define ('ADLDAP_SECURITY_GLOBAL_GROUP', 268435456); define ('ADLDAP_DISTRIBUTION_GROUP', 268435457); define ('ADLDAP_SECURITY_LOCAL_GROUP', 536870912); define ('ADLDAP_DISTRIBUTION_LOCAL_GROUP', 536870913); class adLDAP { // BEFORE YOU ASK A QUESTION, PLEASE READ THE FAQ // http://adldap.sourceforge.net/faq.php // You will need to edit these variables to suit your installation var $_account_suffix="@yourdomain.com"; var $_base_dn ="DC=domain,DC=coml"; // An array of domain controllers. Specify multiple controllers if you // would like the class to balance the LDAP queries amongst multiple servers var $_domain_controllers = array ("server1.domain.com"); // optional account with higher privileges for searching var $_ad_username="topnotchbloke"; var $_ad_password="putarealpasswordinhere"; // AD does not return the primary group. http://support.microsoft.com/?kbid=321360 // This tweak will resolve the real primary group, but may be resource intensive. // 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 bollocks the results var $_real_primarygroup=true; // 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 var $_recursive_groups=true; // You should not need to edit anything below this line //**** ** //other variables var $_user_dn; var $_user_pass; var $_conn; var $_bind; // default constructor function adLDAP(){ //connect to the LDAP server as the username/password $this->_conn = ldap_connect($this->random_controller()); ldap_set_option($this->_conn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($this->_conn, LDAP_OPT_REFERRALS, 0); //disable plain text passwords return true; } // default destructor function __destruct(){ ldap_close ($this->_conn); } function random_controller(){ //select a random domain controller mt_srand(doubleval(microtime()) 100000000); return ($this->_domain_controllers[array_rand($this->_domain_controllers)]); } // authenticate($username,$password) // Authenticate to the directory with a specific username and password // Extremely useful for validating login credentials function authenticate($username,$password){ //validate a users login credentials $returnval=false; if ($username!=NULL && $password!=NULL){ //prevent null bind $this->_user_dn=$username.$this->_account_suffix; $this->_user_pass=$password; $this->_bind = @ldap_bind($this->_conn,$this->_user_dn,$this->_user_pass); if ($this->_bind){ $returnval=true; } } return ($returnval); } // rebind() // Binds to the directory with the default search username and password // specified above. function rebind(){ //connect with another account to search with if necessary $ad_dn=$this->_ad_username.$this->_account_suffix; $this->_bind = @ldap_bind($this->_conn,$ad_dn,$this->_ad_password); if ($this->_bind){ return (true); } return (false); } // user_info($user,$fields) // Returns an array of information for a specific user function user_info($user,$fields=NULL){ if ($user!=NULL){ if ($this->_ad_username!=NULL){ $this->rebind(); } //bind as a another account if necessary if ($this->_bind){ //perform the search and grab all their details $filter="samaccountname=".$user; if ($fields==NULL){ $fields=array("samaccountname","mail","memberof","department","displayname","telephonenumber","primarygroupid"); //$fields=array(""); } $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $sr); // AD does not return the primary group in the ldap query, we may need to fudge it if ($this->_real_primarygroup){ $entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]); } else { $entries[0]["memberof"][]="CN=Domain Users,CN=Users,".$this->_base_dn; } //echo ("<pre>"); print_r($entries); $entries[0]["memberof"]["count"]++; return ($entries); } } return (false); } // user_groups($user) // Returns an array of groups that a user is a member off function user_groups($user,$recursive=NULL){ if ($this->_ad_username!=NULL){ $this->rebind(); } //bind as a another account if necessary if ($recursive==NULL){ $recursive=$this->_recursive_groups; } if ($this->_bind){ //search the directory for their information $info=@$this->user_info($user,array("memberof")); //echo ("<pre>"); print_r($info); $groups=$info[0]["memberof"]; //presuming the entry returned is our guy (unique usernames) $group_array=$this->nice_names($groups); if ($recursive){ foreach ($group_array as $id => $group_name){ $extra_groups=$this->recursive_groups($group_name); $group_array=array_merge($group_array,$extra_groups); } } return ($group_array); } return (false); } // user_ingroup($user,$group) // Returns true if the user is a member of the group function user_ingroup($user,$group,$recursive=NULL){ if ($recursive==NULL){ $recursive=$this->_recursive_groups; } if (($user!=NULL) && ($group!=NULL)){ if ($this->_ad_username!=NULL){ $this->rebind(); } //bind as a another account if necessary if ($this->_bind){ $groups=$this->user_groups($user,array("memberof"),$recursive); if (in_array($group,$groups)){ return (true); } } } return (false); } function recursive_groups($group){ $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); } } return ($ret_groups); } // take an ldap query and return the nice names, without all the LDAP prefixes (eg. CN, DN) function nice_names($groups){ $group_array=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); $group_array[]=substr($bits[0],3,(strlen($bits[0])-3)); } } return ($group_array); } function group_cn($gid){ if ($this->_ad_username!=NULL){ $this->rebind(); } //bind as a another account if necessary // coping with AD not returning the primary group // 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 <img src='https://asprunner.com/forums/file.php?topicimage=1&fieldname=reply&id=11936&image=2&table=forumreplies' class='bbc_emoticon' alt=':)' /> // this way is resource intensive and generally a pain in the @#%^ $r=false; if ($this->_bind){ $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]; $i=$entries["count"]; } } } return ($r); } // group_info($group_name,$fields=NULL) // Returns an array of information for a specified group function group_info($group_name,$fields=NULL){ if ($this->_ad_username!=NULL){ $this->rebind(); } //bind as a another account if necessary if ($this->_bind){ //escape brackets $group_name=str_replace("(","\(",$group_name); $group_name=str_replace(")","\)",$group_name); $filter="(&(objectCategory=group)(name=".$group_name."))"; //echo ($filter." "); if ($fields==NULL){ $fields=array("member","memberof","cn","description","distinguishedname","objectcategory","samaccountname"); } $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields); $entries = ldap_get_entries($this->_conn, $sr); //print_r($entries); return ($entries); } return (false); } function all_users($include_desc = false, $search = "", $sorted = true){ // Returns all AD users if ($this->_ad_username!=NULL){ $this->rebind(); } //bind as a another account if necessary if ($this->_bind){ $users_array = array(); //perform the search and grab all their details $filter = "(&(objectClass=user)(samaccounttype=". ADLDAP_NORMAL_ACCOUNT .")(objectCategory=person)(cn=$search))"; $fields=array("samaccountname","displayname"); $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( $include_desc && strlen($entries[$i]["displayname"][0]) > 0 ) $users_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["displayname"][0]; else if( $include_desc ) $users_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["samaccountname"][0]; else array_push($users_array, $entries[$i]["samaccountname"][0]); } if( $sorted ){ asort($users_array); } return ($users_array); } return (false); } function all_groups($include_desc = false, $search = "", $sorted = true){ // Returns all AD groups if ($this->_ad_username!=NULL){ $this->rebind(); } //bind as a another account if necessary if ($this->_bind){ $groups_array = array(); //perform the search and grab all their details $filter = "(&(objectCategory=group)(samaccounttype=". ADLDAP_SECURITY_GLOBAL_GROUP .")(cn=$search))"; $fields=array("samaccountname","description"); $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( $include_desc && strlen($entries[$i]["description"][0]) > 0 ) $groups_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["description"][0]; else if( $include_desc ) $groups_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["samaccountname"][0]; else array_push($groups_array, $entries[$i]["samaccountname"][0]); } if( $sorted ){ asort($groups_array); } return ($groups_array); } return (false); } } // End class ?>
|
G
|
gdude66 10/20/2006 |
Many, many thanks. Great job. |
G
|
gdude66 11/3/2006 |
Update to LDAP // username and password are stored in the database $conn=db_connect(); $strUsername = (string)@$_POST["username"]; $strPassword = (string)@$_POST["password"];
// username and password are stored in the database $conn=db_connect(); $strUsername = (string)@$_POST["username"]; $strPassword = (string)@$_POST["password"]; [color=#CC0000]$strlPassword = $_POST["password"];
|
T
|
thesofa author 11/3/2006 |
Thanks for pointing out my omission, I hope no-one has given up with LDAP due to my laxness? |