PHP/MySQL/LDap authentication





6
Date Submitted Sun. Sep. 24th, 2006 5:23 PM
Revision 1 of 1
Helper kahotep
Tags "authentication" | "ldap" | "mysql" | "php"
Comments 1 comments
The following program was written for my company's time keeping system which utilizes an LDAP database for authentication and a MySQL database for time-keeping, account access control, etc.

If a user has >= 5 unsuccessful logins, it locks the account for 5 minutes. Once a successful LDAP bind has occured, the $_SESSION vars are set and the authorization process is bypassed until the user logs out or the session expires.

<?
// file:        authorization.php
// purpose: authorization modules
class authorize {

        var $issuccessfulLogin;
        var $manuallyLocked;
        var $timeLocked;

        // purpose: constructor
        function authorize() {  }

        // purpose: bind with LDAP to determine LDAP authorization status
        function LDAP_authenticate( $username, $password, $domain) {
                require('conf/ldap.conf.php');
                $ds = @ldap_connect( $ldapconfig[ 'host' ], $ldapconfig[ 'port' ] );

                if( ! $ds ) return false;

                ldap_set_option( $ds, LDAP_OPT_PROTOCOL_VERSION, 3 );

                $dn = $ldapconfig[ 'prepend' ] . $username . "," . $ldapconfig[ 'basedn' ];

                // bind with ldap to determine LDAP authentication status
                $LDAP_bind_status =
                        ldap_bind($ds,$ldapconfig[ 'prepend' ].$username.",".$ldapconfig['basedn'],$password);

                ldap_close();

                if( $LDAP_bind_status )
                        return true;
                else
                        return false;
        }

        // purpose: determine whether or not the user is authorized or their account is locked
        //                      lock or unlock the account if necessary
        function getAuthStatus( $username, $password, $domain ) {
                if( ! $username || $username == '' )
                        $error  =       'must enter username';
                else if( ! $password || $password == '' )
                        $error  =       'must enter password';
                else if( ! $domain || $domain == '' )
                        $error  =       'must enter domain';

                if( ! $_SESSION['logged_in'] )
                {
                        if( $this->getLockStatus( $username ) ) {
                                $this->unsuccessfulLogin( $username );
                                return false;
                        }
                        else if( ! $this->LDAP_authenticate( $username, $password, $domain) ) {
                                $this->unsuccessfulLogin( $username );
                                return false;
                        }
                        else {
                                $this->successfulLogin( $username );
                                return true;
                        }
                }
                session_start();
                return true;
        }

        // purpose: determine whether or not the user is locked out
        //                      returns true if account is locked, false if unlocked
        function getLockStatus( $username ) {
                if( ! $username || $username == '' )
                        return false;

                $current_time   =       mktime( date('h'), date('i'), date('s'), date('m'), date('d'), date('Y') );
                $five_minutes   =       300; // number of seconds in five minutes

                // query the database for lock status and time locked
                require('conf/mysql.conf.php');
                $query          =       "SELECT is_timesheet_locked, lock_time FROM employee WHERE uid='$username';";
                $result         =       mysql_query( $query );
                $lock_hash      =       mysql_fetch_assoc( $result );

                // if a manual account lock is enabled, account status is LOCKED
                if( $lock_hash['is_timesheet_locked'] == 1 )
                {       $this->manuallyLocked   =       true;   return true;    }
                else
                {       $this->manuallyLocked   =       false;                                  }

                // if an automatic time lock is set, deny access
                if( isset( $lock_hash['lock_time'] ) ) {

                        // has 10 minutes elapsed since locking?
                        if( $lock_hash['lock_time'] + $five_minutes > $current_time )
                        {       $this->timeLocked       =       true;   return true;    }       // account is LOCKED
                        else
                        {       $this->timeLocked       =       falsereturn false;   }       // account is UNLOCKED

                }
                // if no time lock is enabled, account status is UNLOCKED
                else
                {       $this->timeLocked       =       falsereturn false;           }
        }

        // purpose: lock the account of an employee
        function lockAccount( $username ) {
                if( ! $username || $username == '' )
                        return false;


                $current_time   =       mktime( date('h'), date('i'), date('s'), date('m'), date('d'), date('Y') );
                $query  =       "UPDATE employee SET lock_time = $current_time " .
                                        "WHERE uid = '$username' AND lock_time IS NULL;";
                mysql_query( $query );
        }

        // purpose: add unsuccessful login attempt to the tally for this user, lock the account if necessary
        function unsuccessfulLogin( $username ) {
                if( ! $username || $username == '' )
                        return false;

                $this->isSuccessfulLogin        =       false;

                require('conf/mysql.conf.php');
                $query  =       "UPDATE employee SET unsuccessful_attempts = unsuccessful_attempts + 1 " .
                                        "WHERE uid = '$username';";
                mysql_query( $query );

                $query  =       "SELECT unsuccessful_attempts FROM employee WHERE uid = '$username';";
                $result =       mysql_query( $query );
                $row    =       mysql_fetch_row( $result );
                $num_attempts   =       $row[0];

                if( $num_attempts >= 3 )
                        $this->lockAccount( $username );
        }

        // purpose: reset the tally for unsuccessful login attempts for this user
        function successfulLogin( $username ) {
                if( ! $username || $username == '' )
                        return false;

                $this->isSuccessfulLogin        =       true;

                require('employee_data.php');
                $employee_data  =       new employee_data($username);
                $employee_data->saveAll_toSession();

                require('conf/mysql.conf.php');
                $query  =       "UPDATE employee SET unsuccessful_attempts = 0, lock_time=NULL " .
                                        "WHERE uid='$username';";
                mysql_query( $query );
        }

        // purpose: get the current status message for this account, if any
        function getMessage( $username ) {
                if( ! $username || $username == '' )
                        return NULL;

                if( $this->manuallyLocked == true )
                {       return "This account is locked, contact administrator for assistance"}
                else if( $this->timeLocked == true )
                {       return "Due to excessive login attempts, this account is temporarily locked. Try again in a few minutes."; }
                else if( $this->isSuccessfulLogin == false ) {
                        return "Invalid username or password.";
                }
        }

        // purpose: remove all session data for this session
        function logout() {
                $_SESSION['logged_in'] = false;
                session_destroy();
        }
}
?>
 

chris c

Comments

Comments Where's the rest?
Wed. Nov. 29th, 2006 3:34 PM    Newbie cdukes

Voting