JD* Posted June 2, 2008 Share Posted June 2, 2008 Hello all, I'm trying to work with a flexible LDAP setup for logging in to alternate servers. I have the code working for logging in with an ID number, but I'm trying to get it working with a username. I have a set of code that shows me the LDAP attributes on my server, but so far I can't get the cn (as username) to work. The following is the code that I'm using, hopefully it'll help: $connect=ldap_connect($server) or die("Could not find server"); ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); $bind = ldap_bind($connect, (is_numeric($username) ? "uid" : "cn")."=$username,$dn","$password"); if($bind == 1) { return 1; } else { return 0; } ldap_unbind($connect); Any help would be greatly appreciated. Quote Link to comment Share on other sites More sharing options...
rhodesa Posted June 2, 2008 Share Posted June 2, 2008 Well, the DN for someone can only be one thing (I am guessing the uid one). If you want to do it off CN, you will have to do a ldap_search first to find the entry, pull it's DN, then do the bind. Quote Link to comment Share on other sites More sharing options...
JD* Posted June 2, 2008 Author Share Posted June 2, 2008 Right now the $dn variable is set to be static, so I'm not too worried about that, I'm more concerned with being able to use a user's name. I'm just not sure how to go about that. As it stands, we're using OS X servers as our LDAP, so their name is "lastname, firstname", but their short name is their ID, so they can log into a computer using either, so I'd like to make it so that they can log into our website using either. Quote Link to comment Share on other sites More sharing options...
rhodesa Posted June 3, 2008 Share Posted June 3, 2008 well, your code would look something like this: <?php $connect=ldap_connect($server) or die("Could not find server"); ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); $name = 'lastname, firstname'; //This is set from your login form $sr=ldap_search($connect, $dn, 'cn='.$name,array()); if(ldap_count_entries($connect,$sr) !== 1) die("Too many users match"); $user_dn = ldap_get_dn($connect,ldap_first_entry($connect,$sr)) or die("Could not get users dn"); return ldap_bind($connect, $dn, $password); ?> Quote Link to comment Share on other sites More sharing options...
dmccabe Posted June 3, 2008 Share Posted June 3, 2008 I have been messing with ldap authentication for the last couple of months (on and off) and this works as basic authentication: <?php session_start(); $ldap_host = "ZYX.com; // domain name goes here eg: XYZ.com $base_dn = "OU=basedn, DC=XYZ, DC=com"; // replace "basedn" with the lowest branch where your users are & XYZ with your domain $_session['ldapname'] = $_GET['ldapname']; $ldapname = $_GET['ldapname']."@XYZ.com"; // domain name goes here: eg: @XYZ.com $ldappass = $_GET['ldappass']; if (!$ldappass) { ?> Please login below with your windows/citrix username and password! <form method="GET" action="<?php echo $PHP_SELF; ?>" name="login"> <table> <tr> <td>Username:</td> <td><input type="text" name="ldapname"></td> <td><a href=".." title="Click for help on this item"><strong>?</strong></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="ldappass"></td> <td><a href=".." title="Click for help on this item"><strong>?</strong></td> </tr> <tr> <td colspan="2"><input type="submit" value="Login" name="submit"></td> </tr> </table> </form> <?php } else { /*echo 'name: '.$ldapname; echo '<br />pass: '.$ldappass;*/ $connect = ldap_connect( $ldap_host, $ldap_port) or exit(">>Could not connect to LDAP server<<"); //for win2003 ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); //for win2003 ldap_set_option($connect, LDAP_OPT_REFERRALS, 0); $bind = ldap_bind($connect, $ldapname, $ldappass); if (!$bind) { echo 'Invalid username/password.... try again'; } else { print $_session['ldapname']; } } ?> hope it helps Quote Link to comment Share on other sites More sharing options...
JD* Posted June 4, 2008 Author Share Posted June 4, 2008 I got it figured out, thanks to all of your suggestions. What I do now is, when they submit their credentials, I do a search based on whatever it is they submit (ID Number OR Common Name). Then I pull their actual UID, unbind, and then rebind with the UID and password. This way, at one building where the UID is lastnamefirstinitial, and another where it's firstname.lastname and so on, I can use the same code and just toss in the proper DN. Following is the function I made tot allow this: function ldap_auth2($server=NULL, $username=NULL, $password=NULL, $dn=NULL) { error_reporting(0); // Surpress the error message when an account fails to bind $ds=ldap_connect($server); // must be a valid LDAP server! ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // Set our protocol or else this won't work // Search the server for user with the information they submitted if ($ds) { $r=ldap_bind($ds); $sr=ldap_search($ds,$dn, (is_numeric($username) ? "uidnumber=" : "cn=").$username ); } $ldapResults = ldap_get_entries($ds, $sr); $username = "uid=".$ldapResults[0]['uid'][0]; // Get their UID ldap_unbind($ds) // close this connection $connect=ldap_connect($server) or die("Could not find server"); ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); // The above is anonymous, but we can only guarantee access if they can rebind to the server with the uid and password. if(ldap_bind($connect, $username.",".$dn, $password) == 1) { return 1; } else { return 0; }; ldap_unbind($connect); } And then the item that calls the function works like this: case "Log In": //Do LDAP login if(ldap_auth2('my.server.com', $_POST['username'], $_POST['password'], "cn=users,dc=my,dc=server,dc=com") ==1) { echo "You did it!"; } else { echo "You didn't do it"; } Thanks guys! Quote Link to comment Share on other sites More sharing options...
rhodesa Posted June 4, 2008 Share Posted June 4, 2008 The only thing I would do in addition, is provide better error reporting (which you are probably going to get to eventually). Was the user not found? Was it a bad password? Are there more then one accounts with the same CN (which is possible)? Is the account locked (you can get this from the attributes of the entry)? Otherwise, code looks good Quote Link to comment Share on other sites More sharing options...
JD* Posted June 6, 2008 Author Share Posted June 6, 2008 The only thing I would do in addition, is provide better error reporting (which you are probably going to get to eventually). Was the user not found? Was it a bad password? Are there more then one accounts with the same CN (which is possible)? Is the account locked (you can get this from the attributes of the entry)? Otherwise, code looks good Yeah, in my production version there is my error display function to help them figure out what went wrong. In our future, as we transition from multiple login servers to one master, we'll be making it so that if a user logs in with their name and there is more than one user, we'll give them a list of names with IDs, which will then be used, with the password, to try and complete the bind. I don't know that we've used account locking so far, but that is also something interesting to look into. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.