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.

379 lines
9.2 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( lpcbSecurityDescriptor == NULL ) {
  59. return ERROR_INVALID_PARAMETER;
  60. }
  61. if (HKEY_CLASSES_ROOT == hKey) {
  62. fClassesRoot = TRUE;
  63. }
  64. if( IsPredefinedRegistryHandle( hKey ) &&
  65. ( ( RequestedInformation & SACL_SECURITY_INFORMATION ) != 0 )
  66. ) {
  67. //
  68. // If SACL is to be retrieved, open a handle with special access
  69. //
  70. DesiredAccess = ACCESS_SYSTEM_SECURITY;
  71. if( ( RequestedInformation &
  72. ( DACL_SECURITY_INFORMATION |
  73. OWNER_SECURITY_INFORMATION |
  74. GROUP_SECURITY_INFORMATION
  75. ) ) != 0 ) {
  76. DesiredAccess |= READ_CONTROL;
  77. }
  78. Error = OpenPredefinedKeyForSpecialAccess( hKey,
  79. DesiredAccess,
  80. &hKey );
  81. if( Error != ERROR_SUCCESS ) {
  82. return( Error );
  83. }
  84. ASSERT( IsLocalHandle( hKey ) );
  85. hkSpecialHandle = hKey;
  86. } else {
  87. hKey = MapPredefinedHandle( hKey, &TempHandle );
  88. DesiredAccess = MAXIMUM_ALLOWED;
  89. }
  90. if( hKey == NULL ) {
  91. Error = ERROR_INVALID_HANDLE;
  92. goto ExitCleanup;
  93. }
  94. if (IsLocalHandle( hKey )) {
  95. NTSTATUS Status;
  96. if (IsSpecialClassesHandle( hKey ) || fClassesRoot) {
  97. Status = BaseRegGetUserAndMachineClass(
  98. NULL,
  99. hKey,
  100. DesiredAccess,
  101. &hkMachineClass,
  102. &hkUserClass);
  103. if (!NT_SUCCESS(Status)) {
  104. Error = (error_status_t) RtlNtStatusToDosError(Status);
  105. goto ExitCleanup;
  106. }
  107. if (hkMachineClass && hkUserClass) {
  108. if (hkMachineClass != hKey) {
  109. hkClassKey = hkMachineClass;
  110. } else {
  111. hkClassKey = hkUserClass;
  112. }
  113. if (fClassesRoot) {
  114. hKey = hkMachineClass;
  115. } else {
  116. hKey = hkUserClass;
  117. }
  118. }
  119. }
  120. }
  121. //
  122. // Convert the supplied SECURITY_DESCRIPTOR to a RPCable version.
  123. //
  124. RpcSD.lpSecurityDescriptor = pSecurityDescriptor;
  125. RpcSD.cbInSecurityDescriptor = *lpcbSecurityDescriptor;
  126. RpcSD.cbOutSecurityDescriptor = 0;
  127. if( IsLocalHandle( hKey )) {
  128. Error = (LONG)LocalBaseRegGetKeySecurity(
  129. hKey,
  130. RequestedInformation,
  131. &RpcSD
  132. );
  133. } else {
  134. Error = (LONG)BaseRegGetKeySecurity(
  135. DereferenceRemoteHandle( hKey ),
  136. RequestedInformation,
  137. &RpcSD
  138. );
  139. }
  140. //
  141. // Extract the size of the SECURITY_DESCRIPTOR from the RPCable version.
  142. //
  143. *lpcbSecurityDescriptor = RpcSD.cbInSecurityDescriptor;
  144. if (hkClassKey) {
  145. NtClose(hkClassKey);
  146. }
  147. ExitCleanup:
  148. if(hkSpecialHandle) {
  149. RegCloseKey(hkSpecialHandle);
  150. }
  151. CLOSE_LOCAL_HANDLE(TempHandle);
  152. return Error;
  153. }
  154. LONG
  155. APIENTRY
  156. RegSetKeySecurity(
  157. HKEY hKey,
  158. SECURITY_INFORMATION SecurityInformation,
  159. PSECURITY_DESCRIPTOR pSecurityDescriptor
  160. )
  161. /*++
  162. Routine Description:
  163. Win32 RPC wrapper for setting a key's security descriptor.
  164. --*/
  165. {
  166. RPC_SECURITY_DESCRIPTOR RpcSD;
  167. LONG Error;
  168. REGSAM DesiredAccess;
  169. HKEY hkSpecialHandle = NULL;
  170. HKEY hkMachineClass;
  171. HKEY hkUserClass;
  172. HKEY hkClassKey = NULL;
  173. BOOL fClassesRoot = FALSE;
  174. HKEY TempHandle = NULL;
  175. #if DBG
  176. if ( BreakPointOnEntry ) {
  177. DbgBreakPoint();
  178. }
  179. #endif
  180. //
  181. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  182. //
  183. if( hKey == HKEY_PERFORMANCE_DATA ) {
  184. return ERROR_INVALID_HANDLE;
  185. }
  186. if (HKEY_CLASSES_ROOT == hKey) {
  187. fClassesRoot = TRUE;
  188. }
  189. if( IsPredefinedRegistryHandle( hKey ) &&
  190. ( ( SecurityInformation & SACL_SECURITY_INFORMATION ) != 0 )
  191. ) {
  192. //
  193. // If the SACL is to be set, open a handle with
  194. // special access
  195. //
  196. DesiredAccess = MAXIMUM_ALLOWED | ACCESS_SYSTEM_SECURITY;
  197. if( SecurityInformation & DACL_SECURITY_INFORMATION ) {
  198. DesiredAccess |= WRITE_DAC;
  199. } else if( SecurityInformation & OWNER_SECURITY_INFORMATION ) {
  200. DesiredAccess |= WRITE_OWNER;
  201. }
  202. Error = OpenPredefinedKeyForSpecialAccess( hKey,
  203. DesiredAccess,
  204. &hKey );
  205. if( Error != ERROR_SUCCESS ) {
  206. return( Error );
  207. }
  208. ASSERT( IsLocalHandle( hKey ) );
  209. hkSpecialHandle = hKey;
  210. } else {
  211. hKey = MapPredefinedHandle( hKey, &TempHandle );
  212. DesiredAccess = MAXIMUM_ALLOWED;
  213. }
  214. if( hKey == NULL ) {
  215. Error = ERROR_INVALID_HANDLE;
  216. goto ExitCleanup;
  217. }
  218. if (IsLocalHandle( hKey )) {
  219. NTSTATUS Status;
  220. if (IsSpecialClassesHandle( hKey ) || fClassesRoot) {
  221. Status = BaseRegGetUserAndMachineClass(
  222. NULL,
  223. hKey,
  224. DesiredAccess,
  225. &hkMachineClass,
  226. &hkUserClass);
  227. if (!NT_SUCCESS(Status)) {
  228. Error = (error_status_t) RtlNtStatusToDosError(Status);
  229. goto ExitCleanup;
  230. }
  231. if (hkMachineClass && hkUserClass) {
  232. if (hkMachineClass != hKey) {
  233. hkClassKey = hkMachineClass;
  234. } else {
  235. hkClassKey = hkUserClass;
  236. }
  237. if (fClassesRoot) {
  238. hKey = hkMachineClass;
  239. } else {
  240. hKey = hkUserClass;
  241. }
  242. }
  243. }
  244. }
  245. //
  246. // Convert the supplied SECURITY_DESCRIPTOR to a RPCable version.
  247. //
  248. RpcSD.lpSecurityDescriptor = NULL;
  249. Error = MapSDToRpcSD(
  250. pSecurityDescriptor,
  251. &RpcSD
  252. );
  253. if( Error != ERROR_SUCCESS ) {
  254. goto ExitCleanup;
  255. }
  256. if( IsLocalHandle( hKey )) {
  257. Error = (LONG)LocalBaseRegSetKeySecurity (
  258. hKey,
  259. SecurityInformation,
  260. &RpcSD
  261. );
  262. #if defined(_WIN64)
  263. if ( Error == 0)
  264. Wow64RegSetKeyDirty (hKey);
  265. #endif
  266. } else {
  267. Error = (LONG)BaseRegSetKeySecurity (
  268. DereferenceRemoteHandle( hKey ),
  269. SecurityInformation,
  270. &RpcSD
  271. );
  272. }
  273. //
  274. // Free the buffer allocated by MapSDToRpcSD.
  275. //
  276. RtlFreeHeap(
  277. RtlProcessHeap( ), 0,
  278. RpcSD.lpSecurityDescriptor
  279. );
  280. if (hkClassKey) {
  281. NtClose(hkClassKey);
  282. }
  283. ExitCleanup:
  284. if(hkSpecialHandle) {
  285. RegCloseKey(hkSpecialHandle);
  286. }
  287. CLOSE_LOCAL_HANDLE(TempHandle);
  288. return Error;
  289. }