Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
4.8 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: lockout.c
  3. *
  4. * Copyright (c) 1991, Microsoft Corporation
  5. *
  6. * Implements account lockout support functions.
  7. *
  8. * History:
  9. * 05-27-92 Davidc Created.
  10. \***************************************************************************/
  11. #include "msgina.h"
  12. #pragma hdrstop
  13. #define INDEX_WRAP(i) ((i + LOCKOUT_BAD_LOGON_COUNT) % LOCKOUT_BAD_LOGON_COUNT)
  14. #define TERMSERV_EVENTSOURCE L"TermService"
  15. // Also defined in icaevent.mc
  16. #define EVENT_EXCEEDED_MAX_LOGON_ATTEMPTS 0x400003F4L
  17. /***************************************************************************\
  18. * FUNCTION: LockoutInitialize
  19. *
  20. * PURPOSE: Initializes any data used by lockout functions
  21. *
  22. * RETURNS: TRUE
  23. *
  24. * HISTORY:
  25. *
  26. * 05-27-92 Davidc Created.
  27. *
  28. \***************************************************************************/
  29. BOOL
  30. LockoutInitialize(
  31. PGLOBALS pGlobals
  32. )
  33. {
  34. PLOCKOUT_DATA pLockoutData = &pGlobals->LockoutData;
  35. pLockoutData->ConsecutiveFailedLogons = 0;
  36. pLockoutData->FailedLogonIndex = 0;
  37. return(TRUE);
  38. }
  39. /***************************************************************************\
  40. * FUNCTION: LockoutHandleFailedLogon
  41. *
  42. * PURPOSE: Implements account lockout restrictions if failed logons
  43. * have exceeded a limit frequency.
  44. * Account lockout is implemented by imposing an additional delay
  45. * in a failed logon when the various failed logon conditions are met.
  46. *
  47. * RETURNS: TRUE
  48. *
  49. * NOTES: This routine may not return for some time. (typically 30 seconds)
  50. *
  51. * HISTORY:
  52. *
  53. * 05-27-92 Davidc Created.
  54. *
  55. \***************************************************************************/
  56. BOOL
  57. LockoutHandleFailedLogon(
  58. PGLOBALS pGlobals
  59. )
  60. {
  61. PLOCKOUT_DATA pLockoutData = &pGlobals->LockoutData;
  62. ULONG Index = pLockoutData->FailedLogonIndex;
  63. //
  64. // Up our bad logon count
  65. //
  66. pLockoutData->ConsecutiveFailedLogons ++;
  67. //
  68. // See if we have reached our bad logon limit.
  69. //
  70. if (pLockoutData->ConsecutiveFailedLogons > LOCKOUT_BAD_LOGON_COUNT) {
  71. ULONG ElapsedSecondsFirstFailure;
  72. ULONG ElapsedSecondsNow;
  73. BOOLEAN Result;
  74. if ((NtCurrentPeb()->SessionId != 0) && (!IsActiveConsoleSession())) {
  75. //
  76. // Forcibly terminate the remote session is we exceed the maximum
  77. // allowed failed logon attempts
  78. //
  79. HANDLE hEventLogSource= RegisterEventSource(NULL,TERMSERV_EVENTSOURCE);
  80. if (hEventLogSource != NULL)
  81. {
  82. PWSTR Strings[ 1 ];
  83. Strings[0] = pGlobals->MuGlobals.ClientName;
  84. ReportEvent(hEventLogSource,
  85. EVENTLOG_INFORMATION_TYPE,
  86. 0,
  87. EVENT_EXCEEDED_MAX_LOGON_ATTEMPTS,
  88. NULL,
  89. 1,
  90. 0,
  91. Strings,
  92. NULL);
  93. DeregisterEventSource(hEventLogSource);
  94. }
  95. TerminateProcess( GetCurrentProcess(), 0 );
  96. }
  97. //
  98. // Limit the count so we don't have any wrap-round problems
  99. // (32-bits - that's a lot of failed logons I know)
  100. //
  101. pLockoutData->ConsecutiveFailedLogons = LOCKOUT_BAD_LOGON_COUNT + 1;
  102. //
  103. // If the first logon in our list occurred too recently, insert
  104. // the appropriate delay
  105. //
  106. Result = RtlTimeToSecondsSince1980(&pLockoutData->FailedLogonTimes[Index],
  107. &ElapsedSecondsFirstFailure);
  108. ASSERT(Result);
  109. Result = RtlTimeToSecondsSince1980(&pGlobals->LogonTime,
  110. &ElapsedSecondsNow);
  111. ASSERT(Result);
  112. if ((ElapsedSecondsNow - ElapsedSecondsFirstFailure) < LOCKOUT_BAD_LOGON_PERIOD) {
  113. SetupCursor(TRUE);
  114. Sleep(LOCKOUT_BAD_LOGON_DELAY * 1000);
  115. SetupCursor(FALSE);
  116. }
  117. }
  118. //
  119. // Add this failed logon to the array
  120. //
  121. pLockoutData->FailedLogonTimes[Index] = pGlobals->LogonTime;
  122. pLockoutData->FailedLogonIndex = INDEX_WRAP(pLockoutData->FailedLogonIndex+1);
  123. return(TRUE);
  124. }
  125. /***************************************************************************\
  126. * FUNCTION: LockoutHandleSuccessfulLogon
  127. *
  128. * PURPOSE: Resets account lockout statistics since a successful logon occurred.
  129. *
  130. * RETURNS: TRUE
  131. *
  132. * HISTORY:
  133. *
  134. * 05-27-92 Davidc Created.
  135. *
  136. \***************************************************************************/
  137. BOOL
  138. LockoutHandleSuccessfulLogon(
  139. PGLOBALS pGlobals
  140. )
  141. {
  142. //
  143. // Reset our bad logon count
  144. //
  145. pGlobals->LockoutData.ConsecutiveFailedLogons = 0;
  146. return(TRUE);
  147. }