The title says it all, this will allow you to restrict the access to a page or pages running php with access to LDAP. I’ve used this a few times for some internal things we don’t want everyone getting access to or similar scenarios. As always if it works for you, please leave a comment and if it doesn’t please leave a question and I’ll see what I can do to help you out.
Enable LDAP
First thing you’ll need to do is to install ldap for php & enable the needed mods, ldap.load & authnz_ldap.load
On Ubuntu:
apt-get update
apt-get install php5-ldap
cd /etc/apache2/mods-enabled
ln -s ../mods-available/ldap.load ldap.load
ln -s ../mods-available/authnz_ldap.load authnz_ldap.load
apache2ctl graceful
Pages
Now all you need to do is create the login page and the configuration file.
Login Page (login.php):
<?php // http://sudobash.net/?p=736 session_start); session_destroy); if(!isset($_POST['user'])){?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> <!-- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> --> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>LOGIN TITLE</title> </head> <body> <table align="center" height="200px" id="content"> <tr> <td valign="middle"> <h2>TITLE Login</h2> <form action="login.php" method="POST"> <tt>RAC Username:</tt> <input type="text" name="user" size="30" /><br /> <tt>RAC Password:</tt> <input type="password" name="password" size="30" /> <input type="submit" value="Login" name="submit" /> </form> </td> </tr> </table> </body> </html> <?}?> <?if(isset($_POST['user'])){?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> <!-- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> --> <head> <title>LOGIN RESULTS TITLE</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body> <?php include 'conf.php'; // Don't display the warnings - we are already setup to annoy the user ini_set( "display_errors", 0); // No funny stuff! $user = htmlspecialchars($_POST['user']); $user = explode(" ", $user); $user = $user[0]; $user = preg_replace("/[^a-zA-Z0-9_]/", "", $user); $filter = "admin=" . $user; // Connect to the LDAP server. $ldapconn = ldap_connect($server, $port) or die("Could not connect to " . $server . ":" . $port . "."); // Bind with rootreader to the LDAP server to search and retrieve DN. $ldapbind = ldap_bind($ldapconn) or die("Could not bind - contact admin@example.com"); $result = ldap_search($ldapconn,$basedn,$filter) or die ("Search error."); $entries = ldap_get_entries($ldapconn, $result); $binddn = $entries[0]["dn"]; // Bind again using the DN retrieved. If this bind is successful, // then the user has managed to authenticate. $ldapbind = ldap_bind($ldapconn, $binddn, $_POST['password']); if ($ldapbind) { echo "<center><h2>Successful authentication for <span style='color: #000;'>" . $user . "</span></center>"; ?> <table align="center" height="200px" id="content"> <tr> <td valign="middle"> <form action="restricted.php" method="post"> <input type="hidden" name='user' value="<?=$user;?>" > <input type="submit" value="Great, Let's go!" > </form> </td> </tr> </table> <? } else { echo "<center><h2>Failed authentication for <span style='color: #000;'>" . $user . "</span><br /><br /> <a href='login.php'>Try again</a></center>"; } ldap_close($ldapconn); ?> </body> </html> <?}?>
Configuration file (conf.php):
<?php // Configuration file for PHP/LDAP authentication $server = "10.1.1.154"; // YOUR ldap server IP $port = 389; // Default LDAP port when you are not root $basedn = "ou=admins,o=LDAPROOT"; // Make sure to change to match your object. ?>
Well thats all nice and appears to be working but we are still able to go directly to the page we want, we’ll call it “restricted.php”
So within our restricted.php we’ll need to have the following code
Restricted Page (restricted.php):
<?php if(!isset($_POST['user'])) { die('Direct access not permitted, Please visit <a href="index.php">Login page</a>'); } ?>
Results
Then if you have a successful login you will see
You are logged in!
Otherwise if you try to access the file directly you will see
Direct access not permitted, Please visit Login page
Thats all there is to it!
This is a modified version of someone else’s code. Unfortunately I do not have a link to that code anymore only the original files (which also don’t list the site they came from). If I ever find it, I’ll post it here.
Scott,
Thanks for posting this. I have been looking for a graceful ldap solution for time when I MUST deal with a IIS environment or at least let windoze talk to my apache.
I changed “displayed errors” to a 1 and I cant make heads or tails of this the error.
Warning: ldap_search() [function.ldap-search]: Search: Operations error in path/to/my/login.php
$result = ldap_search($ldapconn, $basedn, $filter) or die ("Search error.");
is the line it refers to. I did change my filter to be “sAMAccountName” instead of admin. Any thoughts?
Thanks!
Jason,
If its that line then it has to be something with one of the following variables/settings:
$ldapconn
$basedn
$filter
$server
$port
Unfortunately I can’t help too much beyond that since its on a system I can’t troubleshoot. Are you certain all of those got updated correctly to what you are using locally? You aren’t using a non-default port perhaps?
No we use the default port of 389. and I have reconfig for my ip. I changed the $filter to
$filter="sAMAccountName=".$user;
since my object use sam and not admin. must be a crazy firewall issue.I’m having trouble with the ldap_search line. It keeps giving me the search error message. I think I might be messing up with the basedn variable in the conf file. Do you have any tips for correct usage of this?
Try printing out the result of each of your variables that $result is using. Do you get the expected results?
I need to add SSL and a proxy user to bind to the LDAP directory. Where would I incorporate this?
Sorry, never had to do that so I’m not sure on that one.
am i the only one that has had a problem with this script… I have tried several times and several different way to get this to work but i keep getting an unexpected end of file message when i load the page.