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.

972 lines
24 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*++
  3. Copyright (c) 1998 Citrix Systems
  4. Module Name:
  5. regfix.c
  6. Abstract:
  7. Reads hv (low) level structures in a hive and rewrites the hive structs after applying
  8. ACL fixes. Reads in the hive in block sizes. Scans for and processes security keys.
  9. Extracts the SECURITY_DESCRIPTOR structure form a cell and checks consistency of sizes
  10. of ACEs and ACLs.
  11. Usage: regfix in_filename out_filename
  12. Author:
  13. Maris Kurens (v-marisk (MS), marisk (CTXS)) Apr 1998
  14. Revision History:
  15. Created - Apr 23, 1998
  16. --*/
  17. /*
  18. NOTE: This hive/registry tool does not read the
  19. entire hive into memory, but will read the hive file
  20. on a block by block basis, process each block and
  21. write out the block to a new file using file I/O.
  22. */
  23. // Include NT headers
  24. #include <nt.h>
  25. #include <ntrtl.h>
  26. #include <nturtl.h>
  27. #include <ntseapi.h>
  28. #include "cmp.h"
  29. #include "regfix.h"
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <windows.h>
  34. #define INFILE 0x01
  35. #define OUTFILE 0x02
  36. #define BOTHFILE 0x03
  37. int __cdecl main (int argc, char *argv[]);
  38. void openFile (void);
  39. void closeFile (unsigned which);
  40. void ScanHive (void);
  41. void DoKeySD (IN PCM_KEY_SECURITY Security, IN ULONG CellSize);
  42. void ScanCell (PHCELL Cell, ULONG CellSize);
  43. void DumpSecurityDescriptor (PSECURITY_DESCRIPTOR pSD);
  44. void CtxDumpSid (PSID, PCHAR, PULONG);
  45. void DumpAcl (PACL, PCHAR, PULONG);
  46. void DumpAce (PACE_HEADER, PCHAR, PULONG);
  47. BOOL AreWeRunningTerminalServices(void);
  48. VOID WINAPI ErrorPrintf (int nErrorResourceID, ...);
  49. LPCTSTR inFileName = NULL;
  50. LPCTSTR outFileName = NULL;
  51. HANDLE infilehandle;
  52. HANDLE outfilehandle;
  53. ULONG HiveVersion;
  54. //
  55. // SUMMARY TOTALS
  56. //
  57. ULONG SizeSDData=0;
  58. ULONG NumSDData=0;
  59. ULONG BlockNumb = 0;
  60. ULONG BadACL = 0;
  61. ULONG BadACE = 0;
  62. //---------------------------------------------------------
  63. // Description :
  64. // Basic arg check, arg echo, process calls and result dump
  65. //
  66. // Args :
  67. // if you have to ask ...
  68. //
  69. // Return :
  70. //
  71. //---------------------------------------------------------
  72. int __cdecl main (int argc, char *argv[])
  73. {
  74. //Check if we are running under Terminal Server
  75. if(!AreWeRunningTerminalServices())
  76. {
  77. ErrorPrintf(IDS_ERROR_NOT_TS);
  78. return(1);
  79. }
  80. if (argc < 3)
  81. {
  82. ErrorPrintf (IDS_ERROR_USAGE);
  83. exit (1);
  84. }
  85. inFileName = argv [1];
  86. outFileName = argv [2];
  87. //
  88. // echo the args
  89. //
  90. ErrorPrintf (IDS_WORKING);
  91. //
  92. // open the in and out files
  93. //
  94. openFile ();
  95. //
  96. // and process it
  97. //
  98. ScanHive ();
  99. ErrorPrintf (IDS_DONE);
  100. ErrorPrintf (IDS_SD_NUMBER, NumSDData);
  101. ErrorPrintf (IDS_BAD_ACL_NUMBER, BadACL);
  102. ErrorPrintf (IDS_BAD_ACE_NUMBER, BadACE);
  103. return (0);
  104. }
  105. //---------------------------------------------------------
  106. // Description :
  107. // Closes file handles based on input args
  108. //
  109. // Args :
  110. // which - signals if input or output or both files should be closed
  111. //
  112. // Return : Nothing
  113. //
  114. //---------------------------------------------------------
  115. void closeFile (unsigned which)
  116. {
  117. if (which & INFILE)
  118. {
  119. if (infilehandle != INVALID_HANDLE_VALUE)
  120. {
  121. CloseHandle (infilehandle);
  122. infilehandle = INVALID_HANDLE_VALUE;
  123. }
  124. }
  125. if (which & OUTFILE)
  126. {
  127. if (infilehandle != INVALID_HANDLE_VALUE)
  128. {
  129. CloseHandle (outfilehandle);
  130. outfilehandle = INVALID_HANDLE_VALUE;
  131. }
  132. }
  133. }
  134. //---------------------------------------------------------
  135. // Description :
  136. // Opens input and output files
  137. //
  138. // Args : Nada
  139. //
  140. // Return : Nada
  141. //
  142. //---------------------------------------------------------
  143. void openFile (void)
  144. {
  145. //
  146. // open the input file
  147. //
  148. infilehandle = CreateFile (inFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  149. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  150. if (infilehandle == INVALID_HANDLE_VALUE)
  151. {
  152. fprintf (stderr,
  153. "regfix: Could not open file '%s' error = %08lx\n",
  154. inFileName, GetLastError());
  155. exit(1);
  156. }
  157. //
  158. // open the output file
  159. //
  160. outfilehandle = CreateFile (outFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
  161. CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  162. if (outfilehandle == INVALID_HANDLE_VALUE)
  163. {
  164. closeFile (INFILE);
  165. fprintf (stderr,
  166. "hivestat: Could not create file '%s' error = %08lx\n",
  167. outFileName, GetLastError());
  168. exit(1);
  169. }
  170. }
  171. //---------------------------------------------------------
  172. // Description :
  173. // Scan the hive, looking for security cells. Load the
  174. // hive block by block and write each block to the output
  175. // file after processing it.
  176. //
  177. // Args : None
  178. //
  179. // Return : Nyet
  180. //
  181. //---------------------------------------------------------
  182. void ScanHive (void)
  183. {
  184. static char buffer[HBLOCK_SIZE];
  185. PHBASE_BLOCK bbp;
  186. BOOL rf;
  187. BOOL wf;
  188. ULONG readcount;
  189. ULONG writecount;
  190. ULONG hivelength;
  191. ULONG hiveposition;
  192. PHCELL cp;
  193. PHCELL guard;
  194. PHBIN hbp;
  195. ULONG hoff;
  196. ULONG binread;
  197. ULONG binsize;
  198. ULONG cellsize;
  199. ULONG boff;
  200. ULONG lboff;
  201. ULONG SizeTotal;
  202. //
  203. // read the header
  204. //
  205. rf = ReadFile (infilehandle, buffer, HBLOCK_SIZE, &readcount, NULL);
  206. if ((!rf) || (readcount != HBLOCK_SIZE) )
  207. {
  208. closeFile (BOTHFILE);
  209. fprintf (stderr, "regfix: '%s' - cannot read base block!\n", inFileName);
  210. exit(1);
  211. }
  212. BlockNumb++;
  213. bbp = (PHBASE_BLOCK)(&(buffer[0]));
  214. if ((bbp->Major != HSYS_MAJOR) ||
  215. (bbp->Minor > HSYS_MINOR))
  216. {
  217. closeFile (BOTHFILE);
  218. fprintf(stderr,
  219. "hivestat: major/minor != %d/%d get newer hivestat\n",
  220. HSYS_MAJOR, HSYS_MINOR
  221. );
  222. exit(1);
  223. }
  224. HiveVersion = bbp->Minor;
  225. hivelength = bbp->Length + HBLOCK_SIZE;
  226. hiveposition = HBLOCK_SIZE;
  227. hoff = 0;
  228. //
  229. // scan the hive
  230. //
  231. guard = (PHCELL)(&(buffer[0]) + HBLOCK_SIZE);
  232. wf = WriteFile (outfilehandle, buffer, HBLOCK_SIZE, &writecount, NULL);
  233. if ((!wf) || (writecount != HBLOCK_SIZE) )
  234. {
  235. closeFile (BOTHFILE);
  236. fprintf (stderr, "regfix: '%s' - cannot write base block!\n", outFileName);
  237. exit(1);
  238. }
  239. //
  240. // hiveposition is file relative offset of next block we will read
  241. //
  242. // hoff is the file relative offset of the last block we read
  243. //
  244. // hivelength is actual length of file (header's recorded length plus
  245. // the size of the header.
  246. //
  247. // cp is pointer into memory, within range of buffer, it's a cell pointer
  248. //
  249. while (hiveposition < hivelength)
  250. {
  251. //
  252. // read in first block of bin, check signature, determine key type
  253. //
  254. rf = ReadFile (infilehandle, buffer, HBLOCK_SIZE, &readcount, NULL);
  255. if ((! rf) || (readcount != HBLOCK_SIZE))
  256. {
  257. closeFile (BOTHFILE);
  258. fprintf (stderr, "hivestat: '%s' read error @%08lx\n", inFileName, hiveposition);
  259. exit (1);
  260. }
  261. BlockNumb++;
  262. hbp = (PHBIN)(&(buffer[0]));
  263. if (hbp->Signature != HBIN_SIGNATURE)
  264. {
  265. closeFile (BOTHFILE);
  266. fprintf(stderr,
  267. "hivestat: '%s' bad bin sign. @%08lx\n", inFileName, hiveposition);
  268. exit(1);
  269. }
  270. hiveposition += HBLOCK_SIZE;
  271. hoff += HBLOCK_SIZE;
  272. ASSERT (hoff+HBLOCK_SIZE == hiveposition);
  273. binsize = hbp->Size;
  274. //
  275. // scan the bin
  276. //
  277. // cp = pointer to cell we are looking at
  278. // boff = offset within bin
  279. // lboff = last offset within bin, used only for consistency checks
  280. // binread = number of bytes of bin we've read so far
  281. //
  282. cp = (PHCELL)((PUCHAR)hbp + sizeof(HBIN));
  283. boff = sizeof(HBIN);
  284. lboff = (ULONG)-1;
  285. binread = HBLOCK_SIZE;
  286. while (binread <= binsize)
  287. {
  288. //
  289. // if free, update pointer only
  290. // else scan it
  291. //
  292. if (cp->Size > 0)
  293. {
  294. cellsize = cp->Size;
  295. }
  296. else
  297. {
  298. cellsize = -1 * cp->Size;
  299. ScanCell (cp, cellsize);
  300. }
  301. //
  302. // do basic consistency check
  303. //
  304. #if 0
  305. if (cp->Last != lboff) {
  306. printf("e!,x%08lx bad LAST pointer %08lx\n",
  307. hoff+((PUCHAR)cp - &(buffer[0])), cp->Last);
  308. }
  309. #endif
  310. //
  311. // advance to next cell
  312. //
  313. lboff = boff;
  314. cp = (PHCELL)((PUCHAR)cp + cellsize);
  315. boff += cellsize;
  316. //
  317. // scan ahead in bin, if cp has reached off end of block,
  318. // AND there's bin left to read.
  319. // do this BEFORE breaking out for boff at end.
  320. //
  321. while ((cp >= guard) && (binread < binsize))
  322. {
  323. // write out the currently loaded block
  324. wf = WriteFile (outfilehandle, buffer, HBLOCK_SIZE, &writecount, NULL);
  325. if ((!wf) || (writecount != HBLOCK_SIZE) )
  326. {
  327. closeFile (BOTHFILE);
  328. fprintf (stderr, "regfix: '%s' - cannot write block %d!\n", BlockNumb, outFileName);
  329. exit(1);
  330. }
  331. rf = ReadFile(infilehandle, buffer, HBLOCK_SIZE, &readcount, NULL);
  332. if ((!rf) || (readcount != HBLOCK_SIZE))
  333. {
  334. closeFile (BOTHFILE);
  335. fprintf(stderr, "hivestat: '%s' read error @%08lx\n", inFileName, hiveposition);
  336. exit(1);
  337. }
  338. BlockNumb++;
  339. cp = (PHCELL)((PUCHAR)cp - HBLOCK_SIZE);
  340. hiveposition += HBLOCK_SIZE;
  341. hoff += HBLOCK_SIZE;
  342. binread += HBLOCK_SIZE;
  343. ASSERT (hoff+HBLOCK_SIZE == hiveposition);
  344. }
  345. if (boff >= binsize)
  346. {
  347. break; // we are done with this bin
  348. }
  349. }
  350. wf = WriteFile (outfilehandle, buffer, HBLOCK_SIZE, &writecount, NULL);
  351. if ((!wf) || (writecount != HBLOCK_SIZE) )
  352. {
  353. closeFile (BOTHFILE);
  354. fprintf (stderr, "regfix: '%s' - cannot write block %d!\n", BlockNumb, outFileName);
  355. exit(1);
  356. }
  357. }
  358. return;
  359. }
  360. //---------------------------------------------------------
  361. // Description :
  362. // Given a pointer to an HCELL, check the SD type cell signature
  363. // If it is pass to the SD processing routines.
  364. // Note : framework is in place to handle other cell types
  365. //
  366. // Args :
  367. // Cell - Supplies a pointer to the HCELL
  368. //
  369. // CellSize - Supplies the size of the HCELL
  370. //
  371. // Return : Nothing
  372. //
  373. //---------------------------------------------------------
  374. void ScanCell (IN PHCELL Cell, IN ULONG CellSize)
  375. {
  376. PCELL_DATA Data;
  377. if (HiveVersion==1)
  378. {
  379. Data = (PCELL_DATA)&Cell->u.OldCell.u.UserData;
  380. }
  381. else
  382. {
  383. Data = (PCELL_DATA)&Cell->u.NewCell.u.UserData;
  384. }
  385. //
  386. // grovel through the data, see if we can find the SD keys
  387. //
  388. if ((Data->u.KeyNode.Signature == CM_KEY_NODE_SIGNATURE) &&
  389. (CellSize > sizeof(CM_KEY_NODE)))
  390. {
  391. //
  392. // probably a key node
  393. //
  394. return;
  395. }
  396. else if ((Data->u.KeyValue.Signature == CM_KEY_VALUE_SIGNATURE) &&
  397. (CellSize > sizeof(CM_KEY_VALUE)))
  398. {
  399. //
  400. // probably a key value
  401. //
  402. return;
  403. }
  404. else if ((Data->u.KeySecurity.Signature == CM_KEY_SECURITY_SIGNATURE) &&
  405. (CellSize > sizeof(CM_KEY_SECURITY)))
  406. {
  407. //
  408. // probably a security descriptor
  409. //
  410. DoKeySD (&Data->u.KeySecurity, CellSize);
  411. }
  412. else if ((Data->u.KeyIndex.Signature == CM_KEY_INDEX_ROOT) ||
  413. (Data->u.KeyIndex.Signature == CM_KEY_INDEX_LEAF))
  414. {
  415. //
  416. // probably a key index
  417. //
  418. return;
  419. }
  420. else
  421. {
  422. //
  423. // Nothing with a signature, could be either
  424. // name
  425. // key list
  426. // value data
  427. //
  428. return;
  429. }
  430. }
  431. //---------------------------------------------------------
  432. // Description :
  433. // Expects an SD cell pointer. Extracts the SD descriptor
  434. // and passes it on for further processing
  435. //
  436. // Args :
  437. // Security - Pointer to PCM_KEY_SECURITY type cell
  438. //
  439. // CellSize - size of the HCELL
  440. //
  441. // Return : Nothing
  442. //
  443. //---------------------------------------------------------
  444. void DoKeySD (IN PCM_KEY_SECURITY Security, IN ULONG CellSize)
  445. {
  446. PSECURITY_DESCRIPTOR pSD;
  447. SizeSDData += CellSize;
  448. NumSDData++;
  449. pSD = &Security->Descriptor;
  450. DumpSecurityDescriptor (pSD);
  451. }
  452. //---------------------------------------------------------
  453. // ** The following routines are hacks of the dumpsd
  454. // ** lib code in private\citrix\syslib
  455. // ** This util can easily be modified as a standalone
  456. // ** utility for a variety of hive security processing
  457. //---------------------------------------------------------
  458. //---------------------------------------------------------
  459. // Description :
  460. // Unfolds an SD descriptor passing SID and ACL pointers
  461. // for further processing
  462. //
  463. // Args :
  464. // pSD - Pointer to SECURITY_DESCRIPTOR structure
  465. //
  466. // Return : Nothing
  467. //
  468. //---------------------------------------------------------
  469. void DumpSecurityDescriptor (PSECURITY_DESCRIPTOR pSD)
  470. {
  471. PISECURITY_DESCRIPTOR p = (PISECURITY_DESCRIPTOR)pSD;
  472. PSID pSid;
  473. PACL pAcl;
  474. PCHAR pTmp;
  475. ULONG Size;
  476. /*
  477. DbgPrint ("DUMP_SECURITY_DESCRIPTOR: Revision %d, Sbz1 %d, Control 0x%x\n",
  478. p->Revision, p->Sbz1, p->Control );
  479. if (p->Control & SE_SELF_RELATIVE )
  480. {
  481. DbgPrint("Self Relative\n");
  482. }
  483. DbgPrint("PSID Owner 0x%x\n",p->Owner);
  484. */
  485. // If this is self relative, must offset the pointers
  486. if( p->Owner != NULL )
  487. {
  488. if (p->Control & SE_SELF_RELATIVE)
  489. {
  490. pTmp = (PCHAR)pSD;
  491. pTmp += (ULONG)p->Owner;
  492. CtxDumpSid ((PSID)pTmp, (PCHAR)p, &Size );
  493. }
  494. else
  495. {
  496. // can reference it directly
  497. CtxDumpSid (p->Owner, (PCHAR)p, &Size );
  498. }
  499. }
  500. /*
  501. DbgPrint("PSID Group 0x%x\n",p->Group);
  502. */
  503. // If this is self relative, must offset the pointers
  504. if (p->Group != NULL)
  505. {
  506. if (p->Control & SE_SELF_RELATIVE)
  507. {
  508. pTmp = (PCHAR)pSD;
  509. pTmp += (ULONG)p->Group;
  510. CtxDumpSid( (PSID)pTmp, (PCHAR)p, &Size );
  511. }
  512. else
  513. {
  514. // can reference it directly
  515. CtxDumpSid( p->Group, (PCHAR)p, &Size );
  516. }
  517. }
  518. // DbgPrint("\n");
  519. // DbgPrint("PACL Sacl 0x%x\n",p->Sacl);
  520. // If this is self relative, must offset the pointers
  521. if (p->Sacl != NULL)
  522. {
  523. if (p->Control & SE_SELF_RELATIVE)
  524. {
  525. pTmp = (PCHAR)pSD;
  526. pTmp += (ULONG)p->Sacl;
  527. DumpAcl( (PSID)pTmp, (PCHAR)p, &Size );
  528. }
  529. else
  530. {
  531. // can reference it directly
  532. DumpAcl (p->Sacl, (PCHAR)p, &Size);
  533. }
  534. }
  535. // DbgPrint("\n");
  536. // DbgPrint ("PACL Dacl 0x%x\n",p->Dacl);
  537. // If this is self relative, must offset the pointers
  538. if (p->Dacl != NULL)
  539. {
  540. if (p->Control & SE_SELF_RELATIVE)
  541. {
  542. pTmp = (PCHAR)pSD;
  543. pTmp += (ULONG)p->Dacl;
  544. DumpAcl( (PSID)pTmp, (PCHAR)p, &Size );
  545. }
  546. else
  547. {
  548. // can reference it directly
  549. DumpAcl( p->Dacl, (PCHAR)p, &Size );
  550. }
  551. }
  552. }
  553. //---------------------------------------------------------
  554. // Description :
  555. // Examine an SD descriptor for subauthority and owner
  556. // info
  557. //
  558. // Args :
  559. // pSid - Pointer to SID structure
  560. // pBase - not used (kept for historical reasons)
  561. // pSize - holds the SID size on return
  562. //
  563. // Return : Nothing
  564. //
  565. //---------------------------------------------------------
  566. void CtxDumpSid (
  567. PSID pSid,
  568. PCHAR pBase,
  569. PULONG pSize)
  570. {
  571. PISID p;
  572. ULONG i;
  573. BOOL OK;
  574. DWORD szUserName;
  575. DWORD szDomain;
  576. SID_NAME_USE UserSidType;
  577. WCHAR UserName[256];
  578. WCHAR Domain[256];
  579. ULONG Size = 0;
  580. p = (PISID)pSid;
  581. // DbgPrint("Revision %d, SubAuthorityCount %d\n", p->Revision, p->SubAuthorityCount);
  582. Size += 2; // Revision, SubAuthorityCount
  583. /*
  584. DbgPrint("IdentifierAuthority: %x %x %x %x %x %x\n",
  585. p->IdentifierAuthority.Value[0],
  586. p->IdentifierAuthority.Value[1],
  587. p->IdentifierAuthority.Value[2],
  588. p->IdentifierAuthority.Value[3],
  589. p->IdentifierAuthority.Value[4],
  590. p->IdentifierAuthority.Value[5] );
  591. */
  592. Size += 6; // IdentifierAuthority
  593. for (i=0; i < p->SubAuthorityCount; i++)
  594. {
  595. // DbgPrint("SubAuthority[%d] 0x%x\n", i, p->SubAuthority[i]);
  596. Size += sizeof(ULONG);
  597. }
  598. if (pSize)
  599. {
  600. *pSize = Size;
  601. }
  602. szUserName = sizeof (UserName);
  603. szDomain = sizeof (Domain);
  604. // Now print its account
  605. /*
  606. OK = LookupAccountSidW (
  607. NULL, // Computer Name
  608. pSid,
  609. UserName,
  610. &szUserName,
  611. Domain,
  612. &szDomain,
  613. &UserSidType);
  614. */
  615. // if (OK)
  616. // {
  617. // DbgPrint("Account Name %ws, Domain %ws, Type %d, SidSize %d\n",UserName,Domain,UserSidType,Size);
  618. // }
  619. // else
  620. // {
  621. // DbgPrint("Error looking up account name %d, SizeSid %d\n",GetLastError(),Size);
  622. // }
  623. }
  624. //---------------------------------------------------------
  625. // Description :
  626. // Unfolds an ACL dumping all the ACEs in the process
  627. // checking consistency by tracking the actual size
  628. //
  629. // Args :
  630. // pAcl - Pointer to ACL structure
  631. // pBase - not used (kept for historical reasons)
  632. // pSize - holds the size on return
  633. //
  634. // Return : Nothing
  635. //
  636. //---------------------------------------------------------
  637. void DumpAcl (PACL pAcl, PCHAR pBase, PULONG pSize)
  638. {
  639. USHORT i;
  640. PCHAR pTmp;
  641. ULONG Size, MySize;
  642. PACL p = pAcl;
  643. PCHAR pCur = (PCHAR)pAcl;
  644. MySize = 0;
  645. // DbgPrint ("AclRevision %d, Sbz1 %d, AclSize %d, AceCount %d, Sbz2 %d\n",
  646. // p->AclRevision, p->Sbz1, p->AclSize, p->AceCount, p->Sbz2);
  647. // bump over the ACL header to point to the first ACE
  648. pCur += sizeof (ACL);
  649. MySize += sizeof (ACL);
  650. for (i=0; i < p->AceCount; i++)
  651. {
  652. DumpAce ((PACE_HEADER)pCur, pBase, &Size );
  653. pCur += Size;
  654. MySize += Size;
  655. }
  656. // ACL consistency check
  657. if( p->AclSize != MySize )
  658. {
  659. //
  660. // HACK!HACK!HACK!
  661. // |
  662. // |
  663. // |
  664. // v
  665. if (p->AclSize == 1023) // This hack is in response to MS bug #1607. The hive load fails on ACL
  666. { // size alignment check. The sw hive file that causes this problem has
  667. p->AclSize = 1024; // about 3k SD entries of ACL size 1023. This hack adjusts this.
  668. }
  669. // ^
  670. // |
  671. // |
  672. // |
  673. // |
  674. // HACK!HACK!HACK!
  675. // DbgPrint("Inconsistent ACL Entry! p->AclSize %d, RealSize %d\n",p->AclSize,MySize);
  676. // p->AclSize = MySize;
  677. BadACL++;
  678. }
  679. // return the size of this ACL
  680. *pSize = MySize;
  681. return;
  682. }
  683. //---------------------------------------------------------
  684. // Description :
  685. // Unfolds an ACE descriptor checking consistency by
  686. // tracking the actual size
  687. //
  688. // Args :
  689. // pAce - Pointer to ACE structure
  690. // pBase - not used (kept for historical reasons)
  691. // pSize - holds the size on return
  692. //
  693. // Return : Nothing
  694. //
  695. //---------------------------------------------------------
  696. void DumpAce (PACE_HEADER pAce,
  697. PCHAR pBase,
  698. PULONG pSize)
  699. {
  700. PACE_HEADER p = pAce;
  701. PACCESS_ALLOWED_ACE pAl;
  702. PACCESS_DENIED_ACE pAd;
  703. PSYSTEM_AUDIT_ACE pSa;
  704. PSYSTEM_ALARM_ACE pSl;
  705. PCHAR pTmp;
  706. ULONG MySize, Size, saveSize;
  707. // DbgPrint ("ACE_HEADER: Type %d, Flags 0x%x, Size %d\n",
  708. // p->AceType, p->AceFlags, p->AceSize );
  709. switch (p->AceType)
  710. {
  711. case ACCESS_ALLOWED_ACE_TYPE:
  712. pAl = (PACCESS_ALLOWED_ACE)p;
  713. // DbgPrint("ACCESS_ALLOWED_ACE: AccessMask 0x%x, Sid 0x%x\n",pAl->Mask,pAl->SidStart);
  714. MySize = sizeof(ACCESS_ALLOWED_ACE);
  715. if (pAl->SidStart)
  716. {
  717. pTmp = (PCHAR)&pAl->SidStart;
  718. CtxDumpSid( (PSID)pTmp, pBase, &Size );
  719. MySize += Size;
  720. // Adjust for the first ULONG of the ACE
  721. // being part of the Sid
  722. MySize -= sizeof(ULONG);
  723. }
  724. break;
  725. case ACCESS_DENIED_ACE_TYPE:
  726. pAd = (PACCESS_DENIED_ACE)p;
  727. // DbgPrint("ACCESS_DENIED_ACE: AccessMask 0x%x, Sid 0x%x\n",pAd->Mask,pAd->SidStart);
  728. MySize = sizeof(ACCESS_DENIED_ACE);
  729. if (pAd->SidStart)
  730. {
  731. pTmp = (PCHAR)&pAd->SidStart;
  732. CtxDumpSid( (PSID)pTmp, pBase, &Size );
  733. MySize += Size;
  734. // Adjust for the first ULONG of the ACE
  735. // being part of the Sid
  736. MySize -= sizeof(ULONG);
  737. }
  738. break;
  739. case SYSTEM_AUDIT_ACE_TYPE:
  740. pSa = (PSYSTEM_AUDIT_ACE)p;
  741. // DbgPrint("SYSTEM_AUDIT_ACE: AccessMask 0x%x, Sid 0x%x\n",pSa->Mask,pSa->SidStart);
  742. MySize = sizeof(SYSTEM_AUDIT_ACE);
  743. if ( pSa->SidStart )
  744. {
  745. pTmp = (PCHAR)&pSa->SidStart;
  746. CtxDumpSid( (PSID)pTmp, pBase, &Size );
  747. MySize += Size;
  748. // Adjust for the first ULONG of the ACE
  749. // being part of the Sid
  750. MySize -= sizeof(ULONG);
  751. }
  752. break;
  753. case SYSTEM_ALARM_ACE_TYPE:
  754. pSl = (PSYSTEM_ALARM_ACE)p;
  755. // DbgPrint("SYSTEM_ALARM_ACE: AccessMask 0x%x, Sid 0x%x\n",pSl->Mask,pSl->SidStart);
  756. MySize = sizeof(SYSTEM_ALARM_ACE);
  757. if (pSl->SidStart)
  758. {
  759. pTmp = (PCHAR)&pSl->SidStart;
  760. CtxDumpSid( (PSID)pTmp, pBase, &Size );
  761. MySize += Size;
  762. // Adjust for the first ULONG of the ACE
  763. // being part of the Sid
  764. MySize -= sizeof(ULONG);
  765. }
  766. break;
  767. default:
  768. break;
  769. // DbgPrint("Unknown ACE type %d\n", p->AceType);
  770. }
  771. saveSize = p->AceSize;
  772. // Check its consistency
  773. if ( p->AceSize != MySize )
  774. {
  775. // DbgPrint("Inconsistent ACE Entry! p->AceSize %d, RealSize %d\n",p->AceSize,MySize);
  776. // p->AceSize = MySize;
  777. BadACE++;
  778. }
  779. // return the size so the caller can update the pointer
  780. // *pSize = p->AceSize;
  781. *pSize = saveSize;
  782. // DbgPrint("\n");
  783. return;
  784. }
  785. /*******************************************************************************
  786. *
  787. * AreWeRunningTerminalServices
  788. *
  789. * Check if we are running terminal server
  790. *
  791. * ENTRY:
  792. *
  793. * EXIT: BOOL: True if we are running Terminal Services False if we
  794. * are not running Terminal Services
  795. *
  796. *
  797. ******************************************************************************/
  798. BOOL AreWeRunningTerminalServices(void)
  799. {
  800. OSVERSIONINFOEX osVersionInfo;
  801. DWORDLONG dwlConditionMask = 0;
  802. ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
  803. osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  804. osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
  805. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  806. return VerifyVersionInfo(
  807. &osVersionInfo,
  808. VER_SUITENAME,
  809. dwlConditionMask
  810. );
  811. }