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.

165 lines
3.8 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // acctinfo.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Defines the class AccountInfo.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 10/21/1998 Original version.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include <ias.h>
  19. #include <lm.h>
  20. #include <acctinfo.h>
  21. #include <lockkey.h>
  22. #include <new>
  23. // Registry value names.
  24. const WCHAR VALUE_NAME_DENIALS[] = L"Denials";
  25. // Delimeter used for account names (registry won't allow backslash).
  26. const WCHAR ACCOUNT_NAME_DELIMETER = L':';
  27. // The shared LockoutKey.
  28. LockoutKey AccountInfo::root;
  29. AccountInfo* AccountInfo::open(PCWSTR domain, PCWSTR username) throw ()
  30. {
  31. // If account lockout is disabled or the input parameters are invalid,
  32. // we return NULL.
  33. if (root.getMaxDenials() == 0 || domain == NULL || username == NULL)
  34. {
  35. return NULL;
  36. }
  37. // Calculate the memory needed.
  38. size_t nbyte = sizeof(AccountInfo) +
  39. sizeof(WCHAR) * (wcslen(domain) + wcslen(username));
  40. // Allocate a chunk.
  41. PVOID p = malloc(nbyte);
  42. // Construct the object in place.
  43. return p ? new (p) AccountInfo(domain, username) : NULL;
  44. }
  45. // Close an AccountInfo object; 'info' may be NULL.
  46. void AccountInfo::close(AccountInfo* info) throw ()
  47. {
  48. if (info)
  49. {
  50. // Invoke the destructor.
  51. info->~AccountInfo();
  52. // Free the memory.
  53. free(info);
  54. }
  55. }
  56. bool AccountInfo::isLockedOut() const throw ()
  57. {
  58. DWORD maxDenials = root.getMaxDenials();
  59. return maxDenials && maxDenials <= denials;
  60. }
  61. void AccountInfo::initialize() throw ()
  62. {
  63. root.initialize();
  64. }
  65. void AccountInfo::finalize() throw ()
  66. {
  67. root.finalize();
  68. }
  69. AccountInfo::AccountInfo(PCWSTR domain, PCWSTR username) throw ()
  70. : denials(0)
  71. {
  72. // Copy in the domain.
  73. size_t len = wcslen(domain);
  74. memcpy(identity, domain, len * sizeof(WCHAR));
  75. // Set the delimiter.
  76. delim = identity + len;
  77. *delim = ACCOUNT_NAME_DELIMETER;
  78. // Copy in the username.
  79. wcscpy(delim + 1, username);
  80. // Open the registry entry.
  81. hKey = root.openEntry(identity);
  82. // Reset the delimeter for the getDomain and getUserName accessors.
  83. *delim = L'\0';
  84. if (hKey)
  85. {
  86. // The key exists, so read the denials.
  87. DWORD type, data, cb = sizeof(DWORD);
  88. LONG result = RegQueryValueExW(
  89. hKey,
  90. VALUE_NAME_DENIALS,
  91. NULL,
  92. &type,
  93. (LPBYTE)&data,
  94. &cb
  95. );
  96. if (result == NO_ERROR && type == REG_DWORD && cb == sizeof(DWORD))
  97. {
  98. denials = data;
  99. }
  100. // If the denials are zero, persist will delete the key.
  101. if (denials == 0) { persist(); }
  102. }
  103. }
  104. AccountInfo::~AccountInfo() throw ()
  105. {
  106. if (hKey) { RegCloseKey(hKey); }
  107. }
  108. void AccountInfo::persist() throw ()
  109. {
  110. if (denials > 0)
  111. {
  112. // Make sure we have a key to write to.
  113. if (!hKey)
  114. {
  115. *delim = ACCOUNT_NAME_DELIMETER;
  116. hKey = root.createEntry(identity);
  117. *delim = L'\0';
  118. }
  119. // Update the value.
  120. RegSetValueExW(
  121. hKey,
  122. VALUE_NAME_DENIALS,
  123. 0,
  124. REG_DWORD,
  125. (CONST BYTE*)&denials,
  126. sizeof(DWORD)
  127. );
  128. }
  129. else if (hKey)
  130. {
  131. // We never store zero denials, so close the key ...
  132. RegCloseKey(hKey);
  133. hKey = NULL;
  134. // ... and delete.
  135. *delim = ACCOUNT_NAME_DELIMETER;
  136. root.deleteEntry(identity);
  137. *delim = L'\0';
  138. }
  139. }