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.

1389 lines
40 KiB

  1. /****************************************************************************
  2. PROGRAM: ACLEDIT.C
  3. PURPOSE: Contains routines that edit security on Nt objects
  4. ****************************************************************************/
  5. #include "pviewp.h"
  6. #include <sedapi.h>
  7. //
  8. // Define the type of a pointer to the DACL editor fn
  9. //
  10. typedef DWORD (*LPFNDACLEDITOR) ( HWND,
  11. HANDLE,
  12. LPWSTR,
  13. PSED_OBJECT_TYPE_DESCRIPTOR,
  14. PSED_APPLICATION_ACCESSES,
  15. LPWSTR,
  16. PSED_FUNC_APPLY_SEC_CALLBACK,
  17. ULONG_PTR,
  18. PSECURITY_DESCRIPTOR,
  19. BOOLEAN,
  20. BOOLEAN, // CantWriteDacl
  21. LPDWORD,
  22. DWORD );
  23. //
  24. // Declare globals used to reference dynamically loaded ACLEditor module
  25. //
  26. HMODULE hModAclEditor = NULL;
  27. LPFNDACLEDITOR lpfnDaclEditor = NULL;
  28. //
  29. // Define security information for each type of object
  30. //
  31. //
  32. // Define the maximum number of accesses per object type
  33. //
  34. #define MAX_ACCESSES 30
  35. //
  36. // Define structure to contain the security information for
  37. // an object type
  38. //
  39. typedef struct _OBJECT_TYPE_SECURITY_INFO {
  40. LPWSTR TypeName;
  41. SED_HELP_INFO HelpInfo ;
  42. SED_OBJECT_TYPE_DESCRIPTOR SedObjectTypeDescriptor;
  43. GENERIC_MAPPING GenericMapping;
  44. SED_APPLICATION_ACCESSES AppAccesses ;
  45. SED_APPLICATION_ACCESS AppAccess[MAX_ACCESSES];
  46. } OBJECT_TYPE_SECURITY_INFO, *POBJECT_TYPE_SECURITY_INFO;
  47. //
  48. // Define name of help file
  49. //
  50. #define HELP_FILENAME L"pview.hlp"
  51. //
  52. // Define dummy access (used as filler)
  53. //
  54. #define DUMMY_ACCESS \
  55. { \
  56. 0, \
  57. 0, \
  58. 0, \
  59. NULL \
  60. }
  61. //
  62. // Define generic accesses
  63. //
  64. #define GENERIC_ACCESSES_5(Type) \
  65. { \
  66. Type, \
  67. GENERIC_ALL, \
  68. 0, \
  69. L"All Access" \
  70. }, \
  71. { \
  72. Type, \
  73. GENERIC_READ, \
  74. 0, \
  75. L"Read" \
  76. }, \
  77. { \
  78. Type, \
  79. GENERIC_WRITE, \
  80. 0, \
  81. L"Write" \
  82. }, \
  83. { \
  84. Type, \
  85. GENERIC_EXECUTE, \
  86. 0, \
  87. L"Execute" \
  88. }, \
  89. { \
  90. Type, \
  91. 0, \
  92. 0, \
  93. L"None" \
  94. }
  95. //
  96. // Define generic accesses to be shown in special access dialog
  97. //
  98. #define SPECIAL_GENERIC_ACCESSES_4(Type) \
  99. { \
  100. Type, \
  101. GENERIC_ALL, \
  102. 0, \
  103. L"Generic All" \
  104. }, \
  105. { \
  106. Type, \
  107. GENERIC_READ, \
  108. 0, \
  109. L"Generic Read" \
  110. }, \
  111. { \
  112. Type, \
  113. GENERIC_WRITE, \
  114. 0, \
  115. L"Generic Write" \
  116. }, \
  117. { \
  118. Type, \
  119. GENERIC_EXECUTE, \
  120. 0, \
  121. L"Generic Execute" \
  122. }
  123. //
  124. // Define standard accesses
  125. //
  126. #define STANDARD_ACCESSES_5(Type) \
  127. { \
  128. Type, \
  129. DELETE, \
  130. 0, \
  131. L"Delete" \
  132. }, \
  133. { \
  134. Type, \
  135. READ_CONTROL, \
  136. 0, \
  137. L"Read Control" \
  138. }, \
  139. { \
  140. Type, \
  141. WRITE_DAC, \
  142. 0, \
  143. L"Write DAC" \
  144. }, \
  145. { \
  146. Type, \
  147. WRITE_OWNER, \
  148. 0, \
  149. L"Write Owner" \
  150. }, \
  151. { \
  152. Type, \
  153. SYNCHRONIZE, \
  154. 0, \
  155. L"Synchronize" \
  156. }
  157. //
  158. // Define security info for 'DEFAULT' ACLs found in tokens
  159. //
  160. OBJECT_TYPE_SECURITY_INFO DefaultSecurityInfo = {
  161. //
  162. // Type name
  163. //
  164. L"DEFAULT",
  165. //
  166. // Help info
  167. //
  168. {
  169. HELP_FILENAME,
  170. {0, 0, 0, 0, 0, 0, 0}
  171. },
  172. //
  173. // Acleditor object type descriptor
  174. //
  175. {
  176. SED_REVISION1, // Revision
  177. FALSE, // Is container
  178. FALSE, // AllowNewObjectPermissions
  179. FALSE, // MapSpecificPermsToGeneric
  180. NULL, // Pointer to generic mapping
  181. NULL, // Pointer to generic mapping for new objects
  182. L"Default", // Object type name
  183. NULL, // Pointer to help info
  184. NULL, // ApplyToSubContainerTitle
  185. NULL, // ApplyToObjectsTitle
  186. NULL, // ApplyToSubContainerConfirmation
  187. L"Special...", // SpecialObjectAccessTitle
  188. NULL // SpecialNewObjectAccessTitle
  189. },
  190. //
  191. // Generic mapping
  192. //
  193. {
  194. STANDARD_RIGHTS_READ,
  195. STANDARD_RIGHTS_WRITE,
  196. STANDARD_RIGHTS_EXECUTE,
  197. STANDARD_RIGHTS_ALL
  198. },
  199. //
  200. // Application access structure
  201. //
  202. {
  203. 14, // Access count (must match list below)
  204. NULL, // Pointer to accesses
  205. L"Read", // Default new access
  206. },
  207. //
  208. // Application accesses
  209. //
  210. {
  211. GENERIC_ACCESSES_5(SED_DESC_TYPE_RESOURCE),
  212. STANDARD_ACCESSES_5(SED_DESC_TYPE_RESOURCE_SPECIAL),
  213. SPECIAL_GENERIC_ACCESSES_4(SED_DESC_TYPE_RESOURCE_SPECIAL),
  214. DUMMY_ACCESS, // 15
  215. DUMMY_ACCESS, // 16
  216. DUMMY_ACCESS, // 17
  217. DUMMY_ACCESS, // 18
  218. DUMMY_ACCESS, // 19
  219. DUMMY_ACCESS, // 20
  220. DUMMY_ACCESS, // 21
  221. DUMMY_ACCESS, // 22
  222. DUMMY_ACCESS, // 23
  223. DUMMY_ACCESS, // 24
  224. DUMMY_ACCESS, // 25
  225. DUMMY_ACCESS, // 26
  226. DUMMY_ACCESS, // 27
  227. DUMMY_ACCESS, // 28
  228. DUMMY_ACCESS, // 29
  229. DUMMY_ACCESS // 30
  230. }
  231. };
  232. //
  233. // Define security info for each type of object
  234. //
  235. OBJECT_TYPE_SECURITY_INFO ObjectTypeSecurityInfo[] = {
  236. //
  237. // PROCESS
  238. //
  239. {
  240. //
  241. // Type name
  242. //
  243. L"Process",
  244. //
  245. // Help info
  246. //
  247. {
  248. HELP_FILENAME,
  249. {0, 0, 0, 0, 0, 0, 0}
  250. },
  251. //
  252. // Acleditor object type descriptor
  253. //
  254. {
  255. SED_REVISION1, // Revision
  256. FALSE, // Is container
  257. FALSE, // AllowNewObjectPermissions
  258. FALSE, // MapSpecificPermsToGeneric
  259. NULL, // Pointer to generic mapping
  260. NULL, // Pointer to generic mapping for new objects
  261. L"Process", // Object type name
  262. NULL, // Pointer to help info
  263. NULL, // ApplyToSubContainerTitle
  264. NULL, // ApplyToObjectsTitle
  265. NULL, // ApplyToSubContainerConfirmation
  266. L"Special...", // SpecialObjectAccessTitle
  267. NULL // SpecialNewObjectAccessTitle
  268. },
  269. //
  270. // Generic mapping
  271. //
  272. {
  273. PROCESS_QUERY_INFORMATION | STANDARD_RIGHTS_READ,
  274. PROCESS_SET_INFORMATION | STANDARD_RIGHTS_WRITE,
  275. STANDARD_RIGHTS_EXECUTE,
  276. PROCESS_ALL_ACCESS
  277. },
  278. //
  279. // Application access structure
  280. //
  281. {
  282. 21, // Access count (must match list below)
  283. NULL, // Pointer to accesses
  284. L"Read", // Default new access
  285. },
  286. //
  287. // Application accesses
  288. //
  289. {
  290. GENERIC_ACCESSES_5(SED_DESC_TYPE_RESOURCE),
  291. STANDARD_ACCESSES_5(SED_DESC_TYPE_RESOURCE_SPECIAL),
  292. { // 11
  293. SED_DESC_TYPE_RESOURCE_SPECIAL,
  294. PROCESS_TERMINATE,
  295. 0,
  296. L"Terminate"
  297. },
  298. { // 12
  299. SED_DESC_TYPE_RESOURCE_SPECIAL,
  300. PROCESS_CREATE_THREAD,
  301. 0,
  302. L"Create thread"
  303. },
  304. { // 13
  305. SED_DESC_TYPE_RESOURCE_SPECIAL,
  306. PROCESS_VM_OPERATION,
  307. 0,
  308. L"VM Operation"
  309. },
  310. { // 14
  311. SED_DESC_TYPE_RESOURCE_SPECIAL,
  312. PROCESS_VM_READ,
  313. 0,
  314. L"VM Read"
  315. },
  316. { // 15
  317. SED_DESC_TYPE_RESOURCE_SPECIAL,
  318. PROCESS_VM_WRITE,
  319. 0,
  320. L"VM Write"
  321. },
  322. { // 16
  323. SED_DESC_TYPE_RESOURCE_SPECIAL,
  324. PROCESS_DUP_HANDLE,
  325. 0,
  326. L"Duplicate handle"
  327. },
  328. { // 17
  329. SED_DESC_TYPE_RESOURCE_SPECIAL,
  330. PROCESS_CREATE_PROCESS,
  331. 0,
  332. L"Create process",
  333. },
  334. { // 18
  335. SED_DESC_TYPE_RESOURCE_SPECIAL,
  336. PROCESS_SET_QUOTA,
  337. 0,
  338. L"Set quota"
  339. },
  340. { // 19
  341. SED_DESC_TYPE_RESOURCE_SPECIAL,
  342. PROCESS_SET_INFORMATION,
  343. 0,
  344. L"Set information"
  345. },
  346. { // 20
  347. SED_DESC_TYPE_RESOURCE_SPECIAL,
  348. PROCESS_QUERY_INFORMATION,
  349. 0,
  350. L"Query information"
  351. },
  352. { // 21
  353. SED_DESC_TYPE_RESOURCE_SPECIAL,
  354. PROCESS_SET_PORT,
  355. 0,
  356. L"Set port"
  357. },
  358. DUMMY_ACCESS, // 22
  359. DUMMY_ACCESS, // 23
  360. DUMMY_ACCESS, // 24
  361. DUMMY_ACCESS, // 25
  362. DUMMY_ACCESS, // 26
  363. DUMMY_ACCESS, // 27
  364. DUMMY_ACCESS, // 28
  365. DUMMY_ACCESS, // 29
  366. DUMMY_ACCESS // 30
  367. }
  368. },
  369. //
  370. // THREAD
  371. //
  372. {
  373. //
  374. // Type name
  375. //
  376. L"Thread",
  377. //
  378. // Help info
  379. //
  380. {
  381. HELP_FILENAME,
  382. {0, 0, 0, 0, 0, 0, 0}
  383. },
  384. //
  385. // Acleditor object type descriptor
  386. //
  387. {
  388. SED_REVISION1, // Revision
  389. FALSE, // Is container
  390. FALSE, // AllowNewObjectPermissions
  391. FALSE, // MapSpecificPermsToGeneric
  392. NULL, // Pointer to generic mapping
  393. NULL, // Pointer to generic mapping for new objects
  394. L"Thread", // Object type name
  395. NULL, // Pointer to help info
  396. NULL, // ApplyToSubContainerTitle
  397. NULL, // ApplyToObjectsTitle
  398. NULL, // ApplyToSubContainerConfirmation
  399. L"Special...", // SpecialObjectAccessTitle
  400. NULL // SpecialNewObjectAccessTitle
  401. },
  402. //
  403. // Generic mapping
  404. //
  405. {
  406. THREAD_QUERY_INFORMATION | STANDARD_RIGHTS_READ,
  407. THREAD_SET_INFORMATION | STANDARD_RIGHTS_WRITE,
  408. STANDARD_RIGHTS_EXECUTE,
  409. THREAD_ALL_ACCESS
  410. },
  411. //
  412. // Application access structure
  413. //
  414. {
  415. 20, // Access count (must match list below)
  416. NULL, // Pointer to accesses
  417. L"Read", // Default new access
  418. },
  419. //
  420. // Application accesses
  421. //
  422. {
  423. GENERIC_ACCESSES_5(SED_DESC_TYPE_RESOURCE),
  424. STANDARD_ACCESSES_5(SED_DESC_TYPE_RESOURCE_SPECIAL),
  425. { // 11
  426. SED_DESC_TYPE_RESOURCE_SPECIAL,
  427. THREAD_TERMINATE,
  428. 0,
  429. L"Terminate"
  430. },
  431. { // 12
  432. SED_DESC_TYPE_RESOURCE_SPECIAL,
  433. THREAD_SUSPEND_RESUME,
  434. 0,
  435. L"Suspend/Resume"
  436. },
  437. { // 13
  438. SED_DESC_TYPE_RESOURCE_SPECIAL,
  439. THREAD_ALERT,
  440. 0,
  441. L"Alert"
  442. },
  443. { // 14
  444. SED_DESC_TYPE_RESOURCE_SPECIAL,
  445. THREAD_GET_CONTEXT,
  446. 0,
  447. L"Get context"
  448. },
  449. { // 15
  450. SED_DESC_TYPE_RESOURCE_SPECIAL,
  451. THREAD_SET_CONTEXT,
  452. 0,
  453. L"Set context"
  454. },
  455. { // 16
  456. SED_DESC_TYPE_RESOURCE_SPECIAL,
  457. THREAD_SET_INFORMATION,
  458. 0,
  459. L"Set information"
  460. },
  461. { // 17
  462. SED_DESC_TYPE_RESOURCE_SPECIAL,
  463. THREAD_QUERY_INFORMATION,
  464. 0,
  465. L"Query information"
  466. },
  467. { // 18
  468. SED_DESC_TYPE_RESOURCE_SPECIAL,
  469. THREAD_SET_THREAD_TOKEN,
  470. 0,
  471. L"Set token"
  472. },
  473. { // 19
  474. SED_DESC_TYPE_RESOURCE_SPECIAL,
  475. THREAD_IMPERSONATE,
  476. 0,
  477. L"Impersonate"
  478. },
  479. { // 20
  480. SED_DESC_TYPE_RESOURCE_SPECIAL,
  481. THREAD_DIRECT_IMPERSONATION,
  482. 0,
  483. L"Direct impersonation"
  484. },
  485. DUMMY_ACCESS, // 21
  486. DUMMY_ACCESS, // 22
  487. DUMMY_ACCESS, // 23
  488. DUMMY_ACCESS, // 24
  489. DUMMY_ACCESS, // 25
  490. DUMMY_ACCESS, // 26
  491. DUMMY_ACCESS, // 27
  492. DUMMY_ACCESS, // 28
  493. DUMMY_ACCESS, // 29
  494. DUMMY_ACCESS // 30
  495. }
  496. },
  497. //
  498. // TOKEN
  499. //
  500. {
  501. //
  502. // Type name
  503. //
  504. L"Token",
  505. //
  506. // Help info
  507. //
  508. {
  509. HELP_FILENAME,
  510. {0, 0, 0, 0, 0, 0, 0}
  511. },
  512. //
  513. // Acleditor object type descriptor
  514. //
  515. {
  516. SED_REVISION1, // Revision
  517. FALSE, // Is container
  518. FALSE, // AllowNewObjectPermissions
  519. FALSE, // MapSpecificPermsToGeneric
  520. NULL, // Pointer to generic mapping
  521. NULL, // Pointer to generic mapping for new objects
  522. L"Token", // Object type name
  523. NULL, // Pointer to help info
  524. NULL, // ApplyToSubContainerTitle
  525. NULL, // ApplyToObjectsTitle
  526. NULL, // ApplyToSubContainerConfirmation
  527. L"Special...", // SpecialObjectAccessTitle
  528. NULL // SpecialNewObjectAccessTitle
  529. },
  530. //
  531. // Generic mapping
  532. //
  533. {
  534. TOKEN_READ,
  535. TOKEN_WRITE,
  536. TOKEN_EXECUTE,
  537. TOKEN_ALL_ACCESS
  538. },
  539. //
  540. // Application access structure
  541. //
  542. {
  543. 18, // Access count (must match list below)
  544. NULL, // Pointer to accesses
  545. L"Read", // Default new access
  546. },
  547. //
  548. // Application accesses
  549. //
  550. {
  551. GENERIC_ACCESSES_5(SED_DESC_TYPE_RESOURCE),
  552. STANDARD_ACCESSES_5(SED_DESC_TYPE_RESOURCE_SPECIAL),
  553. { // 11
  554. SED_DESC_TYPE_RESOURCE_SPECIAL,
  555. TOKEN_ASSIGN_PRIMARY,
  556. 0,
  557. L"Assign primary"
  558. },
  559. { // 12
  560. SED_DESC_TYPE_RESOURCE_SPECIAL,
  561. TOKEN_DUPLICATE,
  562. 0,
  563. L"Duplicate"
  564. },
  565. { // 13
  566. SED_DESC_TYPE_RESOURCE_SPECIAL,
  567. TOKEN_IMPERSONATE,
  568. 0,
  569. L"Impersonate"
  570. },
  571. { // 14
  572. SED_DESC_TYPE_RESOURCE_SPECIAL,
  573. TOKEN_QUERY,
  574. 0,
  575. L"Query"
  576. },
  577. { // 15
  578. SED_DESC_TYPE_RESOURCE_SPECIAL,
  579. TOKEN_QUERY_SOURCE,
  580. 0,
  581. L"Query source"
  582. },
  583. { // 16
  584. SED_DESC_TYPE_RESOURCE_SPECIAL,
  585. TOKEN_ADJUST_PRIVILEGES,
  586. 0,
  587. L"Adjust Privileges"
  588. },
  589. { // 17
  590. SED_DESC_TYPE_RESOURCE_SPECIAL,
  591. TOKEN_ADJUST_GROUPS,
  592. 0,
  593. L"Adjust Groups"
  594. },
  595. { // 18
  596. SED_DESC_TYPE_RESOURCE_SPECIAL,
  597. TOKEN_ADJUST_DEFAULT,
  598. 0,
  599. L"Adjust Default"
  600. },
  601. DUMMY_ACCESS, // 19
  602. DUMMY_ACCESS, // 20
  603. DUMMY_ACCESS, // 21
  604. DUMMY_ACCESS, // 22
  605. DUMMY_ACCESS, // 23
  606. DUMMY_ACCESS, // 24
  607. DUMMY_ACCESS, // 25
  608. DUMMY_ACCESS, // 26
  609. DUMMY_ACCESS, // 27
  610. DUMMY_ACCESS, // 28
  611. DUMMY_ACCESS, // 29
  612. DUMMY_ACCESS // 30
  613. }
  614. }
  615. };
  616. /***************************************************************************\
  617. * InitializeACLEditor
  618. *
  619. * Purpose : Initializes this module.
  620. *
  621. * Returns TRUE on success, FALSE on failure
  622. *
  623. * History:
  624. * 09-17-92 Davidc Created.
  625. \***************************************************************************/
  626. BOOL
  627. InitializeAclEditor(
  628. VOID
  629. )
  630. {
  631. //
  632. // Load the acleditor module and get the proc addresses we need
  633. //
  634. hModAclEditor = LoadLibrary(TEXT("acledit.dll"));
  635. if (hModAclEditor == NULL) {
  636. return(FALSE);
  637. }
  638. lpfnDaclEditor = (LPFNDACLEDITOR)GetProcAddress(hModAclEditor,
  639. TEXT("SedDiscretionaryAclEditor"));
  640. if (lpfnDaclEditor == NULL) {
  641. return(FALSE);
  642. }
  643. return(TRUE);
  644. }
  645. /***************************************************************************\
  646. * FindObjectSecurityInfo
  647. *
  648. * Purpose : Searches for object type in our security info table and
  649. * returns pointer to security info if found.
  650. * Any pointers in the security info are initialized by this routine.
  651. *
  652. * Returns pointer to security info or NULL on failure
  653. *
  654. * History:
  655. * 09-17-92 Davidc Created.
  656. \***************************************************************************/
  657. POBJECT_TYPE_SECURITY_INFO
  658. FindObjectSecurityInfo(
  659. HANDLE Object
  660. )
  661. {
  662. NTSTATUS Status;
  663. POBJECT_TYPE_SECURITY_INFO SecurityInfo;
  664. POBJECT_TYPE_INFORMATION TypeInfo;
  665. ULONG Length;
  666. BOOL Found;
  667. ULONG i;
  668. //
  669. // Get the object type
  670. //
  671. Status = NtQueryObject(
  672. Object,
  673. ObjectTypeInformation,
  674. NULL,
  675. 0,
  676. &Length
  677. );
  678. if (Status != STATUS_INFO_LENGTH_MISMATCH) {
  679. DbgPrint("NtQueryObject failed, status = 0x%lx\n", Status);
  680. return(NULL);
  681. }
  682. TypeInfo = Alloc(Length);
  683. if (TypeInfo == NULL) {
  684. DbgPrint("Failed to allocate %ld bytes for object type\n", Length);
  685. return(NULL);
  686. }
  687. Status = NtQueryObject(
  688. Object,
  689. ObjectTypeInformation,
  690. TypeInfo,
  691. Length,
  692. NULL
  693. );
  694. if (!NT_SUCCESS(Status)) {
  695. DbgPrint("NtQueryObject failed, status = 0x%lx\n", Status);
  696. Free(TypeInfo);
  697. return(NULL);
  698. }
  699. //
  700. // Search for the type in our array of security info
  701. //
  702. Found = FALSE;
  703. for ( i=0;
  704. i < (sizeof(ObjectTypeSecurityInfo) / sizeof(*ObjectTypeSecurityInfo));
  705. i++
  706. ) {
  707. UNICODE_STRING FoundType;
  708. SecurityInfo = &ObjectTypeSecurityInfo[i];
  709. RtlInitUnicodeString(&FoundType, SecurityInfo->TypeName);
  710. if (RtlEqualUnicodeString(&TypeInfo->TypeName, &FoundType, TRUE)) {
  711. Found = TRUE;
  712. break;
  713. }
  714. }
  715. Free(TypeInfo);
  716. return(Found ? SecurityInfo : NULL);
  717. }
  718. /***************************************************************************\
  719. * EditObjectDacl
  720. *
  721. * Purpose : Displays and allows the user to edit the Dacl on an object
  722. *
  723. * Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
  724. *
  725. * History:
  726. * 09-17-92 Davidc Created.
  727. \***************************************************************************/
  728. BOOL
  729. EditObjectDacl(
  730. HWND Owner,
  731. LPWSTR ObjectName,
  732. HANDLE Object,
  733. PSECURITY_DESCRIPTOR SecurityDescriptor,
  734. POBJECT_TYPE_SECURITY_INFO SecurityInfo,
  735. PSED_FUNC_APPLY_SEC_CALLBACK SetSecurityCallback,
  736. DWORD *EditResult
  737. )
  738. {
  739. DWORD Result;
  740. HANDLE Instance;
  741. //
  742. // Initialize the pointer fields in the security info structure
  743. //
  744. SecurityInfo->AppAccesses.AccessGroup = SecurityInfo->AppAccess;
  745. SecurityInfo->SedObjectTypeDescriptor.GenericMapping =
  746. &SecurityInfo->GenericMapping;
  747. SecurityInfo->SedObjectTypeDescriptor.GenericMappingNewObjects =
  748. &SecurityInfo->GenericMapping;
  749. SecurityInfo->SedObjectTypeDescriptor.HelpInfo =
  750. &SecurityInfo->HelpInfo;
  751. //
  752. // Get the application instance handle
  753. //
  754. Instance = (HANDLE)(NtCurrentPeb()->ImageBaseAddress);
  755. ASSERT(Instance != 0);
  756. //
  757. // Call the ACL editor, it will call our ApplyNtObjectSecurity function
  758. // to store any ACL changes in the token.
  759. //
  760. Result = (*lpfnDaclEditor)(
  761. Owner,
  762. Instance,
  763. NULL, // server
  764. &SecurityInfo->SedObjectTypeDescriptor, // object type
  765. &SecurityInfo->AppAccesses, // application accesses
  766. ObjectName,
  767. SetSecurityCallback, // Callback
  768. (ULONG_PTR)Object, // Context
  769. SecurityDescriptor,
  770. (BOOLEAN)(SecurityDescriptor == NULL), // Couldn't read DACL
  771. FALSE, // CantWriteDacl
  772. EditResult,
  773. 0
  774. );
  775. if (Result != ERROR_SUCCESS) {
  776. DbgPrint("DAcleditor failed, error = %d\n", Result);
  777. SetLastError(Result);
  778. }
  779. return (Result == ERROR_SUCCESS);
  780. }
  781. /***************************************************************************\
  782. * ApplyNtObjectSecurity
  783. *
  784. * Purpose : Called by ACL editor to set new security on an object
  785. *
  786. * Returns ERROR_SUCCESS or win error code.
  787. *
  788. * History:
  789. * 09-17-92 Davidc Created.
  790. \***************************************************************************/
  791. DWORD
  792. ApplyNtObjectSecurity(
  793. HWND hwndParent,
  794. HANDLE hInstance,
  795. ULONG_PTR CallbackContext,
  796. PSECURITY_DESCRIPTOR SecDesc,
  797. PSECURITY_DESCRIPTOR SecDescNewObjects,
  798. BOOLEAN ApplyToSubContainers,
  799. BOOLEAN ApplyToSubObjects,
  800. LPDWORD StatusReturn
  801. )
  802. {
  803. HANDLE Object = (HANDLE)CallbackContext;
  804. NTSTATUS Status;
  805. *StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
  806. //
  807. // Set the new DACL on the object
  808. //
  809. Status = NtSetSecurityObject(Object,
  810. DACL_SECURITY_INFORMATION,
  811. SecDesc);
  812. if (NT_SUCCESS(Status)) {
  813. *StatusReturn = SED_STATUS_MODIFIED;
  814. } else {
  815. DbgPrint("Failed to set new ACL on object, status = 0x%lx\n", Status);
  816. if (Status == STATUS_ACCESS_DENIED) {
  817. MessageBox(hwndParent,
  818. "You do not have permission to set the permissions on this object",
  819. NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  820. } else {
  821. MessageBox(hwndParent,
  822. "Unable to set object security",
  823. NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  824. }
  825. }
  826. return(ERROR_SUCCESS);
  827. }
  828. /***************************************************************************\
  829. * EditNtObjectDacl
  830. *
  831. * Purpose : Displays and allows the user to edit the Dacl on an NT object
  832. *
  833. * Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
  834. *
  835. * History:
  836. * 09-17-92 Davidc Created.
  837. \***************************************************************************/
  838. BOOL
  839. EditNtObjectDacl(
  840. HWND Owner,
  841. LPWSTR ObjectName,
  842. HANDLE Object,
  843. PSECURITY_DESCRIPTOR SecurityDescriptor,
  844. DWORD *EditResult
  845. )
  846. {
  847. BOOL Result;
  848. POBJECT_TYPE_SECURITY_INFO SecurityInfo;
  849. //
  850. // Lookup our security info for an object of this type
  851. //
  852. SecurityInfo = FindObjectSecurityInfo(Object);
  853. if (SecurityInfo == NULL) {
  854. MessageBox(Owner, "Unable to edit the security on an object of this type",
  855. NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  856. return(FALSE);
  857. }
  858. //
  859. // Edit the ACL. Our callback function will be called to change the
  860. // new permissions
  861. //
  862. Result = EditObjectDacl(
  863. Owner,
  864. ObjectName,
  865. Object,
  866. SecurityDescriptor,
  867. SecurityInfo,
  868. ApplyNtObjectSecurity,
  869. EditResult
  870. );
  871. return (Result);
  872. }
  873. /***************************************************************************\
  874. * EditNtObjectSecurity
  875. *
  876. * Purpose : Displays and allows the user to edit the protection on an NT object
  877. *
  878. * Parameters:
  879. *
  880. * hwndOwner - Owner window for dialog
  881. * Object - handle to NT object. Should have been opened for MAXIMUM_ALLOWED
  882. * Name - Name of object
  883. *
  884. * Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
  885. *
  886. * History:
  887. * 09-17-92 Davidc Created.
  888. \***************************************************************************/
  889. BOOL
  890. EditNtObjectSecurity(
  891. HWND hwndOwner,
  892. HANDLE Object,
  893. LPWSTR ObjectName
  894. )
  895. {
  896. NTSTATUS Status;
  897. BOOL Success = FALSE;
  898. DWORD EditResult;
  899. PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  900. ULONG Length;
  901. //
  902. // If we don't have an address for the DACL editor, we can't do anything
  903. //
  904. if (lpfnDaclEditor == NULL) {
  905. DbgPrint("EditNtObjectSecurity - no ACL editor loaded\n");
  906. return(FALSE);
  907. }
  908. //
  909. // Read the existing security from the object
  910. //
  911. Status = NtQuerySecurityObject(Object,
  912. OWNER_SECURITY_INFORMATION |
  913. GROUP_SECURITY_INFORMATION |
  914. DACL_SECURITY_INFORMATION,
  915. NULL,
  916. 0,
  917. &Length);
  918. ASSERT(!NT_SUCCESS(Status));
  919. if (Status != STATUS_BUFFER_TOO_SMALL) {
  920. DbgPrint("Failed to query object security, status = 0x%lx\n", Status);
  921. } else {
  922. SecurityDescriptor = Alloc(Length);
  923. if (SecurityDescriptor == NULL) {
  924. DbgPrint("Failed to allocate %ld bytes for object SD\n", Length);
  925. goto CleanupAndExit;
  926. }
  927. Status = NtQuerySecurityObject(Object,
  928. OWNER_SECURITY_INFORMATION |
  929. GROUP_SECURITY_INFORMATION |
  930. DACL_SECURITY_INFORMATION,
  931. SecurityDescriptor,
  932. Length,
  933. &Length);
  934. if (!NT_SUCCESS(Status)) {
  935. DbgPrint("Failed to query object security, status = 0x%lx\n", Status);
  936. goto CleanupAndExit;
  937. }
  938. ASSERT(RtlValidSecurityDescriptor(SecurityDescriptor));
  939. }
  940. //
  941. // Call the ACL editor, it will call our ApplyNtObjectSecurity function
  942. // to store any ACL changes in the object.
  943. //
  944. Success = EditNtObjectDacl(
  945. hwndOwner,
  946. ObjectName,
  947. Object,
  948. SecurityDescriptor,
  949. &EditResult
  950. );
  951. if (!Success) {
  952. DbgPrint("PVIEW: Failed to edit object DACL\n");
  953. }
  954. CleanupAndExit:
  955. if (SecurityDescriptor != NULL) {
  956. Free(SecurityDescriptor);
  957. }
  958. return(Success);
  959. }
  960. /***************************************************************************\
  961. * ApplyTokenDefaultDacl
  962. *
  963. * Purpose : Called by ACL editor to set new security on an object
  964. *
  965. * Returns ERROR_SUCCESS or win error code.
  966. *
  967. * History:
  968. * 09-17-92 Davidc Created.
  969. \***************************************************************************/
  970. DWORD
  971. ApplyTokenDefaultDacl(
  972. HWND hwndParent,
  973. HANDLE hInstance,
  974. ULONG_PTR CallbackContext,
  975. PSECURITY_DESCRIPTOR SecDesc,
  976. PSECURITY_DESCRIPTOR SecDescNewObjects,
  977. BOOLEAN ApplyToSubContainers,
  978. BOOLEAN ApplyToSubObjects,
  979. LPDWORD StatusReturn
  980. )
  981. {
  982. HANDLE Token = (HANDLE)CallbackContext;
  983. TOKEN_DEFAULT_DACL DefaultDacl;
  984. NTSTATUS Status;
  985. BOOLEAN DaclPresent;
  986. BOOLEAN DaclDefaulted;
  987. Status = RtlGetDaclSecurityDescriptor (
  988. SecDesc,
  989. &DaclPresent,
  990. &DefaultDacl.DefaultDacl,
  991. &DaclDefaulted
  992. );
  993. ASSERT(NT_SUCCESS(Status));
  994. ASSERT(DaclPresent);
  995. Status = NtSetInformationToken(
  996. Token, // Handle
  997. TokenDefaultDacl, // TokenInformationClass
  998. &DefaultDacl, // TokenInformation
  999. sizeof(DefaultDacl) // TokenInformationLength
  1000. );
  1001. if (NT_SUCCESS(Status)) {
  1002. *StatusReturn = SED_STATUS_MODIFIED;
  1003. } else {
  1004. DbgPrint("SetInformationToken failed, status = 0x%lx\n", Status);
  1005. *StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
  1006. if (Status == STATUS_ACCESS_DENIED) {
  1007. MessageBox(hwndParent,
  1008. "You do not have permission to set the default ACL in this token",
  1009. NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  1010. } else {
  1011. MessageBox(hwndParent,
  1012. "Unable to set default ACL in token",
  1013. NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  1014. }
  1015. }
  1016. return(ERROR_SUCCESS);
  1017. }
  1018. /***************************************************************************\
  1019. * EditTokenDefaultAcl
  1020. *
  1021. * Purpose : Displays and allows the user to edit the default ACL in a token
  1022. *
  1023. * Parameters:
  1024. *
  1025. * hwndOwner - Owner window for dialog
  1026. * Object - handle to token - opened for TOKEN_QUERY access
  1027. * Name - Name of token
  1028. *
  1029. * Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
  1030. *
  1031. * History:
  1032. * 09-17-92 Davidc Created.
  1033. \***************************************************************************/
  1034. BOOL
  1035. EditTokenDefaultDacl(
  1036. HWND hwndOwner,
  1037. HANDLE Token,
  1038. LPWSTR ObjectName
  1039. )
  1040. {
  1041. NTSTATUS Status;
  1042. BOOL Result = FALSE;
  1043. DWORD EditResult;
  1044. PTOKEN_DEFAULT_DACL DefaultDacl = NULL;
  1045. PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  1046. ULONG InfoLength;
  1047. //
  1048. // If we don't have an address for the DACL editor, we can't do anything
  1049. //
  1050. if (lpfnDaclEditor == NULL) {
  1051. DbgPrint("EditNtObjectSecurity - no ACL editor loaded\n");
  1052. return(FALSE);
  1053. }
  1054. //
  1055. // Read the default DACL from the token
  1056. //
  1057. Status = NtQueryInformationToken(
  1058. Token, // Handle
  1059. TokenDefaultDacl, // TokenInformationClass
  1060. NULL, // TokenInformation
  1061. 0, // TokenInformationLength
  1062. &InfoLength // ReturnLength
  1063. );
  1064. ASSERT(!NT_SUCCESS(Status));
  1065. if (Status == STATUS_BUFFER_TOO_SMALL) {
  1066. DefaultDacl = Alloc(InfoLength);
  1067. if (DefaultDacl == NULL) {
  1068. goto CleanupAndExit;
  1069. }
  1070. Status = NtQueryInformationToken(
  1071. Token, // Handle
  1072. TokenDefaultDacl, // TokenInformationClass
  1073. DefaultDacl, // TokenInformation
  1074. InfoLength, // TokenInformationLength
  1075. &InfoLength // ReturnLength
  1076. );
  1077. if (!NT_SUCCESS(Status)) {
  1078. DbgPrint("NtQueryInformationToken failed, status = 0x%lx\n", Status);
  1079. goto CleanupAndExit;
  1080. }
  1081. //
  1082. // Create a security descriptor
  1083. //
  1084. SecurityDescriptor = Alloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
  1085. if (SecurityDescriptor == NULL) {
  1086. DbgPrint("Failed to allocate security descriptor\n");
  1087. goto CleanupAndExit;
  1088. }
  1089. Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
  1090. ASSERT(NT_SUCCESS(Status));
  1091. //
  1092. // Set the DACL on the security descriptor
  1093. //
  1094. Status = RtlSetDaclSecurityDescriptor(
  1095. SecurityDescriptor,
  1096. TRUE, // DACL present
  1097. DefaultDacl->DefaultDacl,
  1098. FALSE // DACL defaulted
  1099. );
  1100. ASSERT(NT_SUCCESS(Status));
  1101. ASSERT(RtlValidSecurityDescriptor(SecurityDescriptor));
  1102. }
  1103. //
  1104. // Call the ACL editor, it will call our ApplyTokenDefaultAcl function
  1105. // to store any default ACL changes in the token.
  1106. //
  1107. Result = EditObjectDacl(
  1108. hwndOwner,
  1109. ObjectName,
  1110. Token,
  1111. SecurityDescriptor,
  1112. &DefaultSecurityInfo,
  1113. ApplyTokenDefaultDacl,
  1114. &EditResult
  1115. );
  1116. if (!Result) {
  1117. DbgPrint("Failed to edit token default ACL\n");
  1118. }
  1119. CleanupAndExit:
  1120. if (SecurityDescriptor != NULL) {
  1121. Free(SecurityDescriptor);
  1122. }
  1123. if (DefaultDacl != NULL) {
  1124. Free(DefaultDacl);
  1125. }
  1126. return(Result);
  1127. }