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.

375 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Regsckey.c
  5. Abstract:
  6. This module contains the client side wrappers for the Win32 Registry
  7. APIs to set and get the SECURITY_DESCRIPTOR for a key. That is:
  8. - RegGetKeySecurity
  9. - RegSetKeySecurity
  10. Author:
  11. David J. Gilman (davegi) 18-Mar-1992
  12. Notes:
  13. See the notes in server\regsckey.c.
  14. --*/
  15. #include <rpc.h>
  16. #include "regrpc.h"
  17. #include "client.h"
  18. #include <wow64reg.h>
  19. NTSTATUS BaseRegGetUserAndMachineClass(
  20. PVOID pKeySemantics,
  21. HKEY hKey,
  22. REGSAM samDesired,
  23. PHKEY phkMachine,
  24. PHKEY phkUser);
  25. LONG
  26. APIENTRY
  27. RegGetKeySecurity (
  28. HKEY hKey,
  29. SECURITY_INFORMATION RequestedInformation,
  30. PSECURITY_DESCRIPTOR pSecurityDescriptor,
  31. LPDWORD lpcbSecurityDescriptor
  32. )
  33. /*++
  34. Routine Description:
  35. Win32 RPC wrapper for getting a key's security descriptor.
  36. --*/
  37. {
  38. RPC_SECURITY_DESCRIPTOR RpcSD;
  39. LONG Error;
  40. REGSAM DesiredAccess;
  41. HKEY hkSpecialHandle = NULL;
  42. HKEY hkMachineClass;
  43. HKEY hkUserClass;
  44. HKEY hkClassKey = NULL;
  45. BOOL fClassesRoot = FALSE;
  46. HKEY TempHandle = NULL;
  47. #if DBG
  48. if ( BreakPointOnEntry ) {
  49. DbgBreakPoint();
  50. }
  51. #endif
  52. //
  53. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  54. //
  55. if( hKey == HKEY_PERFORMANCE_DATA ) {
  56. return ERROR_INVALID_HANDLE;
  57. }
  58. if (HKEY_CLASSES_ROOT == hKey) {
  59. fClassesRoot = TRUE;
  60. }
  61. if( IsPredefinedRegistryHandle( hKey ) &&
  62. ( ( RequestedInformation & SACL_SECURITY_INFORMATION ) != 0 )
  63. ) {
  64. //
  65. // If SACL is to be retrieved, open a handle with special access
  66. //
  67. DesiredAccess = ACCESS_SYSTEM_SECURITY;
  68. if( ( RequestedInformation &
  69. ( DACL_SECURITY_INFORMATION |
  70. OWNER_SECURITY_INFORMATION |
  71. GROUP_SECURITY_INFORMATION
  72. ) ) != 0 ) {
  73. DesiredAccess |= READ_CONTROL;
  74. }
  75. Error = OpenPredefinedKeyForSpecialAccess( hKey,
  76. DesiredAccess,
  77. &hKey );
  78. if( Error != ERROR_SUCCESS ) {
  79. return( Error );
  80. }
  81. ASSERT( IsLocalHandle( hKey ) );
  82. hkSpecialHandle = hKey;
  83. } else {
  84. hKey = MapPredefinedHandle( hKey, &TempHandle );
  85. DesiredAccess = MAXIMUM_ALLOWED;
  86. }
  87. if( hKey == NULL ) {
  88. Error = ERROR_INVALID_HANDLE;
  89. goto ExitCleanup;
  90. }
  91. if (IsLocalHandle( hKey )) {
  92. NTSTATUS Status;
  93. if (IsSpecialClassesHandle( hKey ) || fClassesRoot) {
  94. Status = BaseRegGetUserAndMachineClass(
  95. NULL,
  96. hKey,
  97. DesiredAccess,
  98. &hkMachineClass,
  99. &hkUserClass);
  100. if (!NT_SUCCESS(Status)) {
  101. Error = (error_status_t) RtlNtStatusToDosError(Status);
  102. goto ExitCleanup;
  103. }
  104. if (hkMachineClass && hkUserClass) {
  105. if (hkMachineClass != hKey) {
  106. hkClassKey = hkMachineClass;
  107. } else {
  108. hkClassKey = hkUserClass;
  109. }
  110. if (fClassesRoot) {
  111. hKey = hkMachineClass;
  112. } else {
  113. hKey = hkUserClass;
  114. }
  115. }
  116. }
  117. }
  118. //
  119. // Convert the supplied SECURITY_DESCRIPTOR to a RPCable version.
  120. //
  121. RpcSD.lpSecurityDescriptor = pSecurityDescriptor;
  122. RpcSD.cbInSecurityDescriptor = *lpcbSecurityDescriptor;
  123. RpcSD.cbOutSecurityDescriptor = 0;
  124. if( IsLocalHandle( hKey )) {
  125. Error = (LONG)LocalBaseRegGetKeySecurity(
  126. hKey,
  127. RequestedInformation,
  128. &RpcSD
  129. );
  130. } else {
  131. Error = (LONG)BaseRegGetKeySecurity(
  132. DereferenceRemoteHandle( hKey ),
  133. RequestedInformation,
  134. &RpcSD
  135. );
  136. }
  137. //
  138. // Extract the size of the SECURITY_DESCRIPTOR from the RPCable version.
  139. //
  140. *lpcbSecurityDescriptor = RpcSD.cbInSecurityDescriptor;
  141. if (hkClassKey) {
  142. NtClose(hkClassKey);
  143. }
  144. ExitCleanup:
  145. if(hkSpecialHandle) {
  146. RegCloseKey(hkSpecialHandle);
  147. }
  148. CLOSE_LOCAL_HANDLE(TempHandle);
  149. return Error;
  150. }
  151. LONG
  152. APIENTRY
  153. RegSetKeySecurity(
  154. HKEY hKey,
  155. SECURITY_INFORMATION SecurityInformation,
  156. PSECURITY_DESCRIPTOR pSecurityDescriptor
  157. )
  158. /*++
  159. Routine Description:
  160. Win32 RPC wrapper for setting a key's security descriptor.
  161. --*/
  162. {
  163. RPC_SECURITY_DESCRIPTOR RpcSD;
  164. LONG Error;
  165. REGSAM DesiredAccess;
  166. HKEY hkSpecialHandle = NULL;
  167. HKEY hkMachineClass;
  168. HKEY hkUserClass;
  169. HKEY hkClassKey = NULL;
  170. BOOL fClassesRoot = FALSE;
  171. HKEY TempHandle = NULL;
  172. #if DBG
  173. if ( BreakPointOnEntry ) {
  174. DbgBreakPoint();
  175. }
  176. #endif
  177. //
  178. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  179. //
  180. if( hKey == HKEY_PERFORMANCE_DATA ) {
  181. return ERROR_INVALID_HANDLE;
  182. }
  183. if (HKEY_CLASSES_ROOT == hKey) {
  184. fClassesRoot = TRUE;
  185. }
  186. if( IsPredefinedRegistryHandle( hKey ) &&
  187. ( ( SecurityInformation & SACL_SECURITY_INFORMATION ) != 0 )
  188. ) {
  189. //
  190. // If the SACL is to be set, open a handle with
  191. // special access
  192. //
  193. DesiredAccess = MAXIMUM_ALLOWED | ACCESS_SYSTEM_SECURITY;
  194. if( SecurityInformation & DACL_SECURITY_INFORMATION ) {
  195. DesiredAccess |= WRITE_DAC;
  196. } else if( SecurityInformation & OWNER_SECURITY_INFORMATION ) {
  197. DesiredAccess |= WRITE_OWNER;
  198. }
  199. Error = OpenPredefinedKeyForSpecialAccess( hKey,
  200. DesiredAccess,
  201. &hKey );
  202. if( Error != ERROR_SUCCESS ) {
  203. return( Error );
  204. }
  205. ASSERT( IsLocalHandle( hKey ) );
  206. hkSpecialHandle = hKey;
  207. } else {
  208. hKey = MapPredefinedHandle( hKey, &TempHandle );
  209. DesiredAccess = MAXIMUM_ALLOWED;
  210. }
  211. if( hKey == NULL ) {
  212. Error = ERROR_INVALID_HANDLE;
  213. goto ExitCleanup;
  214. }
  215. if (IsLocalHandle( hKey )) {
  216. NTSTATUS Status;
  217. if (IsSpecialClassesHandle( hKey ) || fClassesRoot) {
  218. Status = BaseRegGetUserAndMachineClass(
  219. NULL,
  220. hKey,
  221. DesiredAccess,
  222. &hkMachineClass,
  223. &hkUserClass);
  224. if (!NT_SUCCESS(Status)) {
  225. Error = (error_status_t) RtlNtStatusToDosError(Status);
  226. goto ExitCleanup;
  227. }
  228. if (hkMachineClass && hkUserClass) {
  229. if (hkMachineClass != hKey) {
  230. hkClassKey = hkMachineClass;
  231. } else {
  232. hkClassKey = hkUserClass;
  233. }
  234. if (fClassesRoot) {
  235. hKey = hkMachineClass;
  236. } else {
  237. hKey = hkUserClass;
  238. }
  239. }
  240. }
  241. }
  242. //
  243. // Convert the supplied SECURITY_DESCRIPTOR to a RPCable version.
  244. //
  245. RpcSD.lpSecurityDescriptor = NULL;
  246. Error = MapSDToRpcSD(
  247. pSecurityDescriptor,
  248. &RpcSD
  249. );
  250. if( Error != ERROR_SUCCESS ) {
  251. goto ExitCleanup;
  252. }
  253. if( IsLocalHandle( hKey )) {
  254. Error = (LONG)LocalBaseRegSetKeySecurity (
  255. hKey,
  256. SecurityInformation,
  257. &RpcSD
  258. );
  259. #if defined(_WIN64)
  260. if ( Error == 0)
  261. Wow64RegSetKeyDirty (hKey);
  262. #endif
  263. } else {
  264. Error = (LONG)BaseRegSetKeySecurity (
  265. DereferenceRemoteHandle( hKey ),
  266. SecurityInformation,
  267. &RpcSD
  268. );
  269. }
  270. //
  271. // Free the buffer allocated by MapSDToRpcSD.
  272. //
  273. RtlFreeHeap(
  274. RtlProcessHeap( ), 0,
  275. RpcSD.lpSecurityDescriptor
  276. );
  277. if (hkClassKey) {
  278. NtClose(hkClassKey);
  279. }
  280. ExitCleanup:
  281. if(hkSpecialHandle) {
  282. RegCloseKey(hkSpecialHandle);
  283. }
  284. CLOSE_LOCAL_HANDLE(TempHandle);
  285. return Error;
  286. }