windows-nt/Source/XPSP1/NT/ds/security/gina/msgina/lockout.c

191 lines
4.8 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/****************************** Module Header ******************************\
* Module Name: lockout.c
*
* Copyright (c) 1991, Microsoft Corporation
*
* Implements account lockout support functions.
*
* History:
* 05-27-92 Davidc Created.
\***************************************************************************/
#include "msgina.h"
#pragma hdrstop
#define INDEX_WRAP(i) ((i + LOCKOUT_BAD_LOGON_COUNT) % LOCKOUT_BAD_LOGON_COUNT)
#define TERMSERV_EVENTSOURCE L"TermService"
// Also defined in icaevent.mc
#define EVENT_EXCEEDED_MAX_LOGON_ATTEMPTS 0x400003F4L
/***************************************************************************\
* FUNCTION: LockoutInitialize
*
* PURPOSE: Initializes any data used by lockout functions
*
* RETURNS: TRUE
*
* HISTORY:
*
* 05-27-92 Davidc Created.
*
\***************************************************************************/
BOOL
LockoutInitialize(
PGLOBALS pGlobals
)
{
PLOCKOUT_DATA pLockoutData = &pGlobals->LockoutData;
pLockoutData->ConsecutiveFailedLogons = 0;
pLockoutData->FailedLogonIndex = 0;
return(TRUE);
}
/***************************************************************************\
* FUNCTION: LockoutHandleFailedLogon
*
* PURPOSE: Implements account lockout restrictions if failed logons
* have exceeded a limit frequency.
* Account lockout is implemented by imposing an additional delay
* in a failed logon when the various failed logon conditions are met.
*
* RETURNS: TRUE
*
* NOTES: This routine may not return for some time. (typically 30 seconds)
*
* HISTORY:
*
* 05-27-92 Davidc Created.
*
\***************************************************************************/
BOOL
LockoutHandleFailedLogon(
PGLOBALS pGlobals
)
{
PLOCKOUT_DATA pLockoutData = &pGlobals->LockoutData;
ULONG Index = pLockoutData->FailedLogonIndex;
//
// Up our bad logon count
//
pLockoutData->ConsecutiveFailedLogons ++;
//
// See if we have reached our bad logon limit.
//
if (pLockoutData->ConsecutiveFailedLogons > LOCKOUT_BAD_LOGON_COUNT) {
ULONG ElapsedSecondsFirstFailure;
ULONG ElapsedSecondsNow;
BOOLEAN Result;
if ((NtCurrentPeb()->SessionId != 0) && (!IsActiveConsoleSession())) {
//
// Forcibly terminate the remote session is we exceed the maximum
// allowed failed logon attempts
//
HANDLE hEventLogSource= RegisterEventSource(NULL,TERMSERV_EVENTSOURCE);
if (hEventLogSource != NULL)
{
PWSTR Strings[ 1 ];
Strings[0] = pGlobals->MuGlobals.ClientName;
ReportEvent(hEventLogSource,
EVENTLOG_INFORMATION_TYPE,
0,
EVENT_EXCEEDED_MAX_LOGON_ATTEMPTS,
NULL,
1,
0,
Strings,
NULL);
DeregisterEventSource(hEventLogSource);
}
TerminateProcess( GetCurrentProcess(), 0 );
}
//
// Limit the count so we don't have any wrap-round problems
// (32-bits - that's a lot of failed logons I know)
//
pLockoutData->ConsecutiveFailedLogons = LOCKOUT_BAD_LOGON_COUNT + 1;
//
// If the first logon in our list occurred too recently, insert
// the appropriate delay
//
Result = RtlTimeToSecondsSince1980(&pLockoutData->FailedLogonTimes[Index],
&ElapsedSecondsFirstFailure);
ASSERT(Result);
Result = RtlTimeToSecondsSince1980(&pGlobals->LogonTime,
&ElapsedSecondsNow);
ASSERT(Result);
if ((ElapsedSecondsNow - ElapsedSecondsFirstFailure) < LOCKOUT_BAD_LOGON_PERIOD) {
SetupCursor(TRUE);
Sleep(LOCKOUT_BAD_LOGON_DELAY * 1000);
SetupCursor(FALSE);
}
}
//
// Add this failed logon to the array
//
pLockoutData->FailedLogonTimes[Index] = pGlobals->LogonTime;
pLockoutData->FailedLogonIndex = INDEX_WRAP(pLockoutData->FailedLogonIndex+1);
return(TRUE);
}
/***************************************************************************\
* FUNCTION: LockoutHandleSuccessfulLogon
*
* PURPOSE: Resets account lockout statistics since a successful logon occurred.
*
* RETURNS: TRUE
*
* HISTORY:
*
* 05-27-92 Davidc Created.
*
\***************************************************************************/
BOOL
LockoutHandleSuccessfulLogon(
PGLOBALS pGlobals
)
{
//
// Reset our bad logon count
//
pGlobals->LockoutData.ConsecutiveFailedLogons = 0;
return(TRUE);
}