Leaked source code of windows server 2003
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.

218 lines
6.2 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: restrict.cxx
  8. //
  9. // Contents: Logon restriction code
  10. // This routine is called only on the KDC (not in kerberos)
  11. //
  12. //
  13. // History: 4-Aug-1996 MikeSw Created from tickets.cxx
  14. //
  15. //------------------------------------------------------------------------
  16. #include "kdcsvr.hxx"
  17. #include "fileno.h"
  18. #define FILENO FILENO_RESTRICT
  19. extern SAMPR_HANDLE GlobalAccountDomainHandle;
  20. //+-------------------------------------------------------------------------
  21. //
  22. // Function: KerbCheckLogonRestrictions
  23. //
  24. // Synopsis: Checks logon restrictions for an account
  25. //
  26. // Effects:
  27. //
  28. // Arguments: UserHandle - handle to a user
  29. // Workstation - Name of client's workstation
  30. // SecondsToLogon - Receives logon duration in seconds
  31. //
  32. // Requires:
  33. //
  34. // Returns: kerberos errors
  35. //
  36. // Notes:
  37. //
  38. //
  39. //--------------------------------------------------------------------------
  40. KERBERR
  41. KerbCheckLogonRestrictions(
  42. IN OPTIONAL PVOID UserHandle,
  43. IN PUNICODE_STRING Workstation,
  44. IN PUSER_ALL_INFORMATION UserAll,
  45. IN ULONG LogonRestrictionsFlags,
  46. OUT PLARGE_INTEGER LogoffTime,
  47. OUT PNTSTATUS RetStatus
  48. )
  49. {
  50. NTSTATUS Status = STATUS_SUCCESS;
  51. KERBERR KerbErr;
  52. LARGE_INTEGER KickoffTime;
  53. LARGE_INTEGER CurrentTime;
  54. PLARGE_INTEGER TempTime;
  55. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime );
  56. //
  57. // The Administrator can be locked out #248363
  58. // We need to check Lockout before PW_Expired or PW_MustChange
  59. //
  60. if (UserAll->UserAccountControl & USER_ACCOUNT_AUTO_LOCKED)
  61. {
  62. BOOL LockOut = TRUE;
  63. if (UserAll->UserId == DOMAIN_USER_RID_ADMIN)
  64. {
  65. PSAMPR_DOMAIN_INFO_BUFFER DomainPasswordInfo = NULL;
  66. D_DebugLog((DEB_TRACE,"KLIN(%x) Admin reached lockout limit - check sys properties\n",
  67. KLIN(FILENO,__LINE__)));
  68. Status = SamrQueryInformationDomain(
  69. GlobalAccountDomainHandle,
  70. DomainPasswordInformation,
  71. &DomainPasswordInfo );
  72. if (!NT_SUCCESS(Status))
  73. {
  74. Status = STATUS_INTERNAL_ERROR;
  75. goto Cleanup;
  76. }
  77. if( ((DOMAIN_PASSWORD_INFORMATION *)DomainPasswordInfo)->PasswordProperties & DOMAIN_LOCKOUT_ADMINS)
  78. {
  79. D_DebugLog((DEB_TRACE,"KLIN(%x) Domain admin lockout enabled\n",
  80. KLIN(FILENO,__LINE__)));
  81. //
  82. // get the safeboot mode - do not lockout Admin if in safeboot mode
  83. //
  84. if (KdcGlobalGlobalSafeBoot)
  85. {
  86. D_DebugLog((DEB_TRACE,"KLIN(%x) KDC in SafeBoot - no admin lockout\n",
  87. KLIN(FILENO,__LINE__)));
  88. LockOut = FALSE;
  89. }
  90. } else
  91. {
  92. D_DebugLog((DEB_TRACE,"KLIN(%x) Domain admin lockout disabled\n",
  93. KLIN(FILENO,__LINE__)));
  94. LockOut = FALSE;
  95. }
  96. SamIFree_SAMPR_DOMAIN_INFO_BUFFER( DomainPasswordInfo,
  97. DomainPasswordInformation );
  98. }
  99. if (LockOut) {
  100. Status = STATUS_ACCOUNT_LOCKED_OUT;
  101. goto Cleanup;
  102. }
  103. }
  104. //
  105. // Check the restrictions SAM doesn't:
  106. //
  107. TempTime = (PLARGE_INTEGER) &UserAll->AccountExpires;
  108. if ((TempTime->QuadPart != 0) &&
  109. (TempTime->QuadPart < CurrentTime.QuadPart))
  110. {
  111. Status = STATUS_ACCOUNT_EXPIRED;
  112. goto Cleanup;
  113. }
  114. //
  115. // For user accounts, check if the password has expired.
  116. //
  117. if (((LogonRestrictionsFlags & KDC_RESTRICT_IGNORE_PW_EXPIRATION) == 0) &&
  118. ((UserAll->UserAccountControl & USER_NORMAL_ACCOUNT) != 0))
  119. {
  120. TempTime = (PLARGE_INTEGER) &UserAll->PasswordMustChange;
  121. if (TempTime->QuadPart < CurrentTime.QuadPart)
  122. {
  123. if (TempTime->QuadPart == 0)
  124. {
  125. Status = STATUS_PASSWORD_MUST_CHANGE;
  126. }
  127. else
  128. {
  129. Status = STATUS_PASSWORD_EXPIRED;
  130. }
  131. goto Cleanup;
  132. }
  133. }
  134. if ((UserAll->UserAccountControl & USER_ACCOUNT_DISABLED))
  135. {
  136. Status = STATUS_ACCOUNT_DISABLED;
  137. goto Cleanup;
  138. }
  139. if ((UserAll->UserAccountControl & USER_SMARTCARD_REQUIRED) &&
  140. ((LogonRestrictionsFlags & KDC_RESTRICT_PKINIT_USED) == 0))
  141. {
  142. Status = STATUS_SMARTCARD_LOGON_REQUIRED;
  143. goto Cleanup;
  144. }
  145. if ((LogonRestrictionsFlags & KDC_RESTRICT_SAM_CHECKS) == 0)
  146. {
  147. DsysAssert(UserHandle); // don't need this unless we're doing SAM checks.
  148. Status = SamIAccountRestrictions(
  149. UserHandle,
  150. Workstation,
  151. &UserAll->WorkStations,
  152. &UserAll->LogonHours,
  153. LogoffTime,
  154. &KickoffTime
  155. );
  156. if (!NT_SUCCESS(Status))
  157. {
  158. goto Cleanup;
  159. }
  160. }
  161. Cleanup:
  162. *RetStatus = Status;
  163. switch(Status)
  164. {
  165. case STATUS_SUCCESS:
  166. KerbErr = KDC_ERR_NONE;
  167. break;
  168. case STATUS_ACCOUNT_EXPIRED: // See bug #23456
  169. case STATUS_ACCOUNT_LOCKED_OUT:
  170. case STATUS_ACCOUNT_DISABLED:
  171. case STATUS_INVALID_LOGON_HOURS:
  172. case STATUS_LOGIN_TIME_RESTRICTION:
  173. case STATUS_LOGIN_WKSTA_RESTRICTION:
  174. KerbErr = KDC_ERR_CLIENT_REVOKED;
  175. break;
  176. case STATUS_PASSWORD_EXPIRED:
  177. case STATUS_PASSWORD_MUST_CHANGE:
  178. KerbErr = KDC_ERR_KEY_EXPIRED;
  179. break;
  180. default:
  181. KerbErr = KDC_ERR_POLICY;
  182. }
  183. return(KerbErr);
  184. }