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.

307 lines
11 KiB

  1. // --------------------------------------------------------------------------
  2. // Module Name: SpecialAccounts.cpp
  3. //
  4. // Copyright (c) 1999-2000, Microsoft Corporation
  5. //
  6. // Class that implements handling special account names for exclusion or
  7. // inclusion.
  8. //
  9. // History: 1999-10-30 vtan created
  10. // 1999-11-26 vtan moved from logonocx
  11. // 2000-01-31 vtan moved from Neptune to Whistler
  12. // --------------------------------------------------------------------------
  13. #include "StandardHeader.h"
  14. #include "SpecialAccounts.h"
  15. #include "RegistryResources.h"
  16. // --------------------------------------------------------------------------
  17. // CSpecialAccounts::s_szUserListKeyName
  18. //
  19. // Purpose: Static const member variable that holds the location of the
  20. // special accounts in the registry.
  21. //
  22. // History: 2000-01-31 vtan created
  23. // --------------------------------------------------------------------------
  24. const TCHAR CSpecialAccounts::s_szUserListKeyName[] = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\SpecialAccounts\\UserList");
  25. // --------------------------------------------------------------------------
  26. // CSpecialAccounts::CSpecialAccounts
  27. //
  28. // Arguments: <none>
  29. //
  30. // Returns: <none>
  31. //
  32. // Purpose: Reads the registry to determine which accounts should be
  33. // filtered out and which should not be filtered out based on an
  34. // action code. The list is built up in memory so that each time
  35. // the class is invoked it adjusts live.
  36. //
  37. // History: 1999-10-30 vtan created
  38. // --------------------------------------------------------------------------
  39. CSpecialAccounts::CSpecialAccounts (void) :
  40. _dwSpecialAccountsCount(0),
  41. _pSpecialAccounts(NULL)
  42. {
  43. CRegKey regKeyUserList;
  44. // Open the key to where the information is stored.
  45. if (ERROR_SUCCESS == regKeyUserList.Open(HKEY_LOCAL_MACHINE, s_szUserListKeyName, KEY_READ))
  46. {
  47. DWORD dwValueCount;
  48. // Find out how many entries there are so an array of the correct
  49. // size can be allocated.
  50. if (ERROR_SUCCESS == regKeyUserList.QueryInfoKey(NULL, NULL, NULL, NULL, NULL, &dwValueCount, NULL, NULL, NULL, NULL))
  51. {
  52. _pSpecialAccounts = static_cast<PSPECIAL_ACCOUNTS>(LocalAlloc(LPTR, dwValueCount * sizeof(SPECIAL_ACCOUNTS)));
  53. if (_pSpecialAccounts != NULL)
  54. {
  55. DWORD dwIndex, dwType, dwValueNameSize, dwDataSize;
  56. PSPECIAL_ACCOUNTS pSCA;
  57. // If the memory was allocated then fill the array in.
  58. regKeyUserList.Reset();
  59. _dwSpecialAccountsCount = dwValueCount;
  60. pSCA = _pSpecialAccounts;
  61. for (dwIndex = 0; dwIndex < dwValueCount; ++dwIndex)
  62. {
  63. dwValueNameSize = ARRAYSIZE(pSCA->wszUsername);
  64. dwDataSize = sizeof(pSCA->dwAction);
  65. // Ensure that the entries are of type REG_DWORD. Ignore
  66. // any that are not.
  67. if ((ERROR_SUCCESS == regKeyUserList.Next(pSCA->wszUsername,
  68. &dwValueNameSize,
  69. &dwType,
  70. &pSCA->dwAction,
  71. &dwDataSize)) &&
  72. (REG_DWORD == dwType))
  73. {
  74. ++pSCA;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. // --------------------------------------------------------------------------
  82. // CSpecialAccounts::~CSpecialAccounts
  83. //
  84. // Arguments: <none>
  85. //
  86. // Returns: <none>
  87. //
  88. // Purpose: Releases the memory allocated in the constructor.
  89. //
  90. // History: 1999-10-30 vtan created
  91. // --------------------------------------------------------------------------
  92. CSpecialAccounts::~CSpecialAccounts (void)
  93. {
  94. if (_pSpecialAccounts != NULL)
  95. {
  96. (HLOCAL)LocalFree(_pSpecialAccounts);
  97. _pSpecialAccounts = NULL;
  98. _dwSpecialAccountsCount = 0;
  99. }
  100. }
  101. // --------------------------------------------------------------------------
  102. // CSpecialAccounts::AlwaysExclude
  103. //
  104. // Arguments: pwszAccountName = Account name to match.
  105. //
  106. // Returns: bool
  107. //
  108. // Purpose: Uses the iterate loop to find a match for exclusion accounts.
  109. //
  110. // History: 1999-10-30 vtan created
  111. // --------------------------------------------------------------------------
  112. bool CSpecialAccounts::AlwaysExclude (const WCHAR *pwszAccountName) const
  113. {
  114. return(IterateAccounts(pwszAccountName, RESULT_EXCLUDE));
  115. }
  116. // --------------------------------------------------------------------------
  117. // CSpecialAccounts::AlwaysInclude
  118. //
  119. // Arguments: pwszAccountName = Account name to match.
  120. //
  121. // Returns: bool
  122. //
  123. // Purpose: Uses the iterate loop to find a match for inclusion accounts.
  124. //
  125. // History: 1999-10-30 vtan created
  126. // --------------------------------------------------------------------------
  127. bool CSpecialAccounts::AlwaysInclude (const WCHAR *pwszAccountName) const
  128. {
  129. return(IterateAccounts(pwszAccountName, RESULT_INCLUDE));
  130. }
  131. // --------------------------------------------------------------------------
  132. // CSpecialAccounts::StaticInitialize
  133. //
  134. // Arguments: <none>
  135. //
  136. // Returns: NTSTATUS
  137. //
  138. // Purpose: Installs default user list for CSpecialAccounts to use.
  139. // CSpecialAccounts lives in specialaccounts.cpp and handles
  140. // exclusion or inclusion of special account names.
  141. //
  142. // History: 1999-11-01 vtan created
  143. // 1999-11-26 vtan moved from logonocx
  144. // --------------------------------------------------------------------------
  145. void CSpecialAccounts::Install (void)
  146. {
  147. // Some of these names can be localized. IWAM_ and IUSR_ are stored in
  148. // resources in IIS. VUSR_ and SQLAgentCmdExec are of unknown origin.
  149. // TsInternetUser is hard coded in TS component bits.
  150. static const TCHAR szTsInternetUserName[] = TEXT("TsInternetUser");
  151. static const TCHAR szSQLAgentUserName[] = TEXT("SQLAgentCmdExec");
  152. static const TCHAR szWebAccessUserName[] = TEXT("IWAM_");
  153. static const TCHAR szInternetUserName[] = TEXT("IUSR_");
  154. static const TCHAR szVisualStudioUserName[] = TEXT("VUSR_");
  155. static const TCHAR szNetShowServicesUserName[] = TEXT("NetShowServices");
  156. static const TCHAR szHelpAssistantUserName[] = TEXT("HelpAssistant");
  157. typedef struct
  158. {
  159. bool fInstall;
  160. const TCHAR *pszAccountName;
  161. DWORD dwActionType;
  162. } tSpecialAccount, *pSpecialAccount;
  163. DWORD dwDisposition;
  164. CRegKey regKeyUserList;
  165. // Open key to the user list.
  166. if (ERROR_SUCCESS == regKeyUserList.Create(HKEY_LOCAL_MACHINE,
  167. s_szUserListKeyName,
  168. REG_OPTION_NON_VOLATILE,
  169. KEY_READ | KEY_WRITE,
  170. &dwDisposition))
  171. {
  172. tSpecialAccount *pSA;
  173. static tSpecialAccount sSpecialAccount[] =
  174. {
  175. { true, szTsInternetUserName, COMPARISON_EQUALS | RESULT_EXCLUDE },
  176. { true, szSQLAgentUserName, COMPARISON_EQUALS | RESULT_EXCLUDE },
  177. { true, szNetShowServicesUserName, COMPARISON_EQUALS | RESULT_EXCLUDE },
  178. { true, szHelpAssistantUserName, COMPARISON_EQUALS | RESULT_EXCLUDE },
  179. { true, szWebAccessUserName, COMPARISON_STARTSWITH | RESULT_EXCLUDE },
  180. { true, szInternetUserName, COMPARISON_STARTSWITH | RESULT_EXCLUDE },
  181. { true, szVisualStudioUserName, COMPARISON_STARTSWITH | RESULT_EXCLUDE },
  182. { true, NULL, 0 },
  183. };
  184. pSA = sSpecialAccount;
  185. while (pSA->pszAccountName != NULL)
  186. {
  187. if (pSA->fInstall)
  188. {
  189. TW32(regKeyUserList.SetDWORD(pSA->pszAccountName, pSA->dwActionType));
  190. }
  191. else
  192. {
  193. TW32(regKeyUserList.DeleteValue(pSA->pszAccountName));
  194. }
  195. ++pSA;
  196. }
  197. }
  198. }
  199. // --------------------------------------------------------------------------
  200. // CSpecialAccounts::IterateAccounts
  201. //
  202. // Arguments: pwszAccountName = Account name to match.
  203. // dwResultType = Result type to match.
  204. //
  205. // Returns: bool
  206. //
  207. // Purpose: Iterates thru the special case account name list from the
  208. // registry built in the constructor. Matches the given account
  209. // name based on the type of match specified for the special case
  210. // entry. If the account names match then match the result type.
  211. //
  212. // History: 1999-10-30 vtan created
  213. // --------------------------------------------------------------------------
  214. bool CSpecialAccounts::IterateAccounts (const WCHAR *pwszAccountName, DWORD dwResultType) const
  215. {
  216. bool fResult;
  217. PSPECIAL_ACCOUNTS pSCA;
  218. fResult = false;
  219. pSCA = _pSpecialAccounts;
  220. if (pSCA != NULL)
  221. {
  222. DWORD dwIndex;
  223. for (dwIndex = 0; !fResult && (dwIndex < _dwSpecialAccountsCount); ++pSCA, ++dwIndex)
  224. {
  225. bool fMatch;
  226. // Perform the account name match based on the required type.
  227. // Currently only "equals" and "starts with" are supported.
  228. switch (pSCA->dwAction & COMPARISON_MASK)
  229. {
  230. case COMPARISON_EQUALS:
  231. {
  232. fMatch = (lstrcmpiW(pwszAccountName, pSCA->wszUsername) == 0);
  233. break;
  234. }
  235. case COMPARISON_STARTSWITH:
  236. {
  237. int iLength;
  238. iLength = lstrlenW(pSCA->wszUsername);
  239. fMatch = (CompareStringW(LOCALE_SYSTEM_DEFAULT,
  240. NORM_IGNORECASE,
  241. pwszAccountName,
  242. iLength,
  243. pSCA->wszUsername,
  244. iLength) == CSTR_EQUAL);
  245. break;
  246. }
  247. default:
  248. {
  249. fMatch = false;
  250. break;
  251. }
  252. }
  253. if (fMatch)
  254. {
  255. // If the name matches make sure the result type does as well.
  256. fResult = ((pSCA->dwAction & RESULT_MASK) == dwResultType);
  257. }
  258. }
  259. }
  260. return(fResult);
  261. }