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.

287 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. cmchek2.c
  5. Abstract:
  6. This module implements consistency checking for the registry.
  7. Author:
  8. Bryan M. Willman (bryanwi) 27-Jan-92
  9. Environment:
  10. Revision History:
  11. --*/
  12. #include "cmp.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGE,CmpValidateHiveSecurityDescriptors)
  15. #endif
  16. extern ULONG CmpUsedStorage;
  17. #ifdef HIVE_SECURITY_STATS
  18. ULONG
  19. CmpCheckForSecurityDuplicates(
  20. IN OUT PCMHIVE CmHive
  21. );
  22. #endif
  23. BOOLEAN
  24. CmpValidateHiveSecurityDescriptors(
  25. IN PHHIVE Hive,
  26. OUT PBOOLEAN ResetSD
  27. )
  28. /*++
  29. Routine Description:
  30. Walks the list of security descriptors present in the hive and passes
  31. each security descriptor to RtlValidSecurityDescriptor.
  32. Only applies to descriptors in Stable store. Those in Volatile store
  33. cannot have come from disk and therefore do not need this treatment
  34. anyway.
  35. Arguments:
  36. Hive - Supplies pointer to the hive control structure
  37. Return Value:
  38. TRUE - All security descriptors are valid
  39. FALSE - At least one security descriptor is invalid
  40. --*/
  41. {
  42. PCM_KEY_NODE RootNode;
  43. PCM_KEY_SECURITY SecurityCell;
  44. HCELL_INDEX ListAnchor;
  45. HCELL_INDEX NextCell;
  46. HCELL_INDEX LastCell;
  47. BOOLEAN BuildSecurityCache;
  48. #ifdef HIVE_SECURITY_STATS
  49. UNICODE_STRING HiveName;
  50. ULONG NoOfCells = 0;
  51. ULONG SmallestSize = 0;
  52. ULONG BiggestSize = 0;
  53. ULONG TotalSecuritySize = 0;
  54. RtlInitUnicodeString(&HiveName, (PCWSTR)Hive->BaseBlock->FileName);
  55. #ifndef _CM_LDR_
  56. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"Security stats for hive (%lx) (%.*S):\n",Hive,HiveName.Length / sizeof(WCHAR),HiveName.Buffer);
  57. #endif //_CM_LDR_
  58. #endif
  59. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC,"CmpValidateHiveSecurityDescriptor: Hive = %p\n",(ULONG_PTR)Hive));
  60. ASSERT( Hive->ReleaseCellRoutine == NULL );
  61. *ResetSD = FALSE;
  62. if( ((PCMHIVE)Hive)->SecurityCount == 0 ) {
  63. BuildSecurityCache = TRUE;
  64. } else {
  65. BuildSecurityCache = FALSE;
  66. }
  67. if (!HvIsCellAllocated(Hive,Hive->BaseBlock->RootCell)) {
  68. //
  69. // root cell HCELL_INDEX is bogus
  70. //
  71. return(FALSE);
  72. }
  73. RootNode = (PCM_KEY_NODE) HvGetCell(Hive, Hive->BaseBlock->RootCell);
  74. if( RootNode == NULL ) {
  75. //
  76. // we couldn't map a view for the bin containing this cell
  77. //
  78. return FALSE;
  79. }
  80. if( FALSE ) {
  81. YankSD:
  82. if( CmDoSelfHeal() ) {
  83. //
  84. // reset all security for the entire hive to the root security. There is no reliable way to
  85. // patch the security list
  86. //
  87. SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, RootNode->Security);
  88. if( SecurityCell == NULL ) {
  89. return FALSE;
  90. }
  91. if( HvMarkCellDirty(Hive, RootNode->Security) ) {
  92. SecurityCell->Flink = SecurityCell->Blink = RootNode->Security;
  93. } else {
  94. return FALSE;
  95. }
  96. //
  97. // destroy existing cache and set up an empty one
  98. //
  99. CmpDestroySecurityCache((PCMHIVE)Hive);
  100. CmpInitSecurityCache((PCMHIVE)Hive);
  101. CmMarkSelfHeal(Hive);
  102. *ResetSD = TRUE;
  103. #if 0
  104. //
  105. // remove this security cell from the list and restart iteration
  106. //
  107. if(HvIsCellAllocated(Hive, NextCell)) {
  108. //
  109. // we come this path when the SD is invalid; we need to free the cell so
  110. // cmpcheckregistry2 detects and fixes it
  111. //
  112. if( HvMarkCellDirty(Hive, NextCell) ) {
  113. HvFreeCell(Hive, NextCell);
  114. } else {
  115. return FALSE;
  116. }
  117. }
  118. LastCell = SecurityCell->Blink;
  119. NextCell = SecurityCell->Flink;
  120. SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, LastCell);
  121. if( SecurityCell == NULL ) {
  122. return FALSE;
  123. }
  124. if( HvMarkCellDirty(Hive, LastCell) ) {
  125. SecurityCell->Flink = NextCell;
  126. } else {
  127. return FALSE;
  128. }
  129. SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, NextCell);
  130. if( SecurityCell == NULL ) {
  131. return FALSE;
  132. }
  133. if( HvMarkCellDirty(Hive, NextCell) ) {
  134. SecurityCell->Blink = LastCell;
  135. } else {
  136. return FALSE;
  137. }
  138. CmMarkSelfHeal(Hive);
  139. #endif
  140. } else {
  141. return FALSE;
  142. }
  143. }
  144. LastCell = 0;
  145. ListAnchor = NextCell = RootNode->Security;
  146. do {
  147. if (!HvIsCellAllocated(Hive, NextCell)) {
  148. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC,"CM: CmpValidateHiveSecurityDescriptors\n"));
  149. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC," NextCell: %08lx is invalid HCELL_INDEX\n",NextCell));
  150. goto YankSD;
  151. }
  152. SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, NextCell);
  153. if( SecurityCell == NULL ) {
  154. //
  155. // we couldn't map a view for the bin containing this cell
  156. //
  157. return FALSE;
  158. }
  159. #ifdef HIVE_SECURITY_STATS
  160. NoOfCells++;
  161. if( (SmallestSize == 0) || ((SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor)) < SmallestSize) ) {
  162. SmallestSize = SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor);
  163. }
  164. if( (BiggestSize == 0) || ((SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor)) > BiggestSize) ) {
  165. BiggestSize = SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor);
  166. }
  167. TotalSecuritySize += (SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor));
  168. #endif
  169. if (NextCell != ListAnchor) {
  170. //
  171. // Check to make sure that our Blink points to where we just
  172. // came from.
  173. //
  174. if (SecurityCell->Blink != LastCell) {
  175. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC," Invalid Blink (%08lx) on security cell %08lx\n",SecurityCell->Blink, NextCell));
  176. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC," should point to %08lx\n", LastCell));
  177. return(FALSE);
  178. }
  179. }
  180. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC,"CmpValidSD: SD shared by %d nodes\n",SecurityCell->ReferenceCount));
  181. if (!SeValidSecurityDescriptor(SecurityCell->DescriptorLength, &SecurityCell->Descriptor)) {
  182. #if DBG
  183. CmpDumpSecurityDescriptor(&SecurityCell->Descriptor,"INVALID DESCRIPTOR");
  184. #endif
  185. goto YankSD;
  186. }
  187. //
  188. // cache this security cell; now that we know it is valid
  189. //
  190. if( BuildSecurityCache == TRUE ) {
  191. if( !NT_SUCCESS(CmpAddSecurityCellToCache ( (PCMHIVE)Hive,NextCell,TRUE,NULL) ) ) {
  192. return FALSE;
  193. }
  194. } else {
  195. //
  196. // just check this cell is there
  197. //
  198. ULONG Index;
  199. if( CmpFindSecurityCellCacheIndex ((PCMHIVE)Hive,NextCell,&Index) == FALSE ) {
  200. //
  201. // bad things happened; maybe an error in our caching code?
  202. //
  203. return FALSE;
  204. }
  205. }
  206. LastCell = NextCell;
  207. NextCell = SecurityCell->Flink;
  208. } while ( NextCell != ListAnchor );
  209. #ifdef HIVE_SECURITY_STATS
  210. #ifndef _CM_LDR_
  211. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t NumberOfCells \t = %20lu (%8lx) \n",NoOfCells,NoOfCells);
  212. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t SmallestCellSize \t = %20lu (%8lx) \n",SmallestSize,SmallestSize);
  213. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t BiggestCellSize \t = %20lu (%8lx) \n",BiggestSize,BiggestSize);
  214. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t TotalSecuritySize\t = %20lu (%8lx) \n",TotalSecuritySize,TotalSecuritySize);
  215. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t HiveLength \t = %20lu (%8lx) \n",Hive->BaseBlock->Length,Hive->BaseBlock->Length);
  216. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\n");
  217. #endif //_CM_LDR_
  218. #endif
  219. if( BuildSecurityCache == TRUE ) {
  220. //
  221. // adjust the size of the cache in case we allocated too much
  222. //
  223. CmpAdjustSecurityCacheSize ( (PCMHIVE)Hive );
  224. #ifdef HIVE_SECURITY_STATS
  225. {
  226. ULONG Duplicates;
  227. Duplicates = CmpCheckForSecurityDuplicates((PCMHIVE)Hive);
  228. if( Duplicates ) {
  229. #ifndef _CM_LDR_
  230. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"Hive %p %lu security cells duplicated !!!\n",Hive,Duplicates);
  231. #endif //_CM_LDR_
  232. }
  233. }
  234. #endif
  235. }
  236. return(TRUE);
  237. }