I'm at my end with this, because I know this was working when I first started this project. I get all the backend stuff done and am ready to publish, then the damn auth doesn't work!:mad::mad: I am able to login without a password! As long as my username is in the LDAP database, it lets me in. I know this used to work, I'm royally confused.

I grabbed an iteration of this of a thread on this forum http://www.phpbuilder.com/board/archive/index.php/t-10257921.html

Here is my interpretation:

<?php
if( isset($_POST['login']) && isset($_POST['password']) )
{
    //LDAP stuff here.
    $username = trim($_POST['login']);
    $password = trim($_POST['password']);
	$ldaphost = "ldap.server"; 


$ds = ldap_connect($ldaphost);

//Can't connect to LDAP.
if( !'ds' )
{
    echo "Error in contacting the LDAP server -- contact ";
    echo "the Helpdesk  (Debug 1)";
    exit;
}

//Connection made -- bind anonymously and get dn for username.
$bind = @ldap_bind($ds);

//Check to make sure we're bound.
if( !'bind' )
{
    echo "Anonymous bind to LDAP FAILED.  Contact the Helpdesk. (Debug 2)";
    exit;
}

$search = ldap_search($ds, "ou=x,dc=x,dc=x", "uid=$username");


//Make sure only ONE result was returned -- if not, they might've thrown a * into the username.  Bad user!
if( ldap_count_entries($ds,$search) != 1 )
{
    echo "Error processing username -- please try to login again. (Debug 3)";
    redirect("login.php");
    exit;
}

$info = ldap_get_entries($ds, $search);

//Now, try to rebind with their full dn and password.
$bind = @ldap_bind($ds, $info[0][dn], $password);
if( !$bind || !isset($bind))
{
    echo "Login failed -- please try again. (Debug 4)";
    redirect("login.php");
    exit;
}

//Now verify the previous search using their credentials.
$search = ldap_search($ds, "ou=x,dc=x,dc=x", "uid=$username");

$info = ldap_get_entries($ds, $search);

if( $username == $info[0]['uid'][0] )
{

    $_SESSION['username'] = $username;
    $_SESSION['fullname'] = $info[0]['cn'][0];
	$_SESSION['affiliation'] = $info[0]['edupersonprimaryaffiliation'][0];
	header('Location: https://www/success.php');
    exit;
}
else
{
    echo "Login failed -- please try again." ;
    exit;
}
ldap_close($ds);
exit;
}
?>

