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.

1119 lines
33 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. sddump.c
  5. Abstract:
  6. Debugger Extension Api
  7. Author:
  8. Baskar Kothandaraman (baskark) 26-Jan-1998
  9. Environment:
  10. Kernel Mode
  11. Revision History:
  12. Kshitiz K. Sharma (kksharma)
  13. Using debugger type info : SID and ACL have exactly same type definitions on
  14. all platforms - No change.
  15. --*/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. /*
  19. +-------------------------------------------------------------------+
  20. NAME: sid_successfully_read
  21. FUNCTION: Tries to read in a SID from the specified address.
  22. It first reads in the minimal structure, then
  23. allocates a buffer big enough to hold the whole sid
  24. & reads in the whole SID....
  25. ARGS: Address -- Address from which to read it from
  26. sid_buffer -- variable to receive the ptr to the
  27. allocated buffer with the SID.
  28. RETURN: TRUE on success, FALSE otherwise.
  29. NOTE***: The caller has to call free(*sid_buffer) to free
  30. up the memory upon a successful call to this
  31. function.
  32. +-------------------------------------------------------------------+
  33. */
  34. BOOLEAN sid_successfully_read(
  35. ULONG64 Address,
  36. PSID *sid_buffer
  37. )
  38. {
  39. ULONG result;
  40. SID minimum; /* minimum we need to read to get the details */
  41. *sid_buffer = NULL;
  42. if ( !ReadMemory( Address,
  43. &minimum,
  44. sizeof(minimum),
  45. &result) )
  46. {
  47. dprintf("%08p: Unable to get MIN SID header\n", Address);
  48. return FALSE;
  49. }
  50. /* Now of read-in any extra sub-authorities necessary */
  51. if (minimum.SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
  52. {
  53. dprintf("SID has an invalid sub-authority_count, 0x%x\n", minimum.SubAuthorityCount);
  54. return FALSE;
  55. }
  56. else
  57. {
  58. ULONG size_to_read = RtlLengthRequiredSid(minimum.SubAuthorityCount);
  59. *sid_buffer = malloc(size_to_read);
  60. if (! *sid_buffer)
  61. {
  62. dprintf("SID: can't allocate memory to read\n");
  63. return FALSE;
  64. }
  65. if ( !ReadMemory( Address,
  66. *sid_buffer,
  67. size_to_read,
  68. &result) )
  69. {
  70. dprintf("%08p: Unable to get The Whole SID\n", Address);
  71. free(*sid_buffer);
  72. *sid_buffer = NULL;
  73. return FALSE;
  74. }
  75. if (! RtlValidSid(*sid_buffer))
  76. {
  77. dprintf("%08p: SID pointed to by this address is invalid\n", Address);
  78. free(*sid_buffer);
  79. *sid_buffer = NULL;
  80. return FALSE;
  81. }
  82. }
  83. return TRUE;
  84. }
  85. /*
  86. +-------------------------------------------------------------------+
  87. NAME: acl_successfully_read
  88. FUNCTION: Tries to read in a ACL from the specified address.
  89. It first reads in the minimal structure, then
  90. allocates a buffer big enough to hold the whole acl
  91. & reads in the whole ACL....
  92. ARGS: Address -- Address from which to read it from
  93. acl_buffer -- variable to receive the ptr to the
  94. allocated buffer with the ACL.
  95. RETURN: TRUE on success, FALSE otherwise.
  96. NOTE***: The caller has to call free(*acl_buffer) to free
  97. up the memory upon a successful call to this
  98. function.
  99. +-------------------------------------------------------------------+
  100. */
  101. BOOLEAN acl_successfully_read(
  102. ULONG64 Address,
  103. PACL *acl_buffer
  104. )
  105. {
  106. ULONG result;
  107. ACL minimum; /* minimum we need to read to get the details */
  108. *acl_buffer = NULL;
  109. if ( !ReadMemory( Address,
  110. &minimum,
  111. sizeof(minimum),
  112. &result) )
  113. {
  114. dprintf("%08p: Unable to get MIN ACL header\n", Address);
  115. return FALSE;
  116. }
  117. *acl_buffer = malloc(minimum.AclSize);
  118. if (! *acl_buffer)
  119. {
  120. dprintf("ACL: can't allocate memory to read\n");
  121. return FALSE;
  122. }
  123. if ( !ReadMemory( Address,
  124. *acl_buffer,
  125. minimum.AclSize,
  126. &result) )
  127. {
  128. dprintf("%08p: Unable to get The Whole ACL\n", Address);
  129. free(*acl_buffer);
  130. *acl_buffer = NULL;
  131. return FALSE;
  132. }
  133. if (! RtlValidAcl(*acl_buffer))
  134. {
  135. dprintf("%08p: ACL pointed to by this address is invalid\n", Address);
  136. free(*acl_buffer);
  137. *acl_buffer = NULL;
  138. return FALSE;
  139. }
  140. return TRUE;
  141. }
  142. /*
  143. +-------------------------------------------------------------------+
  144. NAME: DumpSID
  145. FUNCTION: Prints out a SID, with the padding provided.
  146. ARGS: pad -- Padding to print before the SID.
  147. sid_to_dump -- Pointer to the SID to print.
  148. Flag -- To control options.
  149. RETURN: N/A
  150. NOTE***: It right now, doesn't lookup the sid.
  151. In future, you might want ot use the Flag
  152. parameter to make that optional.
  153. +-------------------------------------------------------------------+
  154. */
  155. VOID DumpSID(
  156. CHAR *pad,
  157. PSID sid_to_dump,
  158. ULONG Flag
  159. )
  160. {
  161. NTSTATUS ntstatus;
  162. UNICODE_STRING us;
  163. if (sid_to_dump)
  164. {
  165. ntstatus = RtlConvertSidToUnicodeString(&us, sid_to_dump, TRUE);
  166. if (NT_SUCCESS(ntstatus))
  167. {
  168. dprintf("%s%wZ", pad, &us);
  169. RtlFreeUnicodeString(&us);
  170. }
  171. else
  172. {
  173. dprintf("0x%08lx: Can't Convert SID to UnicodeString", ntstatus);
  174. }
  175. }
  176. else
  177. {
  178. dprintf("%s is NULL", pad);
  179. }
  180. if (Flag & 1) {
  181. PCSTR pszStr;
  182. dprintf(" ");
  183. pszStr = ConvertSidToFriendlyName(sid_to_dump, "(%s: %s\\%s)");
  184. if (pszStr && *pszStr) {
  185. dprintf(pszStr);
  186. }
  187. }
  188. dprintf("\n");
  189. }
  190. /*
  191. +-------------------------------------------------------------------+
  192. NAME: DumpACL
  193. FUNCTION: Prints out a ACL, with the padding provided.
  194. ARGS: pad -- Padding to print before the ACL.
  195. acl_to_dump -- Pointer to the ACL to print.
  196. Flag -- To control options.
  197. Start -- Actual start address of the Acl
  198. RETURN: N/A
  199. +-------------------------------------------------------------------+
  200. */
  201. BOOL
  202. DumpACL (
  203. IN char *pad,
  204. IN ACL *pacl,
  205. IN ULONG Flags,
  206. IN ULONG64 Start
  207. )
  208. {
  209. USHORT x;
  210. if (pacl == NULL)
  211. {
  212. dprintf("%s is NULL\n", pad);
  213. return FALSE;
  214. }
  215. dprintf("%s\n", pad);
  216. dprintf("%s->AclRevision: 0x%x\n", pad, pacl->AclRevision);
  217. dprintf("%s->Sbz1 : 0x%x\n", pad, pacl->Sbz1);
  218. dprintf("%s->AclSize : 0x%x\n", pad, pacl->AclSize);
  219. dprintf("%s->AceCount : 0x%x\n", pad, pacl->AceCount);
  220. dprintf("%s->Sbz2 : 0x%x\n", pad, pacl->Sbz2);
  221. for (x = 0; x < pacl->AceCount; x ++)
  222. {
  223. PACE_HEADER ace;
  224. CHAR temp_pad[MAX_PATH];
  225. NTSTATUS result;
  226. _snprintf(temp_pad, sizeof(temp_pad), "%s->Ace[%u]: ", pad, x);
  227. result = RtlGetAce(pacl, x, &ace);
  228. if (! NT_SUCCESS(result))
  229. {
  230. dprintf("%sCan't GetAce, 0x%08lx\n", temp_pad, result);
  231. return FALSE;
  232. }
  233. dprintf("%s->AceType: ", temp_pad);
  234. #define BRANCH_AND_PRINT(x) case x: dprintf(#x "\n"); break
  235. switch (ace->AceType)
  236. {
  237. BRANCH_AND_PRINT(ACCESS_ALLOWED_ACE_TYPE);
  238. BRANCH_AND_PRINT(ACCESS_DENIED_ACE_TYPE);
  239. BRANCH_AND_PRINT(SYSTEM_AUDIT_ACE_TYPE);
  240. BRANCH_AND_PRINT(SYSTEM_ALARM_ACE_TYPE);
  241. BRANCH_AND_PRINT(ACCESS_ALLOWED_COMPOUND_ACE_TYPE);
  242. BRANCH_AND_PRINT(ACCESS_ALLOWED_OBJECT_ACE_TYPE);
  243. BRANCH_AND_PRINT(ACCESS_DENIED_OBJECT_ACE_TYPE);
  244. BRANCH_AND_PRINT(SYSTEM_AUDIT_OBJECT_ACE_TYPE);
  245. BRANCH_AND_PRINT(SYSTEM_ALARM_OBJECT_ACE_TYPE);
  246. BRANCH_AND_PRINT(ACCESS_ALLOWED_CALLBACK_ACE_TYPE);
  247. BRANCH_AND_PRINT(ACCESS_DENIED_CALLBACK_ACE_TYPE);
  248. BRANCH_AND_PRINT(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE);
  249. BRANCH_AND_PRINT(ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE);
  250. BRANCH_AND_PRINT(SYSTEM_AUDIT_CALLBACK_ACE_TYPE);
  251. BRANCH_AND_PRINT(SYSTEM_ALARM_CALLBACK_ACE_TYPE);
  252. BRANCH_AND_PRINT(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE);
  253. BRANCH_AND_PRINT(SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE);
  254. default:
  255. dprintf("0x%08lx <-- *** Unknown AceType\n", ace->AceType);
  256. continue; // With the next ace
  257. }
  258. #undef BRANCH_AND_PRINT
  259. dprintf("%s->AceFlags: 0x%x\n", temp_pad, ace->AceFlags);
  260. #define BRANCH_AND_PRINT(x) if (ace->AceFlags & x){ dprintf("%s %s\n", temp_pad, #x); }
  261. BRANCH_AND_PRINT(OBJECT_INHERIT_ACE)
  262. BRANCH_AND_PRINT(CONTAINER_INHERIT_ACE)
  263. BRANCH_AND_PRINT(NO_PROPAGATE_INHERIT_ACE)
  264. BRANCH_AND_PRINT(INHERIT_ONLY_ACE)
  265. BRANCH_AND_PRINT(INHERITED_ACE)
  266. BRANCH_AND_PRINT(SUCCESSFUL_ACCESS_ACE_FLAG)
  267. BRANCH_AND_PRINT(FAILED_ACCESS_ACE_FLAG)
  268. #undef BRANCH_AND_PRINT
  269. dprintf("%s->AceSize: 0x%x\n", temp_pad, ace->AceSize);
  270. /*
  271. From now on it is ace specific stuff.
  272. Fortunately ACEs can be split into 3 groups,
  273. with the ACE structure being the same within the group
  274. Added 8 more ace types for callback support.
  275. */
  276. switch (ace->AceType)
  277. {
  278. case ACCESS_ALLOWED_ACE_TYPE:
  279. case ACCESS_DENIED_ACE_TYPE:
  280. case SYSTEM_AUDIT_ACE_TYPE:
  281. case SYSTEM_ALARM_ACE_TYPE:
  282. {
  283. CHAR more_pad[MAX_PATH];
  284. SYSTEM_AUDIT_ACE *tace = (SYSTEM_AUDIT_ACE *) ace;
  285. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  286. _snprintf(more_pad, sizeof(more_pad), "%s->SID: ", temp_pad);
  287. DumpSID(more_pad, &(tace->SidStart), Flags);
  288. }
  289. break;
  290. case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
  291. case ACCESS_DENIED_CALLBACK_ACE_TYPE:
  292. case SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
  293. case SYSTEM_ALARM_CALLBACK_ACE_TYPE:
  294. {
  295. CHAR more_pad[MAX_PATH];
  296. SYSTEM_AUDIT_ACE *tace = (SYSTEM_AUDIT_ACE *) ace;
  297. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  298. _snprintf(more_pad, sizeof(more_pad), "%s->SID: ", temp_pad);
  299. DumpSID(more_pad, &(tace->SidStart), Flags);
  300. dprintf("%s->Address : %08p\n", temp_pad, Start + (ULONG) (((PUCHAR) ace) - ((PUCHAR) pacl)));
  301. }
  302. break;
  303. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  304. {
  305. CHAR more_pad[MAX_PATH];
  306. COMPOUND_ACCESS_ALLOWED_ACE *tace = (COMPOUND_ACCESS_ALLOWED_ACE *) ace;
  307. PBYTE ptr;
  308. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  309. dprintf("%s->CompoundAceType : 0x%08lx\n", temp_pad, tace->CompoundAceType);
  310. dprintf("%s->Reserved : 0x%08lx\n", temp_pad, tace->Reserved);
  311. _snprintf(more_pad, sizeof(more_pad), "%s->SID(1) : ", temp_pad);
  312. DumpSID(more_pad, &(tace->SidStart), Flags);
  313. ptr = (PBYTE)&(tace->SidStart);
  314. ptr += RtlLengthSid((PSID)ptr); /* Skip this & get to next sid */
  315. _snprintf(more_pad, sizeof(more_pad), "%s->SID(2) : ", temp_pad);
  316. DumpSID(more_pad, ptr, Flags);
  317. }
  318. break;
  319. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  320. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  321. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  322. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  323. {
  324. CHAR more_pad[MAX_PATH];
  325. ACCESS_ALLOWED_OBJECT_ACE *tace = (ACCESS_ALLOWED_OBJECT_ACE *) ace;
  326. PBYTE ptr;
  327. GUID *obj_guid = NULL, *inh_obj_guid = NULL;
  328. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  329. dprintf("%s->Flags : 0x%08lx\n", temp_pad, tace->Flags);
  330. ptr = (PBYTE)&(tace->ObjectType);
  331. if (tace->Flags & ACE_OBJECT_TYPE_PRESENT)
  332. {
  333. dprintf("%s : ACE_OBJECT_TYPE_PRESENT\n", temp_pad);
  334. obj_guid = &(tace->ObjectType);
  335. ptr = (PBYTE)&(tace->InheritedObjectType);
  336. }
  337. if (tace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  338. {
  339. dprintf("%s : ACE_INHERITED_OBJECT_TYPE_PRESENT\n", temp_pad);
  340. inh_obj_guid = &(tace->InheritedObjectType);
  341. ptr = (PBYTE)&(tace->SidStart);
  342. }
  343. if (obj_guid)
  344. {
  345. dprintf("%s->ObjectType : (in HEX)", temp_pad);
  346. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  347. obj_guid->Data1,
  348. obj_guid->Data2,
  349. obj_guid->Data3,
  350. obj_guid->Data4[0],
  351. obj_guid->Data4[1],
  352. obj_guid->Data4[2],
  353. obj_guid->Data4[3],
  354. obj_guid->Data4[4],
  355. obj_guid->Data4[5],
  356. obj_guid->Data4[6],
  357. obj_guid->Data4[7]
  358. );
  359. }
  360. if (inh_obj_guid)
  361. {
  362. dprintf("%s->InhObjTYpe : (in HEX)", temp_pad);
  363. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  364. inh_obj_guid->Data1,
  365. inh_obj_guid->Data2,
  366. inh_obj_guid->Data3,
  367. inh_obj_guid->Data4[0],
  368. inh_obj_guid->Data4[1],
  369. inh_obj_guid->Data4[2],
  370. inh_obj_guid->Data4[3],
  371. inh_obj_guid->Data4[4],
  372. inh_obj_guid->Data4[5],
  373. inh_obj_guid->Data4[6],
  374. inh_obj_guid->Data4[7]
  375. );
  376. }
  377. _snprintf(more_pad, sizeof(more_pad), "%s->SID : ", temp_pad);
  378. DumpSID(more_pad, ptr, Flags);
  379. }
  380. break;
  381. case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
  382. case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
  383. case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
  384. case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE:
  385. {
  386. CHAR more_pad[MAX_PATH];
  387. ACCESS_ALLOWED_OBJECT_ACE *tace = (ACCESS_ALLOWED_OBJECT_ACE *) ace;
  388. PBYTE ptr;
  389. GUID *obj_guid = NULL, *inh_obj_guid = NULL;
  390. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  391. dprintf("%s->Flags : 0x%08lx\n", temp_pad, tace->Flags);
  392. ptr = (PBYTE)&(tace->ObjectType);
  393. if (tace->Flags & ACE_OBJECT_TYPE_PRESENT)
  394. {
  395. dprintf("%s : ACE_OBJECT_TYPE_PRESENT\n", temp_pad);
  396. obj_guid = &(tace->ObjectType);
  397. ptr = (PBYTE)&(tace->InheritedObjectType);
  398. }
  399. if (tace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  400. {
  401. dprintf("%s : ACE_INHERITED_OBJECT_TYPE_PRESENT\n", temp_pad);
  402. inh_obj_guid = &(tace->InheritedObjectType);
  403. ptr = (PBYTE)&(tace->SidStart);
  404. }
  405. if (obj_guid)
  406. {
  407. dprintf("%s->ObjectType : (in HEX)", temp_pad);
  408. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  409. obj_guid->Data1,
  410. obj_guid->Data2,
  411. obj_guid->Data3,
  412. obj_guid->Data4[0],
  413. obj_guid->Data4[1],
  414. obj_guid->Data4[2],
  415. obj_guid->Data4[3],
  416. obj_guid->Data4[4],
  417. obj_guid->Data4[5],
  418. obj_guid->Data4[6],
  419. obj_guid->Data4[7]
  420. );
  421. }
  422. if (inh_obj_guid)
  423. {
  424. dprintf("%s->InhObjTYpe : (in HEX)", temp_pad);
  425. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  426. inh_obj_guid->Data1,
  427. inh_obj_guid->Data2,
  428. inh_obj_guid->Data3,
  429. inh_obj_guid->Data4[0],
  430. inh_obj_guid->Data4[1],
  431. inh_obj_guid->Data4[2],
  432. inh_obj_guid->Data4[3],
  433. inh_obj_guid->Data4[4],
  434. inh_obj_guid->Data4[5],
  435. inh_obj_guid->Data4[6],
  436. inh_obj_guid->Data4[7]
  437. );
  438. }
  439. _snprintf(more_pad, sizeof(more_pad), "%s->SID : ", temp_pad);
  440. DumpSID(more_pad, ptr, Flags);
  441. dprintf("%s->Address : %08p\n", temp_pad, Start + (ULONG) (((PUCHAR) ace) - ((PUCHAR) pacl)));
  442. }
  443. break;
  444. }
  445. dprintf("\n");
  446. }
  447. return TRUE;
  448. }
  449. /*
  450. +-------------------------------------------------------------------+
  451. NAME: DumpSD
  452. FUNCTION: Prints out a Security Descriptor,
  453. with the padding provided.
  454. ARGS: pad -- Padding to print before the ACL.
  455. sd_to_dump -- Pointer to the ACL to print.
  456. owner -- Ptr to Owner SID
  457. group -- Ptr to Group SID
  458. dacl -- Ptr to DACL
  459. sacl -- Ptr to SACL
  460. Flag -- To control options.
  461. dacl_address -- Actual start address of the dacl
  462. sacl_address -- Actual start address of the sacl
  463. RETURN: N/A
  464. +-------------------------------------------------------------------+
  465. */
  466. BOOL
  467. DumpSD (
  468. IN char *pad,
  469. IN ULONG64 sd_to_dump,
  470. IN PSID owner,
  471. IN PSID group,
  472. IN PACL dacl,
  473. IN PACL sacl,
  474. IN ULONG Flags,
  475. IN ULONG64 dacl_address,
  476. IN ULONG64 sacl_address
  477. )
  478. {
  479. ULONG Control;
  480. InitTypeRead(sd_to_dump, SECURITY_DESCRIPTOR);
  481. Control = (ULONG) ReadField(Control);
  482. #define CHECK_SD_CONTROL_FOR(x)\
  483. if (Control & x)\
  484. {\
  485. dprintf("%s %s\n", pad, #x);\
  486. }\
  487. dprintf("%s->Revision: 0x%x\n", pad, (ULONG) ReadField(Revision));
  488. dprintf("%s->Sbz1 : 0x%x\n", pad, (ULONG) ReadField(Sbz1));
  489. dprintf("%s->Control : 0x%x\n", pad, (ULONG) ReadField(Control));
  490. CHECK_SD_CONTROL_FOR(SE_OWNER_DEFAULTED)
  491. CHECK_SD_CONTROL_FOR(SE_GROUP_DEFAULTED)
  492. CHECK_SD_CONTROL_FOR(SE_DACL_PRESENT)
  493. CHECK_SD_CONTROL_FOR(SE_DACL_DEFAULTED)
  494. CHECK_SD_CONTROL_FOR(SE_SACL_PRESENT)
  495. CHECK_SD_CONTROL_FOR(SE_SACL_DEFAULTED)
  496. CHECK_SD_CONTROL_FOR(SE_DACL_UNTRUSTED)
  497. CHECK_SD_CONTROL_FOR(SE_SERVER_SECURITY)
  498. CHECK_SD_CONTROL_FOR(SE_DACL_AUTO_INHERIT_REQ)
  499. CHECK_SD_CONTROL_FOR(SE_SACL_AUTO_INHERIT_REQ)
  500. CHECK_SD_CONTROL_FOR(SE_DACL_AUTO_INHERITED)
  501. CHECK_SD_CONTROL_FOR(SE_SACL_AUTO_INHERITED)
  502. CHECK_SD_CONTROL_FOR(SE_DACL_PROTECTED)
  503. CHECK_SD_CONTROL_FOR(SE_SACL_PROTECTED)
  504. CHECK_SD_CONTROL_FOR(SE_SELF_RELATIVE)
  505. {
  506. CHAR temp_pad[MAX_PATH];
  507. _snprintf(temp_pad, sizeof(temp_pad), "%s->Owner : ", pad);
  508. DumpSID(temp_pad, owner, Flags);
  509. _snprintf(temp_pad, sizeof(temp_pad), "%s->Group : ", pad);
  510. DumpSID(temp_pad, group, Flags);
  511. _snprintf(temp_pad, sizeof(temp_pad), "%s->Dacl : ", pad);
  512. DumpACL(temp_pad, dacl, Flags, dacl_address);
  513. _snprintf(temp_pad, sizeof(temp_pad), "%s->Sacl : ", pad);
  514. DumpACL(temp_pad, sacl, Flags, sacl_address);
  515. }
  516. #undef CHECK_SD_CONTROL_FOR
  517. return TRUE;
  518. }
  519. /*
  520. +-------------------------------------------------------------------+
  521. NAME: sd
  522. FUNCTION: Reads in & prints the security descriptor, from
  523. the address specified. !sd command's workhorse.
  524. ARGS: Standard Debugger extensions, refer to DECLARE_API
  525. macro in the header files.
  526. +-------------------------------------------------------------------+
  527. */
  528. DECLARE_API( sd )
  529. {
  530. ULONG64 Address;
  531. ULONG Flags;
  532. ULONG result;
  533. PACL dacl = NULL, sacl = NULL;
  534. ULONG64 dacl_address;
  535. ULONG64 sacl_address;
  536. // SECURITY_DESCRIPTOR sd_to_dump;
  537. PSID owner_sid = NULL, group_sid = NULL;
  538. ULONG Control;
  539. Address = 0;
  540. Flags = 6;
  541. GetExpressionEx(args, &Address, &args);
  542. if (args && *args) Flags = (ULONG) GetExpression(args);
  543. if (Address == 0) {
  544. dprintf("usage: !sd <SecurityDescriptor-address>\n");
  545. goto CLEANUP;
  546. }
  547. if ( GetFieldValue( Address,
  548. "SECURITY_DESCRIPTOR",
  549. "Control",
  550. Control) ) {
  551. dprintf("%08p: Unable to get SD contents\n", Address);
  552. goto CLEANUP;
  553. }
  554. if (Control & SE_SELF_RELATIVE)
  555. {
  556. ULONG dacl_offset, sacl_offset;
  557. InitTypeRead(Address, SECURITY_DESCRIPTOR_RELATIVE);
  558. dacl_offset = (ULONG) ReadField(Dacl);
  559. sacl_offset = (ULONG) ReadField(Sacl);
  560. if (!(Control & SE_OWNER_DEFAULTED)) /* read in the owner */
  561. {
  562. ULONG owner_offset = (ULONG) ReadField(Owner);
  563. if (owner_offset != 0)
  564. {
  565. ULONG64 owner_address = Address + owner_offset;
  566. if (! sid_successfully_read(owner_address, & owner_sid))
  567. {
  568. dprintf("%08p: Unable to read in Owner in SD\n", owner_address);
  569. goto CLEANUP;
  570. }
  571. }
  572. }
  573. if (!(Control & SE_GROUP_DEFAULTED)) /* read in the group */
  574. {
  575. ULONG group_offset = (ULONG) ReadField(Group);
  576. if (group_offset != 0)
  577. {
  578. ULONG64 group_address = Address + group_offset;
  579. if (! sid_successfully_read(group_address, & group_sid))
  580. {
  581. dprintf("%08p: Unable to read in Group in SD\n", group_address);
  582. goto CLEANUP;
  583. }
  584. }
  585. }
  586. if ((Control & SE_DACL_PRESENT) &&
  587. (dacl_offset != 0))
  588. {
  589. dacl_address = Address + dacl_offset;
  590. if (! acl_successfully_read(dacl_address, & dacl))
  591. {
  592. dprintf("%08p: Unable to read in Dacl in SD\n", dacl_address);
  593. goto CLEANUP;
  594. }
  595. }
  596. if ((Control & SE_SACL_PRESENT) &&
  597. (sacl_offset != 0))
  598. {
  599. sacl_address = Address + sacl_offset;
  600. if (! acl_successfully_read(sacl_address, & sacl))
  601. {
  602. dprintf("%08p: Unable to read in Sacl in SD\n", sacl_address);
  603. goto CLEANUP;
  604. }
  605. }
  606. }
  607. else
  608. {
  609. ULONG64 Dacl, Sacl;
  610. InitTypeRead(Address, SECURITY_DESCRIPTOR);
  611. Dacl = ReadField(Dacl);
  612. Sacl = ReadField(Sacl);
  613. if (!(Control & SE_OWNER_DEFAULTED)) /* read in the owner */
  614. {
  615. ULONG64 owner_address = ReadField(Owner);
  616. if (owner_address != 0 &&
  617. ! sid_successfully_read(owner_address, & owner_sid))
  618. {
  619. dprintf("%08p: Unable to read in Owner in SD\n", owner_address);
  620. goto CLEANUP;
  621. }
  622. }
  623. if (!(Control & SE_GROUP_DEFAULTED)) /* read in the group */
  624. {
  625. ULONG64 group_address = ReadField(Group);
  626. if (group_address != 0 &&
  627. ! sid_successfully_read(group_address, & group_sid))
  628. {
  629. dprintf("%08p: Unable to read in Group in SD\n", group_address);
  630. goto CLEANUP;
  631. }
  632. }
  633. if ((Control & SE_DACL_PRESENT) &&
  634. (Dacl != 0))
  635. {
  636. dacl_address = Dacl;
  637. if (! acl_successfully_read(dacl_address, & dacl))
  638. {
  639. dprintf("%08p: Unable to read in Dacl in SD\n", dacl_address);
  640. goto CLEANUP;
  641. }
  642. }
  643. if ((Control & SE_SACL_PRESENT) &&
  644. (Sacl != 0))
  645. {
  646. sacl_address = (Sacl);
  647. if (! acl_successfully_read(sacl_address, & sacl))
  648. {
  649. dprintf("%08p: Unable to read in Sacl in SD\n", sacl_address);
  650. goto CLEANUP;
  651. }
  652. }
  653. }
  654. DumpSD("", Address, owner_sid, group_sid, dacl, sacl, Flags, dacl_address, sacl_address);
  655. CLEANUP:
  656. if (owner_sid)
  657. {
  658. free(owner_sid);
  659. }
  660. if (group_sid)
  661. {
  662. free(group_sid);
  663. }
  664. if (dacl)
  665. {
  666. free(dacl);
  667. }
  668. if (sacl)
  669. {
  670. free(sacl);
  671. }
  672. return S_OK;
  673. }
  674. PSTR g_SidAttrType = "nt!_SID_AND_ATTRIBUTES";
  675. ULONG64
  676. GetSidAddr(ULONG64 BaseAddress)
  677. {
  678. ULONG64 Addr;
  679. if (GetFieldValue(BaseAddress, g_SidAttrType, "Sid", Addr))
  680. {
  681. dprintf("Cannot read %s.Sid @ %p\n", g_SidAttrType, BaseAddress);
  682. return 0;
  683. }
  684. return Addr;
  685. }
  686. ULONG
  687. GetSidAttributes(ULONG64 BaseAddress)
  688. {
  689. ULONG Attributes;
  690. if (GetFieldValue(BaseAddress, g_SidAttrType, "Attributes", Attributes))
  691. {
  692. dprintf("Cannot read %s.Attributes @%p\n", g_SidAttrType, BaseAddress);
  693. return 0;
  694. }
  695. return Attributes;
  696. }
  697. typedef
  698. BOOL
  699. (* PFuncLookupAccountSidA)(
  700. IN LPCSTR lpSystemName,
  701. IN PSID Sid,
  702. OUT LPSTR Name,
  703. IN OUT LPDWORD cbName,
  704. OUT LPSTR ReferencedDomainName,
  705. IN OUT LPDWORD cbReferencedDomainName,
  706. OUT PSID_NAME_USE peUse
  707. );
  708. BOOL
  709. WINAPI
  710. LsaLookupAccountSidA(
  711. IN LPCSTR lpSystemName,
  712. IN PSID Sid,
  713. OUT LPSTR Name,
  714. IN OUT LPDWORD cbName,
  715. OUT LPSTR ReferencedDomainName,
  716. IN OUT LPDWORD cbReferencedDomainName,
  717. OUT PSID_NAME_USE peUse
  718. )
  719. {
  720. PFuncLookupAccountSidA pFuncLookupAccountSidA = NULL;
  721. BOOL bRetval = FALSE;
  722. HMODULE hLib = LoadLibrary("advapi32.dll");
  723. if (hLib)
  724. {
  725. pFuncLookupAccountSidA = (PFuncLookupAccountSidA) GetProcAddress(hLib, "LookupAccountSidA");
  726. if (pFuncLookupAccountSidA)
  727. {
  728. bRetval = pFuncLookupAccountSidA(lpSystemName, Sid, Name, cbName,
  729. ReferencedDomainName, cbReferencedDomainName, peUse);
  730. }
  731. FreeLibrary(hLib);
  732. }
  733. return bRetval;
  734. }
  735. PCSTR GetSidTypeStr(IN SID_NAME_USE eUse)
  736. {
  737. static PCSTR acszSidTypeStr[] = {
  738. "Invalid", "User", "Group", "Domain", "Alias", "Well Known Group",
  739. "Deleted Account", "Invalid", "Unknown", "Computer",
  740. };
  741. if (eUse < SidTypeUser || eUse > SidTypeComputer) {
  742. dprintf( "Unrecognized SID");
  743. return NULL;
  744. }
  745. return acszSidTypeStr[eUse];
  746. }
  747. PCSTR ConvertSidToFriendlyName(IN SID* pSid, IN PCSTR pszFmt)
  748. {
  749. HRESULT hRetval = E_FAIL;
  750. static CHAR szSid[MAX_PATH] = {0};
  751. CHAR szName[MAX_PATH] = {0};
  752. CHAR szDomainName[MAX_PATH] ={0};
  753. SID_NAME_USE eUse = SidTypeInvalid;
  754. DWORD cbName = sizeof(szName) - 1;
  755. DWORD cbDomainName = sizeof(szDomainName) - 1;
  756. PCSTR pszSidTypeStr;
  757. if (CheckControlC())
  758. {
  759. return NULL;
  760. }
  761. //
  762. // null terminates szSid
  763. //
  764. szSid[0] = 0;
  765. hRetval = LsaLookupAccountSidA(NULL, pSid,
  766. szName, &cbName,
  767. szDomainName, &cbDomainName,
  768. &eUse) ? S_OK : GetLastError() + 0x80000000;
  769. if (SUCCEEDED(hRetval))
  770. {
  771. pszSidTypeStr = GetSidTypeStr(eUse);
  772. if (!pszSidTypeStr)
  773. {
  774. return NULL;
  775. }
  776. hRetval = _snprintf(szSid, sizeof(szSid) -1, pszFmt, pszSidTypeStr, *szDomainName ? szDomainName : "localhost", szName) >= 0 ? S_OK : HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  777. }
  778. if (FAILED(hRetval) && (ERROR_NONE_MAPPED != HRESULT_CODE(hRetval))) {
  779. dprintf("ConvertSidToFriendlyName on failed with error code %#x\n", hRetval);
  780. return NULL;
  781. }
  782. //
  783. // Indicate none mapped if so
  784. //
  785. if (!*szSid)
  786. {
  787. _snprintf(szSid, sizeof(szSid) - 1, "(no name mapped)");
  788. }
  789. return szSid;
  790. }
  791. void ShowSid(IN PCSTR pszPad, IN ULONG64 addrSid, IN ULONG fOptions)
  792. {
  793. PSID sid_to_dump = NULL;
  794. if (!addrSid) {
  795. dprintf("%s(null)\n", pszPad);
  796. return;
  797. }
  798. if (! sid_successfully_read(addrSid, & sid_to_dump))
  799. {
  800. dprintf("%s%08p: Unable to read in SID\n", pszPad,addrSid);
  801. return ;
  802. }
  803. DumpSID((PCHAR) pszPad, sid_to_dump, fOptions);
  804. if (sid_to_dump)
  805. {
  806. free (sid_to_dump);
  807. }
  808. }
  809. /*
  810. +-------------------------------------------------------------------+
  811. NAME: sid
  812. FUNCTION: Reads in & prints the SID, from
  813. the address specified. !sid command's workhorse.
  814. ARGS: Standard Debugger extensions, refer to DECLARE_API
  815. macro in the header files.
  816. +-------------------------------------------------------------------+
  817. */
  818. DECLARE_API( sid )
  819. {
  820. ULONG64 Address;
  821. ULONG Flags;
  822. ULONG result;
  823. PSID sid_to_dump = NULL;
  824. NTSTATUS ntstatus;
  825. UNICODE_STRING us;
  826. Address = 0;
  827. Flags = 6;
  828. GetExpressionEx(args, &Address, &args);
  829. if (args && *args) Flags = (ULONG) GetExpression(args);
  830. if (Address == 0) {
  831. dprintf("usage: !sid <SID-address>\n");
  832. return E_INVALIDARG;
  833. }
  834. if (! sid_successfully_read(Address, & sid_to_dump))
  835. {
  836. dprintf("%08p: Unable to read in SID\n", Address);
  837. return E_INVALIDARG;
  838. }
  839. DumpSID("SID is: ", sid_to_dump, Flags);
  840. if (sid_to_dump)
  841. {
  842. free (sid_to_dump);
  843. }
  844. return S_OK;
  845. }
  846. /*
  847. +-------------------------------------------------------------------+
  848. NAME: acl
  849. FUNCTION: Reads in & prints the ACL, from
  850. the address specified. !acl command's workhorse.
  851. ARGS: Standard Debugger extensions, refer to DECLARE_API
  852. macro in the header files.
  853. +-------------------------------------------------------------------+
  854. */
  855. DECLARE_API( acl )
  856. {
  857. ULONG64 Address;
  858. ULONG Flags;
  859. ULONG result;
  860. PACL acl_to_dump;
  861. NTSTATUS ntstatus;
  862. UNICODE_STRING us;
  863. Address = 0;
  864. Flags = 6;
  865. GetExpressionEx(args, &Address, &args);
  866. if (args && *args) Flags = (ULONG) GetExpression(args);
  867. if (Address == 0) {
  868. dprintf("usage: !acl <ACL-address>\n");
  869. return E_INVALIDARG;
  870. }
  871. if (! acl_successfully_read(Address, & acl_to_dump))
  872. {
  873. dprintf("%08p: Unable to read in ACL\n", Address);
  874. return E_INVALIDARG;
  875. }
  876. DumpACL("ACL is: ", acl_to_dump, Flags, Address);
  877. return S_OK;
  878. }