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.

344 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1989-1993 Microsoft Corporation
  3. Module Name:
  4. arcsec.c
  5. Abstract:
  6. This module contains subroutines for protecting the system
  7. partition on an ARC system.
  8. Author:
  9. Jim Kelly (JimK) 13-Jan-1993
  10. Environment:
  11. Kernel mode - system initialization
  12. Revision History:
  13. --*/
  14. #include "iomgr.h"
  15. //
  16. // Define procedures local to this module.
  17. //
  18. NTSTATUS
  19. IopApplySystemPartitionProt(
  20. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  21. );
  22. #ifdef ALLOC_PRAGMA
  23. #pragma alloc_text(INIT,IopProtectSystemPartition)
  24. #pragma alloc_text(INIT,IopApplySystemPartitionProt)
  25. #endif
  26. //
  27. // This name must match the name use by the DISK MANAGER utility.
  28. // The Disk Manager creates and sets the value of this registry
  29. // key. We only look at it.
  30. //
  31. #define IOP_SYSTEM_PART_PROT_KEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa"
  32. #define IOP_SYSTEM_PART_PROT_VALUE L"Protect System Partition"
  33. BOOLEAN
  34. IopProtectSystemPartition(
  35. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  36. )
  37. /*++
  38. Routine Description:
  39. This routine assigns protection to the system partition of an
  40. ARC system, if necessary. If this is not an ARC system, or
  41. the system partition does not need to be protected, then this
  42. routine does nothing.
  43. Arguments:
  44. LoaderBlock - Supplies a pointer to the loader parameter block that was
  45. created by the OS Loader.
  46. Return Value:
  47. The function value is a BOOLEAN indicating whether or not protection
  48. has been appropriately applied. TRUE indicates no errors were
  49. encountered. FALSE indicates an error was encountered.
  50. --*/
  51. {
  52. //
  53. // We only entertain the possibility of assigning protection
  54. // to the system partition if we are an ARC system. For the
  55. // time being, the best way to determine if you are an ARC
  56. // system is to see if you aren't and X86 machine. DavidRo
  57. // believes that at some point in the future we will have
  58. // ARC compliant X86 machines. At that point in time, we
  59. // will need to change the following #ifdef's into something
  60. // that does a run-time determination.
  61. //
  62. #ifdef i386 // if (!ARC-Compliant system)
  63. //
  64. // Nothing to do for non-ARC systems
  65. //
  66. return(TRUE);
  67. #else // ARC-COMPLIANT system
  68. NTSTATUS status;
  69. NTSTATUS tmpStatus;
  70. HANDLE keyHandle;
  71. OBJECT_ATTRIBUTES objectAttributes;
  72. UNICODE_STRING keyName;
  73. UNICODE_STRING valueName;
  74. ULONG resultLength;
  75. ULONG keyBuffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( ULONG )];
  76. PKEY_VALUE_PARTIAL_INFORMATION keyValue;
  77. //
  78. // This is an ARC system. Attempt to retrieve information from the registry
  79. // indicating whether or not we should protect the system partition.
  80. //
  81. RtlInitUnicodeString( &keyName, IOP_SYSTEM_PART_PROT_KEY );
  82. InitializeObjectAttributes( &objectAttributes,
  83. &keyName,
  84. OBJ_CASE_INSENSITIVE,
  85. NULL,
  86. NULL );
  87. status = NtOpenKey( &keyHandle, KEY_READ, &objectAttributes);
  88. if (NT_SUCCESS( status )) {
  89. keyValue = (PKEY_VALUE_PARTIAL_INFORMATION) &keyBuffer[0];
  90. RtlInitUnicodeString( &valueName, IOP_SYSTEM_PART_PROT_VALUE );
  91. status = NtQueryValueKey( keyHandle,
  92. &valueName,
  93. KeyValuePartialInformation,
  94. keyValue,
  95. sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( ULONG ),
  96. &resultLength );
  97. if (NT_SUCCESS( status )) {
  98. PBOOLEAN applyIt;
  99. //
  100. // The appropriate information was located in the registry. Now
  101. // determine whether or not is indicates that protection is to be
  102. // applied.
  103. //
  104. applyIt = &(keyValue->Data[0]);
  105. if (*applyIt) {
  106. status = IopApplySystemPartitionProt( LoaderBlock );
  107. }
  108. }
  109. tmpStatus = NtClose( keyHandle );
  110. ASSERT(NT_SUCCESS( tmpStatus ));
  111. }
  112. return TRUE;
  113. #endif // ARC-COMPLIANT system
  114. }
  115. NTSTATUS
  116. IopApplySystemPartitionProt(
  117. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  118. )
  119. /*++
  120. Routine Description:
  121. This routine applies protection to the system partition that
  122. prevents all users except administrators from accessing the
  123. partition.
  124. This routine is only used during system initialization.
  125. As such, all memory allocations are expected to succeed.
  126. Success is tested only with assertions.
  127. Arguments:
  128. LoaderBlock - Supplies a pointer to the loader parameter block that was
  129. created by the OS Loader.
  130. Return Value:
  131. The function value is the final status from attempting to set the system
  132. partition protection.
  133. --*/
  134. {
  135. NTSTATUS status;
  136. PACL dacl;
  137. SECURITY_DESCRIPTOR securityDescriptor;
  138. OBJECT_ATTRIBUTES objectAttributes;
  139. ULONG length;
  140. CHAR ArcNameFmt[12];
  141. ArcNameFmt[0] = '\\';
  142. ArcNameFmt[1] = 'A';
  143. ArcNameFmt[2] = 'r';
  144. ArcNameFmt[3] = 'c';
  145. ArcNameFmt[4] = 'N';
  146. ArcNameFmt[5] = 'a';
  147. ArcNameFmt[6] = 'm';
  148. ArcNameFmt[7] = 'e';
  149. ArcNameFmt[8] = '\\';
  150. ArcNameFmt[9] = '%';
  151. ArcNameFmt[10] = 's';
  152. ArcNameFmt[11] = '\0';
  153. ASSERT( ARGUMENT_PRESENT( LoaderBlock ) );
  154. ASSERT( ARGUMENT_PRESENT( LoaderBlock->ArcHalDeviceName ) );
  155. //
  156. // Build an appropriate discretionary ACL.
  157. //
  158. length = (ULONG) sizeof( ACL ) +
  159. ( 2 * ((ULONG) sizeof( ACCESS_ALLOWED_ACE ))) +
  160. SeLengthSid( SeLocalSystemSid ) +
  161. SeLengthSid( SeAliasAdminsSid ) +
  162. 8; // The 8 is just for good measure
  163. dacl = (PACL) ExAllocatePool( PagedPool, length );
  164. if (!dacl) {
  165. return STATUS_INSUFFICIENT_RESOURCES;
  166. }
  167. status = RtlCreateAcl( dacl, length, ACL_REVISION2 );
  168. if (NT_SUCCESS( status )) {
  169. status = RtlAddAccessAllowedAce( dacl,
  170. ACL_REVISION2,
  171. GENERIC_ALL,
  172. SeLocalSystemSid );
  173. if (NT_SUCCESS( status )) {
  174. status = RtlAddAccessAllowedAce( dacl,
  175. ACL_REVISION2,
  176. GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | READ_CONTROL,
  177. SeAliasAdminsSid );
  178. if (NT_SUCCESS( status )) {
  179. //
  180. // Put it in a security descriptor so that it may be applied to
  181. // the system partition device.
  182. //
  183. status = RtlCreateSecurityDescriptor( &securityDescriptor,
  184. SECURITY_DESCRIPTOR_REVISION );
  185. if (NT_SUCCESS( status )) {
  186. status = RtlSetDaclSecurityDescriptor( &securityDescriptor,
  187. TRUE,
  188. dacl,
  189. FALSE );
  190. }
  191. }
  192. }
  193. }
  194. if (!NT_SUCCESS( status )) {
  195. ExFreePool( dacl );
  196. return status;
  197. }
  198. //
  199. // Open the ARC boot device and apply the ACL.
  200. //
  201. {
  202. NTSTATUS tmpStatus;
  203. UCHAR deviceNameBuffer[256];
  204. STRING deviceNameString;
  205. UNICODE_STRING deviceNameUnicodeString;
  206. HANDLE deviceHandle;
  207. IO_STATUS_BLOCK ioStatusBlock;
  208. //
  209. // Begin by formulating the ARC name of the boot device in the ARC
  210. // name space.
  211. //
  212. sprintf( deviceNameBuffer,
  213. ArcNameFmt,
  214. LoaderBlock->ArcHalDeviceName );
  215. RtlInitAnsiString( &deviceNameString, deviceNameBuffer );
  216. status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString,
  217. &deviceNameString,
  218. TRUE );
  219. if (NT_SUCCESS( status )) {
  220. InitializeObjectAttributes( &objectAttributes,
  221. &deviceNameUnicodeString,
  222. OBJ_CASE_INSENSITIVE,
  223. NULL,
  224. NULL );
  225. status = ZwOpenFile( &deviceHandle,
  226. WRITE_DAC,
  227. &objectAttributes,
  228. &ioStatusBlock,
  229. TRUE,
  230. 0 );
  231. RtlFreeUnicodeString( &deviceNameUnicodeString );
  232. if (NT_SUCCESS( status )) {
  233. //
  234. // Apply the ACL built above to the system partition device
  235. // object.
  236. //
  237. status = ZwSetSecurityObject( deviceHandle,
  238. DACL_SECURITY_INFORMATION,
  239. &securityDescriptor );
  240. tmpStatus = NtClose( deviceHandle );
  241. }
  242. }
  243. }
  244. //
  245. // Free the memory used to hold the ACL.
  246. //
  247. ExFreePool( dacl );
  248. return status;
  249. }