Any help in retaining my sanity is greatly appreciated!!!!

  • Dan

    I think you're making it too complicated. Why not just bind as the user? If it fails, you should get a message like, "Invalid credentials", but of course, you can trap that error.

    Here's the entirety of my LDAP login script and it works like a charm:

    // Authenticate through LDAP to mydomain.com...
    $login = $Username."@mydomain.com";
    $conn = ldap_connect("mydomain.com");
    $bind = ldap_bind($conn, $login, $password);
    $ldap_err = ldap_error($conn);
    
    // Redirect the user if authentication fails...
    if(! $bind)
      {
      // Log the error...
      $query = "INSERT INTO EventLog (event_id, long_text) VALUES (3, '$ldap_err for user $Username')";
      mysql_query($query, $link);
    
      // Kill session & LDAP link and redirect user...
      session_destroy();
      if(ldap_errno($conn) == 49)
        $ldap_err = "Username or password is incorrect.";
      ldap_close($conn);
    
      // The following is just my pre-login error-message/redirector function...
      goback($ldap_err, "login.php");
    
      // Just in case my function above fails, end script here...
      exit;
      }
    ldap_close($conn);

      Thanks ixalmida - I tried yours and couldn't get it to work. Then i tried to water my down to something minimal:

      <?php
      if( isset($_POST['login']) && isset($_POST['password']) )
      {
          //LDAP stuff here.
          $username = trim($_POST['login']);
          $password = trim($_POST['password']);
      	$ldaphost = "ldap.server.edu"; 
          $ds = ldap_connect($ldaphost);
      
      
      $search = ldap_search($ds, "ou=x,dc=x,dc=x", "uid=$username");
      
      $info = ldap_get_entries($ds, $search);
      
      //Now, try to rebind with their full dn and password.
      $bind = @ldap_bind($ds, $info[0][dn]);
      if( !$bind || !isset($bind))
      {
          echo "Login failed -- please try again. (Debug 4)";
          redirect("login.php");
      	include 'footer.php';
          exit;
      }
      
      else
      {
          echo "Login WORKED. MAYBE." ;
          exit;
      }
      
      exit;
      }
      ?>

      Two things I have noticed:

      1) the first statement that basically says to do this script if there is something in both the username and password field isn't working. I'm putting in just a username, and it runs the script.
      2) The bind I have is just completely ignoring the password field. I even remove the $password from it and it works. Does the bind statement not require a password to work? Seems that way.

      I would like to do yours, but I don't completely understand how. When you have this:

      $login = $username."@mydomain.com";

      You want me just to use the domain name, not the ldap address? I'm sorry, I know little about LDAP and not sure how my network login @mydomain.com will resolve to LDAP.

      Thanks again for your assistance!

      • Dan

        Your question is valid - yes, you CAN bind without the password, but you'll need the password later to do any operations on LDAP. However, you can authenticate using the bind statement IF you use the password. Just make sure you check username & password for empty strings before you attempt to use bind.

        I can't say for sure if you'll need the "@mydomain.com" added to the username. But if you're authenticating on a Windows network, it could be useful. Think about a Windows login - if you specify "@mydomain.com" after the username then the domain field gets grayed out and ignored. This is one method for logging into domains that aren't in a Win computer's domain list.

        Also bear in mind the assumption that "mydomain.com" will resolve to the proper LDAP server in DNS. You can check that with a ping command from the Linux console. If not, you can add the hostname/IP of the LDAP server into the Linux hosts file.

          We have a Solaris server for both LDAP and the web server.

          Alright, well I do check for empty strings when I have the "if( isset($POST['login']) && isset($POST['password']) )" statement, correct? How do I MAKE it use both the username and password to authenticate to LDAP? Even if the isset statement works, that just means there is something in the field, it doesn't say - Hey, this password goes with this login, so therefore access this file.

          I'm sorry, I'm just confused. I am trying to reference this pearl script as well, this is what we use to authenticate for iTunesU:

          # Check ldap
          
          my $user=$q->param('user');
          my $password = $q->param('pw');
          
          my $ldap = Net::LDAP->new('ldap.server.edu');
          my $login = $ldap->bind("uid=".$user.",ou=x,dc=x,dc=edu",password=>$password);
          
          if ($login->is_error()) {
          	# redirect to the login page
          	print $q->redirect('https://www.x.edu/itunesu_login/error.html');
          };
          
          #
          # Harvest information from LDAP server
          #
          my $results = $ldap->search(base=>"ou=x,dc=x,dc=edu",scope=>'sub',filter=>"(uid=".$user.")");
          my @entries = $results->entries;
          
          $displayName  = $entries[0]->get_value('cn');
          $emailAddress = $entries[0]->get_value('mail');
          $username = $user;
          $userIdentifier = $entries[0]->get_value('uidnumber');
          $employeeType = $entries[0]->get_value('edupersonprimaryaffiliation');
          $employeeType = "Authenticated" if ($employeeType eq "");
          

          Thanks again for your reply. I'm just not getting it I guess. It really was working, I don't know what the $%#@ happened :mad:

          • Dan

            Something I noticed:

            danno74 wrote:

            1) the first statement that basically says to do this script if there is something in both the username and password field isn't working.

            That's not true. You only checked to see if the POST variable was set - not whether it was empty or not. (Hint: A POST'ed element with no value is still defined - it's just defined as NULL or an empty string.)

            Also, this comment:

                //Now, try to rebind with their full dn and password.
                $bind = @ldap_bind($ds, $info[0][dn]);

            is incorrect; you never try to use their password in the bind statement.

            Speaking of that line, why do you have the '@' error suppressor in there? To me, it should never be in your code because you're either a) debugging a problem (like we are now) and want as much information as you can get, or b) the script is in production, in which case display_errors should never be enabled since you should be logging them (and again, you'd want to see any new problems in the error log).

              I'm glad somebody was listening.

              Put another way:

              // Assuming your connection is correct...
              // The following statements return TRUE:
              $bind = ldap_bind($ldapconn, $username);
              $bind = ldap_bind($ldapconn, $username, $correct_password);
              
              // This statement returns FALSE:
              $bind = ldap_bind($ldapconn, $username, $incorrect_password);

                SIDE NOTE: It is important to handle potential pre-authentication errors before you even get to the LDAP stuff.

                Here is what I do before I get to ldap_bind():

                // Make sure Username & password are posted...
                if(!(isset($_POST['Username']) && isset($_POST['password'])))
                  // Redirect with error - "missing input"
                
                $Username = clean_string(strip_tags($_POST['Username']));
                $password = clean_string(strip_tags($_POST['password']));
                
                // Check for valid username...
                if(strlen($Username) < 4 || strlen($Username) > 25)
                  // CODE:  Redirect with error - "invalid username"
                
                // Check for valid password...
                if(strlen($password) < 6 || strlen($password) > 25)
                  // CODE:  Redirect with error - "invalid password"
                
                // Check to see if user is registered...
                  // CODE: "user not registered" if user isn't found in database
                
                // Now check LDAP...
                  Write a Reply...