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.

353 lines
9.0 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  2. Copyright (c) 1992-1994 Microsoft Corporation
  3. Module Name:
  4. perfsec.c
  5. Abstract:
  6. This file implements the _access checking functions used by the
  7. performance registry API's
  8. Author:
  9. Bob Watson (a-robw)
  10. Revision History:
  11. 8-Mar-95 Created (and extracted from Perflib.c
  12. --*/
  13. #define UNICODE
  14. //
  15. // Include files
  16. //
  17. #pragma warning(disable:4306)
  18. #include <nt.h>
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <windows.h>
  22. #include "ntconreg.h"
  23. #include "perflib.h"
  24. #pragma warning(default:4306)
  25. #define INITIAL_SID_BUFFER_SIZE 4096
  26. #define FREE_IF_ALLOC(x) if ((x) != NULL) {FREEMEM(x);}
  27. BOOL
  28. TestTokenForPriv(
  29. HANDLE hToken,
  30. LPTSTR szPrivName
  31. )
  32. /***************************************************************************\
  33. * TestTokenForPriv
  34. *
  35. * Returns TRUE if the token passed has the specified privilege
  36. *
  37. * The token handle passed must have TOKEN_QUERY access.
  38. *
  39. * History:
  40. * 03-07-95 a-robw Created
  41. \***************************************************************************/
  42. {
  43. BOOL bStatus;
  44. LUID PrivLuid;
  45. PRIVILEGE_SET PrivSet;
  46. LUID_AND_ATTRIBUTES PrivLAndA[1];
  47. BOOL bReturn = FALSE;
  48. // get value of priv
  49. bStatus = LookupPrivilegeValue (
  50. NULL,
  51. szPrivName,
  52. &PrivLuid);
  53. if (!bStatus) {
  54. // unable to lookup privilege
  55. goto Exit_Point;
  56. }
  57. // build Privilege Set for function call
  58. PrivLAndA[0].Luid = PrivLuid;
  59. PrivLAndA[0].Attributes = 0;
  60. PrivSet.PrivilegeCount = 1;
  61. PrivSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
  62. PrivSet.Privilege[0] = PrivLAndA[0];
  63. // check for the specified priv in the token
  64. bStatus = PrivilegeCheck (
  65. hToken,
  66. &PrivSet,
  67. &bReturn);
  68. if (bStatus) {
  69. SetLastError (ERROR_SUCCESS);
  70. }
  71. //
  72. // Tidy up
  73. //
  74. Exit_Point:
  75. return(bReturn);
  76. }
  77. BOOL
  78. TestClientForPriv (
  79. BOOL *pbThread,
  80. LPTSTR szPrivName
  81. )
  82. /***************************************************************************\
  83. * TestClientForPriv
  84. *
  85. * Returns TRUE if our client has the specified privilege
  86. * Otherwise, returns FALSE.
  87. *
  88. \***************************************************************************/
  89. {
  90. BOOL bResult;
  91. BOOL bIgnore;
  92. DWORD dwLastError;
  93. BOOL bThreadFlag = FALSE; // assume data is from process or an error occurred
  94. HANDLE hClient;
  95. SetLastError (ERROR_SUCCESS);
  96. bResult = OpenThreadToken(GetCurrentThread(), // This Thread
  97. TOKEN_QUERY, //DesiredAccess
  98. FALSE, // use context of calling thread
  99. &hClient); //TokenHandle
  100. if (!bResult) {
  101. // unable to get a Thread Token, try a Process Token
  102. bResult = OpenProcessToken(GetCurrentProcess(), // This Process
  103. TOKEN_QUERY, //DesiredAccess
  104. &hClient); //TokenHandle
  105. } else {
  106. // data is from current THREAD
  107. bThreadFlag = TRUE;
  108. }
  109. if (bResult) {
  110. try {
  111. bResult = TestTokenForPriv( hClient, szPrivName );
  112. } except (EXCEPTION_EXECUTE_HANDLER) {
  113. bResult = FALSE;
  114. }
  115. bIgnore = CloseHandle( hClient );
  116. ASSERT(bIgnore == TRUE);
  117. } else {
  118. dwLastError = GetLastError ();
  119. }
  120. // set thread flag if present
  121. if (pbThread != NULL) {
  122. try {
  123. *pbThread = bThreadFlag;
  124. } except (EXCEPTION_EXECUTE_HANDLER) {
  125. SetLastError (ERROR_INVALID_PARAMETER);
  126. }
  127. }
  128. return(bResult);
  129. }
  130. LONG
  131. GetProcessNameColMeth (
  132. VOID
  133. )
  134. {
  135. NTSTATUS Status;
  136. HANDLE hPerflibKey;
  137. OBJECT_ATTRIBUTES oaPerflibKey;
  138. UNICODE_STRING PerflibSubKeyString;
  139. UNICODE_STRING NameInfoValueString;
  140. LONG lReturn = PNCM_SYSTEM_INFO;
  141. PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
  142. DWORD dwBufLen;
  143. DWORD dwRetBufLen;
  144. PDWORD pdwValue;
  145. RtlInitUnicodeString (
  146. &PerflibSubKeyString,
  147. L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib");
  148. InitializeObjectAttributes(
  149. &oaPerflibKey,
  150. &PerflibSubKeyString,
  151. OBJ_CASE_INSENSITIVE,
  152. NULL,
  153. NULL
  154. );
  155. Status = NtOpenKey(
  156. &hPerflibKey,
  157. MAXIMUM_ALLOWED,
  158. &oaPerflibKey
  159. );
  160. if (NT_SUCCESS (Status)) {
  161. // registry key opened, now read value.
  162. // allocate enough room for the structure, - the last
  163. // UCHAR in the struct, but + the data buffer (a dword)
  164. dwBufLen = sizeof(KEY_VALUE_PARTIAL_INFORMATION) -
  165. sizeof(UCHAR) + sizeof (DWORD);
  166. pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ALLOCMEM (dwBufLen);
  167. if (pKeyInfo != NULL) {
  168. // initialize value name string
  169. RtlInitUnicodeString (
  170. &NameInfoValueString,
  171. L"CollectUnicodeProcessNames");
  172. dwRetBufLen = 0;
  173. Status = NtQueryValueKey (
  174. hPerflibKey,
  175. &NameInfoValueString,
  176. KeyValuePartialInformation,
  177. (PVOID)pKeyInfo,
  178. dwBufLen,
  179. &dwRetBufLen);
  180. if (NT_SUCCESS(Status)) {
  181. // check value of return data buffer
  182. pdwValue = (PDWORD)&pKeyInfo->Data[0];
  183. if (*pdwValue == PNCM_MODULE_FILE) {
  184. lReturn = PNCM_MODULE_FILE;
  185. } else {
  186. // all other values will cause this routine to return
  187. // the default value of PNCM_SYSTEM_INFO;
  188. }
  189. }
  190. FREEMEM (pKeyInfo);
  191. }
  192. // close handle
  193. NtClose (hPerflibKey);
  194. }
  195. return lReturn;
  196. }
  197. LONG
  198. GetPerfDataAccess (
  199. VOID
  200. )
  201. {
  202. NTSTATUS Status;
  203. HANDLE hPerflibKey;
  204. OBJECT_ATTRIBUTES oaPerflibKey;
  205. UNICODE_STRING PerflibSubKeyString;
  206. UNICODE_STRING NameInfoValueString;
  207. LONG lReturn = CPSR_EVERYONE;
  208. PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
  209. DWORD dwBufLen;
  210. DWORD dwRetBufLen;
  211. PDWORD pdwValue;
  212. RtlInitUnicodeString (
  213. &PerflibSubKeyString,
  214. L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib");
  215. InitializeObjectAttributes(
  216. &oaPerflibKey,
  217. &PerflibSubKeyString,
  218. OBJ_CASE_INSENSITIVE,
  219. NULL,
  220. NULL
  221. );
  222. Status = NtOpenKey(
  223. &hPerflibKey,
  224. MAXIMUM_ALLOWED,
  225. &oaPerflibKey
  226. );
  227. if (NT_SUCCESS (Status)) {
  228. // registry key opened, now read value.
  229. // allocate enough room for the structure, - the last
  230. // UCHAR in the struct, but + the data buffer (a dword)
  231. dwBufLen = sizeof(KEY_VALUE_PARTIAL_INFORMATION) -
  232. sizeof(UCHAR) + sizeof (DWORD);
  233. pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ALLOCMEM (dwBufLen);
  234. if (pKeyInfo != NULL) {
  235. // see if the user right should be checked
  236. // init value name string
  237. RtlInitUnicodeString (
  238. &NameInfoValueString,
  239. L"CheckProfileSystemRight");
  240. dwRetBufLen = 0;
  241. Status = NtQueryValueKey (
  242. hPerflibKey,
  243. &NameInfoValueString,
  244. KeyValuePartialInformation,
  245. (PVOID)pKeyInfo,
  246. dwBufLen,
  247. &dwRetBufLen);
  248. if (NT_SUCCESS(Status)) {
  249. // check value of return data buffer
  250. pdwValue = (PDWORD)&pKeyInfo->Data[0];
  251. if (*pdwValue == CPSR_CHECK_ENABLED) {
  252. lReturn = CPSR_CHECK_PRIVS;
  253. } else {
  254. // all other values will cause this routine to return
  255. // the default value of CPSR_EVERYONE
  256. }
  257. }
  258. FREEMEM (pKeyInfo);
  259. }
  260. // close handle
  261. NtClose (hPerflibKey);
  262. }
  263. return lReturn;
  264. }
  265. BOOL
  266. TestClientForAccess (
  267. VOID
  268. )
  269. /***************************************************************************\
  270. * TestClientForAccess
  271. *
  272. * Returns TRUE if our client is allowed to read the perflib key.
  273. * Otherwise, returns FALSE.
  274. *
  275. \***************************************************************************/
  276. {
  277. HKEY hKeyPerflib;
  278. DWORD dwStatus;
  279. BOOL bResult = FALSE;
  280. dwStatus = RegOpenKeyExW(
  281. HKEY_LOCAL_MACHINE,
  282. L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
  283. 0L,
  284. KEY_READ,
  285. & hKeyPerflib);
  286. if (dwStatus == ERROR_SUCCESS) {
  287. RegCloseKey(hKeyPerflib);
  288. bResult = TRUE;
  289. }
  290. return (bResult);
  291. }