diff --git a/include/class.auth.php b/include/class.auth.php
index 3071cd424b9493a19a137066dde710f1291178fb..9ff8cfd7ecf709c3246f356b8a5195a3c0ec1127 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -332,10 +332,40 @@ class AccessDenied {
  * Simple authentication backend which will lock the login form after a
  * configurable number of attempts
  */
-class AuthLockoutBackend extends AuthenticationBackend {
+abstract class AuthStrikeBackend extends AuthenticationBackend {
 
     function authenticate($username, $password=null) {
-        global $cfg, $ost;
+        return static::authStrike($username, $password);
+    }
+
+    function signOn() {
+        return static::authStrike('Unknown');
+    }
+
+    function login($user, $bk) {
+        return false;
+    }
+
+    function supportsAuthentication() {
+        return false;
+    }
+
+    function getAllowedBackends($userid) {
+        return array();
+    }
+
+    abstract function  authStrike($username, $password=null);
+}
+
+/*
+ * Backend to monitor staff's failed login attempts
+ */
+class StaffAuthStrikeBackend extends  AuthStrikeBackend {
+
+    function authstrike($username, $password=null) {
+        global $ost;
+
+        $cfg = $ost->getConfig();
 
         if($_SESSION['_staff']['laststrike']) {
             if((time()-$_SESSION['_staff']['laststrike'])<$cfg->getStaffLoginTimeout()) {
@@ -369,12 +399,49 @@ class AuthLockoutBackend extends AuthenticationBackend {
             $ost->logWarning('Failed staff login attempt ('.$username.')', $alert, false);
         }
     }
+}
+StaffAuthenticationBackend::register(StaffAuthStrikeBackend);
+
+/*
+ * Backend to monitor user's failed login attempts
+ */
+class UserAuthStrikeBackend extends  AuthStrikeBackend {
+
+    function authstrike($username, $password=null) {
+        global $ost;
+
+        $cfg = $ost->getConfig();
+
+        //Check time for last max failed login attempt strike.
+        if($_SESSION['_client']['laststrike']) {
+            if((time()-$_SESSION['_client']['laststrike'])<$cfg->getClientLoginTimeout()) {
+                $_SESSION['_client']['laststrike'] = time(); //renew the strike.
+                return new AccessDenied('You\'ve reached maximum failed login attempts allowed.');
+            } else { //Timeout is over.
+                //Reset the counter for next round of attempts after the timeout.
+                $_SESSION['_client']['laststrike'] = null;
+                $_SESSION['_client']['strikes'] = 0;
+            }
+        }
+
+        $_SESSION['_client']['strikes']+=1;
+        if($_SESSION['_client']['strikes']>$cfg->getClientMaxLogins()) {
+            $_SESSION['_client']['laststrike'] = time();
+            $alert='Excessive login attempts by a user.'."\n".
+                    'Login: '.$username.': '.$password."\n".
+                    'IP: '.$_SERVER['REMOTE_ADDR']."\n".'Time:'.date('M j, Y, g:i a T')."\n\n".
+                    'Attempts #'.$_SESSION['_client']['strikes'];
+            $ost->logError('Excessive login attempts (user)', $alert, ($cfg->alertONLoginError()));
+            return new AccessDenied('Access Denied');
+        } elseif($_SESSION['_client']['strikes']%2==0) { //Log every other failed login attempt as a warning.
+            $alert='Login: '.$username.': '.$password."\n".'IP: '.$_SERVER['REMOTE_ADDR'].
+                   "\n".'TIME: '.date('M j, Y, g:i a T')."\n\n".'Attempts #'.$_SESSION['_client']['strikes'];
+            $ost->logWarning('Failed login attempt (user)', $alert);
+        }
 
-    function supportsAuthentication() {
-        return false;
     }
 }
-AuthenticationBackend::register(AuthLockoutBackend);
+UserAuthenticationBackend::register(UserAuthStrikeBackend);
 
 
 class osTicketAuthentication extends StaffAuthenticationBackend {