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.

2708 lines
88 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1996.
  5. //
  6. // File: MARTABAS.CXX
  7. //
  8. // Contents: Implementation of the base MARTA funcitons
  9. //
  10. // History: 22-Jul-96 MacM Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <aclpch.hxx>
  14. #pragma hdrstop
  15. #include <ntprov.hxx>
  16. #include <strings.h>
  17. #include <ntdsguid.h>
  18. CSList gWrkrList(NtProvFreeWorkerItem); // List of active worker threads
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: AccProvGetCapabilities
  22. //
  23. // Synopsis: Gets the provider capabilities
  24. //
  25. // Arguments: [IN fClass] -- Class of capabilities to request
  26. // [OUT pulCaps] -- Provider capabilities
  27. //
  28. // Returns: VOID
  29. //
  30. // Notes:
  31. //
  32. //----------------------------------------------------------------------------
  33. VOID
  34. WINAPI
  35. AccProvGetCapabilities(IN ULONG fClass,
  36. OUT PULONG pulCaps)
  37. {
  38. acDebugOut((DEB_TRACE_API,"in.out AccProvGetCapabilities\n"));
  39. if(fClass == ACTRL_CLASS_GENERAL)
  40. {
  41. *pulCaps = ACTRL_CAP_KNOWS_SIDS | ACTRL_CAP_SUPPORTS_HANDLES;
  42. }
  43. else
  44. {
  45. *pulCaps = ACTRL_CAP_NONE;
  46. }
  47. return;
  48. }
  49. //+---------------------------------------------------------------------------
  50. //
  51. // Function: AccProvIsObjectAccessible
  52. //
  53. // Synopsis: Determines if the given path is accessible or not
  54. //
  55. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  56. // [IN ObjectType] -- Type of the object
  57. //
  58. // Returns: ERROR_SUCCESS -- The path is recognized
  59. // ERROR_PATH_NOT_FOUND -- The path was not recognized
  60. //
  61. // Notes:
  62. //
  63. //----------------------------------------------------------------------------
  64. DWORD
  65. WINAPI
  66. AccProvIsObjectAccessible(IN LPCWSTR pwszObjectPath,
  67. IN SE_OBJECT_TYPE ObjectType)
  68. {
  69. acDebugOut((DEB_TRACE_API,"in AccProvIsObjectAccessible\n"));
  70. DWORD dwErr = ERROR_PATH_NOT_FOUND;
  71. PWSTR DsServerlessPath, OldServerPath = NULL;
  72. static NTMARTA_ACCESS_CACHE rgAccessCache[MAX_ACCESS_ENTRIES];
  73. static ULONG cCacheEntries = 0;
  74. static ULONG iCacheOldest = 0;
  75. //
  76. // First, check our cache. Maybe we can get out cheap. Note that
  77. // we expect our result to be failure when we start.
  78. //
  79. ULONG dwObjLen = wcslen(pwszObjectPath);
  80. if(dwObjLen < MAX_PATH)
  81. {
  82. RtlAcquireResourceShared(&gCacheLock, TRUE);
  83. for(ULONG iIndex = 0;
  84. iIndex < cCacheEntries && dwErr == ERROR_PATH_NOT_FOUND;
  85. iIndex++)
  86. {
  87. //
  88. // We'll have to do this base on object type...
  89. //
  90. switch(ObjectType)
  91. {
  92. case SE_SERVICE:
  93. case SE_PRINTER:
  94. case SE_REGISTRY_KEY:
  95. //
  96. // See if it's a UNC name, in which case we'll compare
  97. // the only the server\\share name.
  98. //
  99. if(dwObjLen > 1 && pwszObjectPath[1] == L'\\')
  100. {
  101. //
  102. // It's a UNC name
  103. //
  104. if(_wcsnicmp(pwszObjectPath,
  105. rgAccessCache[iIndex].wszPath,
  106. rgAccessCache[iIndex].cLen) == 0 &&
  107. (*(pwszObjectPath + rgAccessCache[iIndex].cLen)
  108. == L'\0' ||
  109. *(pwszObjectPath + rgAccessCache[iIndex].cLen)
  110. == L'\\'))
  111. {
  112. dwErr = ERROR_SUCCESS;
  113. }
  114. }
  115. else
  116. {
  117. if(_wcsicmp(pwszObjectPath,
  118. rgAccessCache[iIndex].wszPath) == 0)
  119. {
  120. dwErr = ERROR_SUCCESS;
  121. }
  122. }
  123. break;
  124. case SE_DS_OBJECT:
  125. case SE_DS_OBJECT_ALL:
  126. //
  127. // These have to match exact. Handle the case where we were given a
  128. // server name prefixed DS path
  129. //
  130. if(IS_UNC_PATH(pwszObjectPath, dwObjLen ) )
  131. {
  132. DsServerlessPath = wcschr(pwszObjectPath+2, L'\\');
  133. if(DsServerlessPath != NULL)
  134. {
  135. DsServerlessPath++;
  136. OldServerPath = ( PWSTR )pwszObjectPath;
  137. pwszObjectPath = DsServerlessPath;
  138. dwObjLen = wcslen(DsServerlessPath);
  139. }
  140. }
  141. if(dwObjLen == rgAccessCache[iIndex].cLen &&
  142. _wcsicmp(pwszObjectPath,
  143. rgAccessCache[iIndex].wszPath) == 0)
  144. {
  145. dwErr = ERROR_SUCCESS;
  146. }
  147. break;
  148. case SE_FILE_OBJECT:
  149. case SE_KERNEL_OBJECT:
  150. case SE_LMSHARE:
  151. case SE_WMIGUID_OBJECT:
  152. if(dwObjLen == rgAccessCache[iIndex].cLen &&
  153. _wcsicmp(pwszObjectPath,
  154. rgAccessCache[iIndex].wszPath) == 0)
  155. {
  156. dwErr = ERROR_SUCCESS;
  157. }
  158. break;
  159. }
  160. //
  161. // Make sure our types match...
  162. //
  163. if(dwErr == ERROR_SUCCESS && ObjectType != rgAccessCache[iIndex].ObjectType)
  164. {
  165. dwErr = ERROR_PATH_NOT_FOUND;
  166. }
  167. #ifdef DBG
  168. if(dwErr == ERROR_SUCCESS)
  169. {
  170. acDebugOut((DEB_TRACE_CACHE, "Object %ws [%lu] found in cache!\n",
  171. rgAccessCache[iIndex].wszPath,
  172. rgAccessCache[iIndex].ObjectType));
  173. }
  174. #endif
  175. }
  176. RtlReleaseResource(&gCacheLock);
  177. }
  178. //
  179. // If we got a match, return
  180. //
  181. if(dwErr == ERROR_SUCCESS)
  182. {
  183. return(ERROR_SUCCESS);
  184. }
  185. //
  186. // Well, that didn't work, so we'll have to go check. Note that there
  187. // is not a lock here, so there is a window whereby an entry could be added
  188. // for the path that we are currently checking. If that happens, it only
  189. // means that the same entry will be in the cache more than once. This
  190. // is harmless.
  191. //
  192. HANDLE hHandle;
  193. switch (ObjectType)
  194. {
  195. case SE_FILE_OBJECT:
  196. dwErr = IsFilePathLocalOrLM((PWSTR)pwszObjectPath);
  197. break;
  198. case SE_SERVICE:
  199. dwErr = OpenServiceObject((PWSTR)pwszObjectPath,
  200. SERVICE_USER_DEFINED_CONTROL,
  201. (SC_HANDLE *)&hHandle);
  202. if(dwErr == ERROR_SUCCESS)
  203. {
  204. CloseServiceHandle((SC_HANDLE)hHandle);
  205. }
  206. else
  207. {
  208. if(dwErr == ERROR_SERVICE_DOES_NOT_EXIST ||
  209. dwErr == ERROR_INVALID_NAME)
  210. {
  211. dwErr = ERROR_PATH_NOT_FOUND;
  212. }
  213. }
  214. break;
  215. case SE_PRINTER:
  216. dwErr = OpenPrinterObject((PWSTR)pwszObjectPath,
  217. PRINTER_ACCESS_USE,
  218. &hHandle);
  219. if(dwErr == ERROR_SUCCESS)
  220. {
  221. ClosePrinter(hHandle);
  222. }
  223. else
  224. {
  225. if(dwErr == ERROR_INVALID_PRINTER_NAME)
  226. {
  227. dwErr = ERROR_PATH_NOT_FOUND;
  228. }
  229. }
  230. break;
  231. case SE_REGISTRY_KEY:
  232. dwErr = OpenRegistryObject((PWSTR)pwszObjectPath,
  233. KEY_EXECUTE,
  234. &hHandle);
  235. if(dwErr == ERROR_SUCCESS)
  236. {
  237. RegCloseKey((HKEY)hHandle);
  238. }
  239. else
  240. {
  241. if(dwErr == ERROR_INVALID_PARAMETER ||
  242. dwErr == ERROR_FILE_NOT_FOUND)
  243. {
  244. dwErr = ERROR_PATH_NOT_FOUND;
  245. }
  246. }
  247. break;
  248. case SE_LMSHARE:
  249. //
  250. // Note that this doesn't have to be a local share, just a lan man
  251. // share
  252. //
  253. dwErr = PingLmShare(pwszObjectPath);
  254. break;
  255. case SE_KERNEL_OBJECT: // FALL THROUGH
  256. case SE_WMIGUID_OBJECT:
  257. //
  258. // Can't have kernel objects outside of NT, so just return success
  259. //
  260. dwErr = ERROR_SUCCESS;
  261. break;
  262. case SE_DS_OBJECT: // FALL THROUGH
  263. case SE_DS_OBJECT_ALL:
  264. dwErr = PingDSObj(OldServerPath ? OldServerPath : pwszObjectPath);
  265. break;
  266. default:
  267. //
  268. // Unknown object type. Pass it on.
  269. //
  270. dwErr = ERROR_PATH_NOT_FOUND;
  271. break;
  272. }
  273. if(dwErr == ERROR_ACCESS_DENIED)
  274. {
  275. dwErr = ERROR_SUCCESS;
  276. }
  277. //
  278. // Add it to the cache, if we succeeded
  279. //
  280. if(dwErr == ERROR_SUCCESS &&
  281. (ObjectType != SE_KERNEL_OBJECT && ObjectType != SE_WMIGUID_OBJECT))
  282. {
  283. //
  284. // Lock the cache
  285. //
  286. RtlAcquireResourceExclusive(&gCacheLock, TRUE);
  287. //
  288. // For some items, we'll want to save the root of the path, since it
  289. // is not possible to have linked services, registry keys, etc, while
  290. // for files and shares, it can cause problems. If an entry is too
  291. // long to be cached, we'll ignore it.
  292. //
  293. if(dwObjLen <= MAX_PATH)
  294. {
  295. //
  296. // Save off the object type and path name. For those that
  297. // need it, we'll go through and shorten them as requried.
  298. //
  299. rgAccessCache[iCacheOldest].ObjectType = ObjectType;
  300. wcscpy(rgAccessCache[iCacheOldest].wszPath,
  301. pwszObjectPath);
  302. rgAccessCache[iCacheOldest].cLen = dwObjLen;
  303. PWSTR pwszLop = rgAccessCache[iCacheOldest].wszPath;
  304. switch (ObjectType)
  305. {
  306. case SE_SERVICE:
  307. case SE_PRINTER:
  308. case SE_REGISTRY_KEY:
  309. //
  310. // See if it's a UNC name, in which case we'll lop
  311. // it off
  312. //
  313. if(IS_UNC_PATH(pwszObjectPath, dwObjLen))
  314. {
  315. //
  316. // It's a UNC name, so lop it off
  317. //
  318. pwszLop = wcschr(pwszLop + 2,
  319. L'\\');
  320. if(pwszLop != NULL)
  321. {
  322. pwszLop = wcschr(pwszLop + 1, '\\');
  323. if(pwszLop != NULL)
  324. {
  325. *pwszLop = L'\0';
  326. rgAccessCache[iCacheOldest].cLen = (DWORD)(pwszLop -
  327. rgAccessCache[iCacheOldest].wszPath);
  328. }
  329. }
  330. }
  331. break;
  332. case SE_DS_OBJECT:
  333. case SE_DS_OBJECT_ALL:
  334. //
  335. // Save off the domain name part
  336. //
  337. //
  338. // Note that we'll get the object in RDN format, so
  339. // it's a simple matter to lop it off if necessary
  340. pwszLop = wcschr(pwszLop, L'\\');
  341. if(pwszLop != NULL)
  342. {
  343. *pwszLop = L'\0';
  344. rgAccessCache[iCacheOldest].cLen = (DWORD)(pwszLop -
  345. rgAccessCache[iCacheOldest].wszPath);
  346. }
  347. break;
  348. }
  349. //
  350. // Update our indexes and counts
  351. //
  352. if(cCacheEntries < MAX_ACCESS_ENTRIES)
  353. {
  354. cCacheEntries++;
  355. }
  356. iCacheOldest++;
  357. if(iCacheOldest == MAX_ACCESS_ENTRIES)
  358. {
  359. iCacheOldest = 0;
  360. }
  361. }
  362. RtlReleaseResource(&gCacheLock);
  363. }
  364. if ( dwErr == ERROR_INVALID_NAME ) {
  365. acDebugOut(( DEB_ERROR, "%ws returned ERROR_INVALID_NAME\n", pwszObjectPath ));
  366. ASSERT( FALSE );
  367. }
  368. acDebugOut((DEB_TRACE_API,"out AccProvIsObjectAccessible: %lu\n", dwErr));
  369. return(dwErr);
  370. }
  371. //+---------------------------------------------------------------------------
  372. //
  373. // Function: AccProvHandleIsObjectAccessible
  374. //
  375. // Synopsis: Determines if the given object is accessible or not given
  376. // a handle to it
  377. //
  378. // Arguments: [IN hObject] -- Object handle
  379. // [IN ObjectType] -- Type of the object
  380. //
  381. // Returns: ERROR_SUCCESS -- The path is recognized
  382. // ERROR_PATH_NOT_FOUND -- The path was not recognized
  383. //
  384. // Notes:
  385. //
  386. //----------------------------------------------------------------------------
  387. DWORD
  388. WINAPI
  389. AccProvHandleIsObjectAccessible(IN HANDLE hObject,
  390. IN SE_OBJECT_TYPE ObjectType)
  391. {
  392. acDebugOut((DEB_TRACE_API,"in AccProvHandleIsObjectAccessible\n"));
  393. DWORD dwErr = ERROR_PATH_NOT_FOUND;
  394. //
  395. // Because a handle can get reused, we can't cache them like we did
  396. // above...
  397. //
  398. switch (ObjectType)
  399. {
  400. case SE_FILE_OBJECT:
  401. {
  402. DWORD dwHigh;
  403. DWORD dwSize = GetFileSize(hObject,
  404. &dwHigh);
  405. if(dwSize == 0xFFFFFFFF)
  406. {
  407. dwErr = GetLastError();
  408. }
  409. else
  410. {
  411. dwErr = ERROR_SUCCESS;
  412. }
  413. }
  414. break;
  415. case SE_SERVICE:
  416. {
  417. SERVICE_STATUS SvcStatus;
  418. if(QueryServiceStatus((SC_HANDLE)hObject,
  419. &SvcStatus) == FALSE)
  420. {
  421. dwErr = GetLastError();
  422. }
  423. else
  424. {
  425. dwErr = ERROR_SUCCESS;
  426. }
  427. }
  428. break;
  429. case SE_PRINTER:
  430. {
  431. dwErr = LoadDLLFuncTable();
  432. if(dwErr == ERROR_SUCCESS)
  433. {
  434. ULONG cNeeded;
  435. if(DLLFuncs.PGetPrinter(hObject,
  436. 1,
  437. NULL,
  438. 0,
  439. &cNeeded) == FALSE)
  440. {
  441. dwErr = GetLastError();
  442. if(dwErr == ERROR_INSUFFICIENT_BUFFER)
  443. {
  444. dwErr = ERROR_SUCCESS;
  445. }
  446. }
  447. }
  448. }
  449. break;
  450. case SE_REGISTRY_KEY:
  451. dwErr = RegQueryInfoKey((HKEY)hObject,
  452. NULL,
  453. NULL,
  454. NULL,
  455. NULL,
  456. NULL,
  457. NULL,
  458. NULL,
  459. NULL,
  460. NULL,
  461. NULL,
  462. NULL);
  463. break;
  464. case SE_KERNEL_OBJECT: // FALL THROUGH
  465. case SE_WINDOW_OBJECT: // FALL THROUGH
  466. case SE_WMIGUID_OBJECT:
  467. //
  468. // Can't have kernel/windows objects outside of NT, so just return
  469. // success
  470. //
  471. dwErr = ERROR_SUCCESS;
  472. break;
  473. case SE_LMSHARE: // FALL THROUGH
  474. case SE_DS_OBJECT: // FALL THROUGH
  475. case SE_DS_OBJECT_ALL:
  476. //
  477. // Can't have handles to DS objects
  478. //
  479. dwErr = ERROR_PATH_NOT_FOUND;
  480. break;
  481. default:
  482. //
  483. // Unknown object type. Pass it on.
  484. //
  485. dwErr = ERROR_PATH_NOT_FOUND;
  486. break;
  487. }
  488. //
  489. // Make sure the reason we failed isn't because of permissions
  490. //
  491. if(dwErr == ERROR_ACCESS_DENIED)
  492. {
  493. dwErr = ERROR_SUCCESS;
  494. }
  495. acDebugOut((DEB_TRACE_API,"out AccProvIsObjectAccessible: %lu\n", dwErr));
  496. return(dwErr);
  497. }
  498. //+---------------------------------------------------------------------------
  499. //
  500. // Function: AccProvCancelOperation
  501. //
  502. // Synopsis: Cancels an ongoing operation.
  503. //
  504. // Arguments: [IN pOverlapped] -- Operation to cancel
  505. //
  506. // Returns: ERROR_SUCCESS -- Success
  507. // ERROR_INVALID_PARAMETER -- A bad overlapped structure was
  508. // given
  509. //
  510. // Notes:
  511. //
  512. //----------------------------------------------------------------------------
  513. DWORD
  514. WINAPI
  515. AccProvCancelOperation(IN PACTRL_OVERLAPPED pOverlapped)
  516. {
  517. DWORD dwErr = ERROR_SUCCESS;
  518. //
  519. // Ok, first, grab a read lock, so nobody inserts on us, and find the
  520. // right node
  521. //
  522. PNTMARTA_WRKR_INFO pWrkrNode = NULL;
  523. {
  524. // RtlAcquireResourceShared(&gWrkrLock, TRUE);
  525. RtlAcquireResourceExclusive(&gWrkrLock, TRUE);
  526. pWrkrNode = (PNTMARTA_WRKR_INFO)gWrkrList.Find((PVOID)pOverlapped,
  527. NtProvFindWorkerItem);
  528. RtlReleaseResource(&gWrkrLock);
  529. }
  530. if(pWrkrNode == NULL)
  531. {
  532. dwErr = ERROR_INVALID_PARAMETER;
  533. }
  534. else
  535. {
  536. //
  537. // All right. We'll set our stop flag, and wait for it to return..
  538. // It doesn't matter what we set the flag to, since all we need to do
  539. // is set it non-0
  540. //
  541. pWrkrNode->fState++;
  542. //
  543. // Now, wait for the call to finish
  544. //
  545. WaitForSingleObject(pWrkrNode->hWorker,
  546. INFINITE);
  547. }
  548. return(dwErr);
  549. }
  550. //+---------------------------------------------------------------------------
  551. //
  552. // Function: AccProvGetOperationResults
  553. //
  554. // Synopsis: Gets the results of an operation
  555. //
  556. // Arguments: [IN pOverlapped] -- Operation to cancel
  557. // [OUT dwResults] -- Where the results are returned
  558. // [OUT pcProcessed] -- Number of items processed
  559. //
  560. // Returns: ERROR_SUCCESS -- Success
  561. // ERROR_INVALID_PARAMETER -- A bad overlapped structure was
  562. // given
  563. // ERROR_IO_PENDING -- Operation hasn't completed yet
  564. //
  565. // Notes:
  566. //
  567. //----------------------------------------------------------------------------
  568. DWORD
  569. WINAPI
  570. AccProvGetOperationResults(IN PACTRL_OVERLAPPED pOverlapped,
  571. OUT PDWORD dwResults,
  572. OUT PDWORD pcProcessed)
  573. {
  574. DWORD dwErr = ERROR_SUCCESS;
  575. PNTMARTA_WRKR_INFO pWrkrNode = NULL;
  576. //
  577. // Ok, first, grab a write lock. This will prevent anyone from
  578. // reading and or writing to the list, until we get done updating
  579. // our overlapped structure.
  580. //
  581. RtlAcquireResourceExclusive(&gWrkrLock, TRUE);
  582. pWrkrNode = (PNTMARTA_WRKR_INFO)gWrkrList.Find((PVOID)pOverlapped,
  583. NtProvFindWorkerItem);
  584. RtlReleaseResource(&gWrkrLock);
  585. if(pWrkrNode == NULL)
  586. {
  587. //
  588. // Now, the reason we may have not found the node is that somebody
  589. // has removed it. If so, check our overlapped structure, since
  590. // that will have been updated by the last call
  591. //
  592. if(pOverlapped->hEvent != NULL)
  593. {
  594. dwErr = ERROR_INVALID_PARAMETER;
  595. }
  596. else
  597. {
  598. *dwResults = pOverlapped->Reserved2;
  599. if(pcProcessed != NULL)
  600. {
  601. *pcProcessed = pOverlapped->Reserved1;
  602. }
  603. }
  604. }
  605. else
  606. {
  607. //
  608. // See if the thread has stopped processing or not
  609. //
  610. if(WaitForSingleObject(pWrkrNode->hWorker, 0) == WAIT_TIMEOUT)
  611. {
  612. if(pcProcessed != NULL)
  613. {
  614. *pcProcessed = pWrkrNode->cProcessed;
  615. }
  616. dwErr = ERROR_IO_PENDING;
  617. }
  618. else
  619. {
  620. //
  621. // Get the results of the thread exit first.
  622. //
  623. if(GetExitCodeThread(pWrkrNode->hWorker,
  624. dwResults) == FALSE)
  625. {
  626. dwErr = GetLastError();
  627. }
  628. else
  629. {
  630. dwErr = ERROR_SUCCESS;
  631. CloseHandle(pWrkrNode->hWorker);
  632. pWrkrNode->hWorker = NULL;
  633. //
  634. // Save off the results. They go in Reserved2 parameter
  635. //
  636. pOverlapped->Reserved2 = *dwResults;
  637. pOverlapped->Reserved1 = pWrkrNode->cProcessed;
  638. //
  639. // Remove the node from our list, and do our updates. We
  640. // need to do all of this before releasing our resource,
  641. // to prevent some race conditions
  642. //
  643. RtlAcquireResourceExclusive(&gWrkrLock, TRUE);
  644. gWrkrList.Remove((PVOID)pWrkrNode);
  645. RtlReleaseResource(&gWrkrLock);
  646. //
  647. // Deallocate our memory
  648. //
  649. AccFree(pWrkrNode);
  650. }
  651. }
  652. }
  653. return(dwErr);
  654. }
  655. //+---------------------------------------------------------------------------
  656. //
  657. // Function: AccProvSetAccessRights
  658. //
  659. // Synopsis: Sets the access rights on the given object. It replaces any
  660. // existing rights.
  661. //
  662. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  663. // [IN ObjectType] -- Type of the object
  664. // [IN pAccessList] -- Optional. The list of access
  665. // rights to set.
  666. // [IN pAuditList] -- Optional. The list of access
  667. // rights to set.
  668. // [IN pOwner] -- Optional. Owner to set
  669. // [IN pGroup] -- Optional. Group to set
  670. // [IN pOverlapped] -- Overlapped structure to use for
  671. // asynchronous control
  672. //
  673. // Returns: ERROR_SUCCESS -- Success
  674. // ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
  675. //
  676. // Notes:
  677. //
  678. //----------------------------------------------------------------------------
  679. DWORD
  680. WINAPI
  681. AccProvSetAccessRights(IN LPCWSTR pwszObjectPath,
  682. IN SE_OBJECT_TYPE ObjectType,
  683. IN SECURITY_INFORMATION SecurityInfo,
  684. IN OPTIONAL PACTRL_ACCESS pAccessList,
  685. IN OPTIONAL PACTRL_AUDIT pAuditList,
  686. IN OPTIONAL PTRUSTEE pOwner,
  687. IN OPTIONAL PTRUSTEE pGroup,
  688. IN PACTRL_OVERLAPPED pOverlapped)
  689. {
  690. DWORD dwErr;
  691. CAccessList *pAccList = new CAccessList;
  692. if(pAccList == NULL)
  693. {
  694. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  695. }
  696. else
  697. {
  698. dwErr = pAccList->SetObjectType(ObjectType);
  699. if(dwErr == ERROR_SUCCESS)
  700. {
  701. if(FLAG_ON(SecurityInfo, DACL_SECURITY_INFORMATION))
  702. {
  703. dwErr = pAccList->AddAccessLists(DACL_SECURITY_INFORMATION,
  704. pAccessList,
  705. FALSE);
  706. }
  707. if(dwErr == ERROR_SUCCESS &&
  708. FLAG_ON(SecurityInfo, SACL_SECURITY_INFORMATION))
  709. {
  710. dwErr = pAccList->AddAccessLists(SACL_SECURITY_INFORMATION,
  711. pAuditList,
  712. FALSE);
  713. }
  714. if(dwErr == ERROR_SUCCESS)
  715. {
  716. //
  717. // Add the owner and group
  718. //
  719. dwErr = pAccList->AddOwnerGroup(SecurityInfo,
  720. pOwner,
  721. pGroup);
  722. }
  723. }
  724. if(dwErr == ERROR_SUCCESS)
  725. {
  726. //
  727. // Finally, if all that worked, we'll do the rest
  728. //
  729. dwErr = NtProvDoSet(pwszObjectPath,
  730. ObjectType,
  731. pAccList,
  732. pOverlapped,
  733. NTMARTA_DELETE_ALIST);
  734. }
  735. if(dwErr != ERROR_SUCCESS)
  736. {
  737. delete(pAccList);
  738. }
  739. }
  740. return(dwErr);
  741. }
  742. //+---------------------------------------------------------------------------
  743. //
  744. // Function: AccProvHandleSetAccessRights
  745. //
  746. // Synopsis: Sets the access rights on the given object. It replaces any
  747. // existing rights.
  748. //
  749. // Arguments: [IN hObject] -- Handle to the object
  750. // [IN ObjectType] -- Type of the object
  751. // [IN pAccessList] -- Optional. The list of access
  752. // rights to set.
  753. // [IN pAuditList] -- Optional. The list of access
  754. // rights to set.
  755. // [IN pOwner] -- Optional. Owner to set
  756. // [IN pGroup] -- Optional. Group to set
  757. // [IN pOverlapped] -- Overlapped structure to use for
  758. // asynchronous control
  759. //
  760. // Returns: ERROR_SUCCESS -- Success
  761. // ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
  762. //
  763. // Notes:
  764. //
  765. //----------------------------------------------------------------------------
  766. DWORD
  767. WINAPI
  768. AccProvHandleSetAccessRights(IN HANDLE hObject,
  769. IN SE_OBJECT_TYPE ObjectType,
  770. IN SECURITY_INFORMATION SecurityInfo,
  771. IN PACTRL_ACCESS pAccessList OPTIONAL,
  772. IN PACTRL_AUDIT pAuditList OPTIONAL,
  773. IN PTRUSTEE pOwner OPTIONAL,
  774. IN PTRUSTEE pGroup OPTIONAL,
  775. IN PACTRL_OVERLAPPED pOverlapped)
  776. {
  777. DWORD dwErr;
  778. CAccessList *pAccList = new CAccessList;
  779. if(pAccList == NULL)
  780. {
  781. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  782. }
  783. else
  784. {
  785. dwErr = pAccList->SetObjectType(ObjectType);
  786. if(dwErr == ERROR_SUCCESS)
  787. {
  788. if(FLAG_ON(SecurityInfo, DACL_SECURITY_INFORMATION))
  789. {
  790. dwErr = pAccList->AddAccessLists(DACL_SECURITY_INFORMATION,
  791. pAccessList,
  792. FALSE);
  793. }
  794. if(dwErr == ERROR_SUCCESS &&
  795. FLAG_ON(SecurityInfo, SACL_SECURITY_INFORMATION))
  796. {
  797. dwErr = pAccList->AddAccessLists(SACL_SECURITY_INFORMATION,
  798. pAuditList,
  799. FALSE);
  800. }
  801. if(dwErr == ERROR_SUCCESS)
  802. {
  803. //
  804. // Add the owner and group
  805. //
  806. dwErr = pAccList->AddOwnerGroup(SecurityInfo,
  807. pOwner,
  808. pGroup);
  809. }
  810. }
  811. if(dwErr == ERROR_SUCCESS)
  812. {
  813. //
  814. // Finally, if all that worked, we'll do the rest
  815. //
  816. dwErr = NtProvDoHandleSet(hObject,
  817. ObjectType,
  818. pAccList,
  819. pOverlapped,
  820. NTMARTA_DELETE_ALIST);
  821. }
  822. if(dwErr != ERROR_SUCCESS)
  823. {
  824. delete pAccList;
  825. }
  826. }
  827. return(dwErr);
  828. }
  829. //+---------------------------------------------------------------------------
  830. //
  831. // Function: AccProvGrantAccessRights
  832. //
  833. // Synopsis: Grants the access rights on the given object. It merges the
  834. // supplied rights with any existing rights.
  835. //
  836. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  837. // [IN ObjectType] -- Type of the object
  838. // [IN pAccessList] -- Optional. The list of access
  839. // rights to set.
  840. // [IN pAuditList] -- Optional. The list of access
  841. // rights to set.
  842. //
  843. // Returns: ERROR_SUCCESS -- The path is recognized
  844. //
  845. // Notes:
  846. //
  847. //----------------------------------------------------------------------------
  848. DWORD
  849. WINAPI
  850. AccProvGrantAccessRights(IN LPCWSTR pwszObjectPath,
  851. IN SE_OBJECT_TYPE ObjectType,
  852. IN OPTIONAL PACTRL_ACCESS pAccessList,
  853. IN OPTIONAL PACTRL_AUDIT pAuditList,
  854. IN PACTRL_OVERLAPPED pOverlapped)
  855. {
  856. DWORD dwErr = ERROR_SUCCESS;
  857. //
  858. // First, read the relevant information. This will involve getting the
  859. // access and audit lists for each property specified in the access and
  860. // audit list.
  861. //
  862. PACTRL_RIGHTS_INFO pRightsList = NULL;
  863. ULONG cItems;
  864. dwErr = NtProvSetRightsList(pAccessList,
  865. pAuditList,
  866. &cItems,
  867. &pRightsList);
  868. if(dwErr == ERROR_SUCCESS)
  869. {
  870. //
  871. // First, read all of the rights
  872. //
  873. CAccessList *pAccList = NULL;
  874. //
  875. // NtProvGetAccessListForObject modifies its first
  876. // parameter, so we can't pass in a CONST string.
  877. //
  878. PWSTR pwszTmpObjectPath = (PWSTR)AccAlloc( (wcslen(pwszObjectPath) + 1) * sizeof( WCHAR ) );
  879. if (pwszTmpObjectPath)
  880. {
  881. wcscpy( pwszTmpObjectPath, pwszObjectPath );
  882. pwszTmpObjectPath[wcslen(pwszObjectPath)] = UNICODE_NULL;
  883. dwErr = NtProvGetAccessListForObject( pwszTmpObjectPath,
  884. ObjectType,
  885. pRightsList,
  886. cItems,
  887. &pAccList);
  888. //
  889. // Now, process the input lists
  890. //
  891. if(dwErr == ERROR_SUCCESS)
  892. {
  893. //
  894. // First, the access list
  895. //
  896. if(pAccessList != NULL)
  897. {
  898. dwErr = pAccList->AddAccessLists(DACL_SECURITY_INFORMATION,
  899. pAccessList,
  900. TRUE);
  901. }
  902. //
  903. // Then, the audit list
  904. //
  905. if(dwErr == ERROR_SUCCESS && pAuditList != NULL)
  906. {
  907. dwErr = pAccList->AddAccessLists(SACL_SECURITY_INFORMATION,
  908. pAuditList,
  909. TRUE);
  910. }
  911. }
  912. if(dwErr == ERROR_SUCCESS)
  913. {
  914. //
  915. // Finally, if all that worked, we'll do the rest
  916. //
  917. dwErr = NtProvDoSet(pwszObjectPath,
  918. ObjectType,
  919. pAccList,
  920. pOverlapped,
  921. NTMARTA_DELETE_ALIST);
  922. }
  923. if(dwErr != ERROR_SUCCESS)
  924. {
  925. delete pAccList;
  926. }
  927. AccFree( pwszTmpObjectPath );
  928. }
  929. else
  930. {
  931. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  932. }
  933. AccFree(pRightsList);
  934. }
  935. return(dwErr);
  936. }
  937. //+---------------------------------------------------------------------------
  938. //
  939. // Function: AccProvHandleGrantAccessRights
  940. //
  941. // Synopsis: Grants the access rights on the given object. It merges the
  942. // supplied rights with any existing rights.
  943. //
  944. // Arguments: [IN hObject] -- Handle to the open object
  945. // [IN ObjectType] -- Type of the object
  946. // [IN pAccessList] -- Optional. The list of access
  947. // rights to set.
  948. // [IN pAuditList] -- Optional. The list of access
  949. // rights to set.
  950. //
  951. // Returns: ERROR_SUCCESS -- The path is recognized
  952. //
  953. // Notes:
  954. //
  955. //----------------------------------------------------------------------------
  956. DWORD
  957. WINAPI
  958. AccProvHandleGrantAccessRights(IN HANDLE hObject,
  959. IN SE_OBJECT_TYPE ObjectType,
  960. IN OPTIONAL PACTRL_ACCESS pAccessList,
  961. IN OPTIONAL PACTRL_AUDIT pAuditList,
  962. IN PACTRL_OVERLAPPED pOverlapped)
  963. {
  964. DWORD dwErr = ERROR_SUCCESS;
  965. //
  966. // First, read the relevant information. This will involve getting the
  967. // access and audit lists for each property specified in the access and
  968. // audit list.
  969. //
  970. PACTRL_RIGHTS_INFO pRightsList = NULL;
  971. ULONG cItems;
  972. dwErr = NtProvSetRightsList(pAccessList,
  973. pAuditList,
  974. &cItems,
  975. &pRightsList);
  976. if(dwErr == ERROR_SUCCESS)
  977. {
  978. //
  979. // First, read all of the rights
  980. //
  981. CAccessList *pAccList = NULL;
  982. dwErr = NtProvGetAccessListForHandle(hObject,
  983. ObjectType,
  984. pRightsList,
  985. cItems,
  986. &pAccList);
  987. //
  988. // Don't need the rights list, so we might as well release it
  989. //
  990. AccFree(pRightsList);
  991. //
  992. // Now, process the input lists
  993. //
  994. if(dwErr == ERROR_SUCCESS)
  995. {
  996. //
  997. // First, the access list
  998. //
  999. if(pAccessList != NULL)
  1000. {
  1001. dwErr = pAccList->AddAccessLists(DACL_SECURITY_INFORMATION,
  1002. pAccessList,
  1003. TRUE);
  1004. }
  1005. //
  1006. // Then, the audit list
  1007. //
  1008. if(dwErr == ERROR_SUCCESS && pAuditList != NULL)
  1009. {
  1010. dwErr = pAccList->AddAccessLists(SACL_SECURITY_INFORMATION,
  1011. pAuditList,
  1012. TRUE);
  1013. }
  1014. }
  1015. if(dwErr == ERROR_SUCCESS)
  1016. {
  1017. //
  1018. // Finally, if all that worked, we'll do the rest
  1019. //
  1020. dwErr = NtProvDoHandleSet(hObject,
  1021. ObjectType,
  1022. pAccList,
  1023. pOverlapped,
  1024. NTMARTA_DELETE_ALIST);
  1025. }
  1026. if(dwErr != ERROR_SUCCESS)
  1027. {
  1028. delete pAccList;
  1029. }
  1030. }
  1031. return(dwErr);
  1032. }
  1033. //+---------------------------------------------------------------------------
  1034. //
  1035. // Function: AccProvRevokeAccessRights
  1036. //
  1037. // Synopsis: Revokes the access rights on the given object. It goes
  1038. // through and removes any explicit entries for the given
  1039. // trustees
  1040. //
  1041. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  1042. // [IN ObjectType] -- Type of the object
  1043. // [IN pwszProperty] -- Optional. The name of the
  1044. // property on the object to revoke
  1045. // for
  1046. // [IN cTrustees] -- Number of trustees in list
  1047. // [IN prgTrustees] -- List of trustees to revoke
  1048. //
  1049. // Returns: ERROR_SUCCESS -- The operation succeeded
  1050. //
  1051. // Notes:
  1052. //
  1053. //----------------------------------------------------------------------------
  1054. DWORD
  1055. WINAPI
  1056. AccProvRevokeAccessRights(IN LPCWSTR pwszObjectPath,
  1057. IN SE_OBJECT_TYPE ObjectType,
  1058. IN OPTIONAL LPCWSTR pwszProperty,
  1059. IN ULONG cTrustees,
  1060. IN PTRUSTEE prgTrustees,
  1061. IN PACTRL_OVERLAPPED pOverlapped)
  1062. {
  1063. DWORD dwErr = ERROR_SUCCESS;
  1064. CAccessList *pAccList = NULL;
  1065. //
  1066. // First, read the relevant information
  1067. //
  1068. if(dwErr == ERROR_SUCCESS)
  1069. {
  1070. ACTRL_RIGHTS_INFO RI;
  1071. RI.pwszProperty = (PWSTR)pwszProperty;
  1072. RI.SeInfo = DACL_SECURITY_INFORMATION;
  1073. PWSTR pwszTmpObjectPath = (PWSTR)AccAlloc( (wcslen(pwszObjectPath) + 1) * sizeof( WCHAR ) );
  1074. if (pwszTmpObjectPath)
  1075. {
  1076. wcscpy( pwszTmpObjectPath, pwszObjectPath );
  1077. pwszTmpObjectPath[wcslen(pwszObjectPath)] = UNICODE_NULL;
  1078. dwErr = NtProvGetAccessListForObject(pwszTmpObjectPath,
  1079. ObjectType,
  1080. &RI,
  1081. 1,
  1082. &pAccList);
  1083. AccFree( pwszTmpObjectPath );
  1084. }
  1085. else
  1086. {
  1087. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1088. }
  1089. }
  1090. for(DWORD iIndex = 0;
  1091. iIndex < cTrustees && dwErr == ERROR_SUCCESS;
  1092. iIndex++)
  1093. {
  1094. dwErr = pAccList->RemoveTrusteeFromAccess(DACL_SECURITY_INFORMATION,
  1095. &(prgTrustees[iIndex]),
  1096. (PWSTR)pwszProperty);
  1097. }
  1098. //
  1099. // Then, do the set
  1100. //
  1101. if(dwErr == ERROR_SUCCESS)
  1102. {
  1103. dwErr = NtProvDoSet(pwszObjectPath,
  1104. ObjectType,
  1105. pAccList,
  1106. pOverlapped,
  1107. NTMARTA_DELETE_ALIST);
  1108. }
  1109. if(dwErr != ERROR_SUCCESS)
  1110. {
  1111. delete pAccList;
  1112. }
  1113. return(dwErr);
  1114. }
  1115. //+---------------------------------------------------------------------------
  1116. //
  1117. // Function: AccProvHandleRevokeAccessRights
  1118. //
  1119. // Synopsis: Revokes the access rights on the given object. It goes
  1120. // through and removes any explicit entries for the given
  1121. // trustees
  1122. //
  1123. // Arguments: [IN hObject] -- Handle to the open object
  1124. // [IN ObjectType] -- Type of the object
  1125. // [IN pwszProperty] -- Optional. The name of the
  1126. // property on the object to revoke
  1127. // for
  1128. // [IN cTrustees] -- Number of trustees in list
  1129. // [IN prgTrustees] -- List of trustees to revoke
  1130. //
  1131. // Returns: ERROR_SUCCESS -- The operation succeeded
  1132. //
  1133. // Notes:
  1134. //
  1135. //----------------------------------------------------------------------------
  1136. DWORD
  1137. WINAPI
  1138. AccProvHandleRevokeAccessRights(IN HANDLE hObject,
  1139. IN SE_OBJECT_TYPE ObjectType,
  1140. IN OPTIONAL LPCWSTR pwszProperty,
  1141. IN ULONG cTrustees,
  1142. IN PTRUSTEE prgTrustees,
  1143. IN PACTRL_OVERLAPPED pOverlapped)
  1144. {
  1145. DWORD dwErr = ERROR_SUCCESS;
  1146. CAccessList *pAccList = NULL;
  1147. //
  1148. // First, read the relevant information
  1149. //
  1150. if(dwErr == ERROR_SUCCESS)
  1151. {
  1152. ACTRL_RIGHTS_INFO RI;
  1153. RI.pwszProperty = (PWSTR)pwszProperty;
  1154. RI.SeInfo = DACL_SECURITY_INFORMATION;
  1155. dwErr = NtProvGetAccessListForHandle(hObject,
  1156. ObjectType,
  1157. &RI,
  1158. 1,
  1159. &pAccList);
  1160. }
  1161. for(DWORD iIndex = 0;
  1162. iIndex < cTrustees && dwErr == ERROR_SUCCESS;
  1163. iIndex++)
  1164. {
  1165. dwErr = pAccList->RemoveTrusteeFromAccess(DACL_SECURITY_INFORMATION,
  1166. &(prgTrustees[iIndex]),
  1167. (PWSTR)pwszProperty);
  1168. }
  1169. //
  1170. // Then, do the set
  1171. //
  1172. if(dwErr == ERROR_SUCCESS)
  1173. {
  1174. dwErr = NtProvDoHandleSet(hObject,
  1175. ObjectType,
  1176. pAccList,
  1177. pOverlapped,
  1178. NTMARTA_DELETE_ALIST);
  1179. }
  1180. if(dwErr != ERROR_SUCCESS)
  1181. {
  1182. delete pAccList;
  1183. }
  1184. return(dwErr);
  1185. }
  1186. //+---------------------------------------------------------------------------
  1187. //
  1188. // Function: AccProvRevokeAuditRights
  1189. //
  1190. // Synopsis: Revokes the audit rights on the given object. It goes
  1191. // through and removes any explicit entries for the given
  1192. // trustees
  1193. //
  1194. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  1195. // [IN ObjectType] -- Type of the object
  1196. // [IN pwszProperty] -- Optional. The name of the
  1197. // property on the object to revoke
  1198. // for
  1199. // [IN cTrustees] -- Number of trustees in list
  1200. // [IN prgTrustees] -- List of trustees to revoke
  1201. //
  1202. // Returns: ERROR_SUCCESS -- The operation succeeded
  1203. //
  1204. // Notes:
  1205. //
  1206. //----------------------------------------------------------------------------
  1207. DWORD
  1208. WINAPI
  1209. AccProvRevokeAuditRights(IN LPCWSTR pwszObjectPath,
  1210. IN SE_OBJECT_TYPE ObjectType,
  1211. IN OPTIONAL LPCWSTR pwszProperty,
  1212. IN ULONG cTrustees,
  1213. IN PTRUSTEE prgTrustees,
  1214. IN PACTRL_OVERLAPPED pOverlapped)
  1215. {
  1216. DWORD dwErr = ERROR_SUCCESS;
  1217. CAccessList *pAccList = NULL;
  1218. //
  1219. // First, read the relevant information
  1220. //
  1221. if(dwErr == ERROR_SUCCESS)
  1222. {
  1223. ACTRL_RIGHTS_INFO RI;
  1224. RI.pwszProperty = (PWSTR)pwszProperty;
  1225. RI.SeInfo = SACL_SECURITY_INFORMATION;
  1226. PWSTR pwszTmpObjectPath = (PWSTR)AccAlloc( (wcslen(pwszObjectPath) + 1) * sizeof( WCHAR ) );
  1227. if (pwszTmpObjectPath)
  1228. {
  1229. wcscpy( pwszTmpObjectPath, pwszObjectPath );
  1230. pwszTmpObjectPath[wcslen(pwszObjectPath)] = UNICODE_NULL;
  1231. dwErr = NtProvGetAccessListForObject(pwszTmpObjectPath,
  1232. ObjectType,
  1233. &RI,
  1234. 1,
  1235. &pAccList);
  1236. AccFree( pwszTmpObjectPath );
  1237. }
  1238. else
  1239. {
  1240. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1241. }
  1242. }
  1243. for(DWORD iIndex = 0;
  1244. iIndex < cTrustees && dwErr == ERROR_SUCCESS;
  1245. iIndex++)
  1246. {
  1247. dwErr = pAccList->RemoveTrusteeFromAccess(SACL_SECURITY_INFORMATION,
  1248. &(prgTrustees[iIndex]),
  1249. (PWSTR)pwszProperty);
  1250. }
  1251. //
  1252. // Then, do the set
  1253. //
  1254. if(dwErr == ERROR_SUCCESS)
  1255. {
  1256. dwErr = NtProvDoSet(pwszObjectPath,
  1257. ObjectType,
  1258. pAccList,
  1259. pOverlapped,
  1260. NTMARTA_DELETE_ALIST);
  1261. }
  1262. if(dwErr != ERROR_SUCCESS)
  1263. {
  1264. delete pAccList;
  1265. }
  1266. return(dwErr);
  1267. }
  1268. //+---------------------------------------------------------------------------
  1269. //
  1270. // Function: AccProvHandleRevokeAuditRights
  1271. //
  1272. // Synopsis: Revokes the audit rights on the given object. It goes
  1273. // through and removes any explicit entries for the given
  1274. // trustees
  1275. //
  1276. // Arguments: [IN hObject] -- Handle to the open object
  1277. // [IN ObjectType] -- Type of the object
  1278. // [IN pwszProperty] -- Optional. The name of the
  1279. // property on the object to revoke
  1280. // for
  1281. // [IN cTrustees] -- Number of trustees in list
  1282. // [IN prgTrustees] -- List of trustees to revoke
  1283. //
  1284. // Returns: ERROR_SUCCESS -- The operation succeeded
  1285. //
  1286. // Notes:
  1287. //
  1288. //----------------------------------------------------------------------------
  1289. DWORD
  1290. WINAPI
  1291. AccProvHandleRevokeAuditRights(IN HANDLE hObject,
  1292. IN SE_OBJECT_TYPE ObjectType,
  1293. IN OPTIONAL LPCWSTR pwszProperty,
  1294. IN ULONG cTrustees,
  1295. IN PTRUSTEE prgTrustees,
  1296. IN PACTRL_OVERLAPPED pOverlapped)
  1297. {
  1298. DWORD dwErr = ERROR_SUCCESS;
  1299. CAccessList *pAccList = NULL;
  1300. //
  1301. // First, read the relevant information
  1302. //
  1303. if(dwErr == ERROR_SUCCESS)
  1304. {
  1305. ACTRL_RIGHTS_INFO RI;
  1306. RI.pwszProperty = (PWSTR)pwszProperty;
  1307. RI.SeInfo = SACL_SECURITY_INFORMATION;
  1308. dwErr = NtProvGetAccessListForHandle(hObject,
  1309. ObjectType,
  1310. &RI,
  1311. 1,
  1312. &pAccList);
  1313. }
  1314. for(DWORD iIndex = 0;
  1315. iIndex < cTrustees && dwErr == ERROR_SUCCESS;
  1316. iIndex++)
  1317. {
  1318. dwErr = pAccList->RemoveTrusteeFromAccess(SACL_SECURITY_INFORMATION,
  1319. &(prgTrustees[iIndex]),
  1320. (PWSTR)pwszProperty);
  1321. }
  1322. //
  1323. // Then, do the set
  1324. //
  1325. if(dwErr == ERROR_SUCCESS)
  1326. {
  1327. dwErr = NtProvDoHandleSet(hObject,
  1328. ObjectType,
  1329. pAccList,
  1330. pOverlapped,
  1331. NTMARTA_DELETE_ALIST);
  1332. }
  1333. if(dwErr != ERROR_SUCCESS)
  1334. {
  1335. delete pAccList;
  1336. }
  1337. return(dwErr);
  1338. }
  1339. //+---------------------------------------------------------------------------
  1340. //
  1341. // Function: AccProvGetAllRights
  1342. //
  1343. // Synopsis: Gets the all the requested rights from the object. This
  1344. // includes the access rights, audit rights, and owner and group
  1345. // if supported.
  1346. //
  1347. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  1348. // [IN ObjectType] -- Type of the object
  1349. // [IN pwszProperty] -- Optional. The name of the
  1350. // property on the object to revoke
  1351. // for
  1352. // [OUT ppAccessList] -- Optional. Where to return the
  1353. // access list
  1354. // [OUT ppAuditList] -- Optional. Where to return the
  1355. // audit list.
  1356. // [OUT ppOwner] -- Number of trustees in list
  1357. // [OUT ppGroup] -- List of trustees to revoke
  1358. //
  1359. // Returns: ERROR_SUCCESS -- The operation succeeded
  1360. // ERROR_INVALID_PARAMETER -- An non-NULL property name was
  1361. // given on an object that doesn't
  1362. // support properties.
  1363. //
  1364. // Notes:
  1365. //
  1366. //----------------------------------------------------------------------------
  1367. DWORD
  1368. WINAPI
  1369. AccProvGetAllRights(IN LPCWSTR pwszObjectPath,
  1370. IN SE_OBJECT_TYPE ObjectType,
  1371. IN LPCWSTR pwszProperty,
  1372. OUT OPTIONAL PACTRL_ACCESS *ppAccessList,
  1373. OUT OPTIONAL PACTRL_AUDIT *ppAuditList,
  1374. OUT OPTIONAL PTRUSTEE *ppOwner,
  1375. OUT OPTIONAL PTRUSTEE *ppGroup)
  1376. {
  1377. acDebugOut((DEB_TRACE_API,"in AccProvGetAllRights\n"));
  1378. DWORD dwErr = ERROR_SUCCESS;
  1379. //
  1380. // Do the simple parameter checks first...
  1381. //
  1382. if(pwszProperty != NULL &&
  1383. !(ObjectType == SE_DS_OBJECT_ALL || ObjectType == SE_DS_OBJECT))
  1384. {
  1385. return(ERROR_INVALID_PARAMETER);
  1386. }
  1387. SECURITY_INFORMATION SeInfo = 0;
  1388. //
  1389. // Determine what we need to read
  1390. //
  1391. if(ppAccessList != NULL)
  1392. {
  1393. SeInfo |= DACL_SECURITY_INFORMATION;
  1394. *ppAccessList = NULL;
  1395. }
  1396. if(ppAuditList != NULL)
  1397. {
  1398. SeInfo |= SACL_SECURITY_INFORMATION;
  1399. *ppAuditList = NULL;
  1400. }
  1401. if(ppOwner != NULL)
  1402. {
  1403. SeInfo |= OWNER_SECURITY_INFORMATION;
  1404. *ppOwner = NULL;
  1405. }
  1406. if(ppGroup != NULL)
  1407. {
  1408. SeInfo |= GROUP_SECURITY_INFORMATION;
  1409. *ppGroup = NULL;
  1410. }
  1411. //
  1412. // If nothing was requested, do nothing...
  1413. //
  1414. if(SeInfo == 0)
  1415. {
  1416. return(ERROR_SUCCESS);
  1417. }
  1418. //
  1419. // Now, go ahead and do the read...
  1420. //
  1421. CAccessList *pAccList;
  1422. ACTRL_RIGHTS_INFO RI;
  1423. RI.pwszProperty = (PWSTR)pwszProperty;
  1424. RI.SeInfo = SeInfo;
  1425. //
  1426. // NtProvGetAccessListForObject modifies its first
  1427. // parameter, so we can't pass in a CONST string.
  1428. //
  1429. PWSTR pwszTmpObjectPath = (PWSTR)AccAlloc( (wcslen(pwszObjectPath) + 1) * sizeof( WCHAR ) );
  1430. if (pwszTmpObjectPath)
  1431. {
  1432. wcscpy( pwszTmpObjectPath, pwszObjectPath );
  1433. pwszTmpObjectPath[wcslen(pwszObjectPath)] = UNICODE_NULL;
  1434. dwErr = NtProvGetAccessListForObject(pwszTmpObjectPath,
  1435. ObjectType,
  1436. &RI,
  1437. 1,
  1438. &pAccList);
  1439. //
  1440. // Now, get the data in the form we need
  1441. //
  1442. if(dwErr == ERROR_SUCCESS)
  1443. {
  1444. //
  1445. // Now, convert the stuff that we need to...
  1446. //
  1447. dwErr = pAccList->MarshalAccessLists(SeInfo,
  1448. ppAccessList,
  1449. ppAuditList);
  1450. if(dwErr == ERROR_SUCCESS && ppOwner != NULL)
  1451. {
  1452. dwErr = pAccList->GetSDSidAsTrustee(OWNER_SECURITY_INFORMATION,
  1453. ppOwner);
  1454. }
  1455. if(dwErr == ERROR_SUCCESS && ppGroup != NULL)
  1456. {
  1457. dwErr = pAccList->GetSDSidAsTrustee(GROUP_SECURITY_INFORMATION,
  1458. ppGroup);
  1459. }
  1460. //
  1461. // Ok, if anything failed, we'll do the cleanup
  1462. //
  1463. if(dwErr != ERROR_SUCCESS)
  1464. {
  1465. if((SeInfo & DACL_SECURITY_INFORMATION) != 0)
  1466. {
  1467. AccFree(*ppAccessList);
  1468. }
  1469. if((SeInfo & SACL_SECURITY_INFORMATION) != 0)
  1470. {
  1471. AccFree(*ppAuditList);
  1472. }
  1473. if((SeInfo & OWNER_SECURITY_INFORMATION) != 0)
  1474. {
  1475. AccFree(*ppOwner);
  1476. }
  1477. if((SeInfo & GROUP_SECURITY_INFORMATION) != 0)
  1478. {
  1479. AccFree(*ppGroup);
  1480. }
  1481. }
  1482. delete pAccList;
  1483. }
  1484. AccFree( pwszTmpObjectPath );
  1485. }
  1486. else
  1487. {
  1488. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1489. }
  1490. //
  1491. // The destruction of the CAclList class will clean up all of the
  1492. // memory we obtained
  1493. //
  1494. acDebugOut((DEB_TRACE_API,"out AccProvGetAllRights: %lu\n", dwErr));
  1495. return(dwErr);
  1496. }
  1497. //+---------------------------------------------------------------------------
  1498. //
  1499. // Function: AccProvHandleGetAllRights
  1500. //
  1501. // Synopsis: Gets the all the requested rights from the object. This
  1502. // includes the access rights, audit rights, and owner and group
  1503. // if supported.
  1504. //
  1505. // Arguments: [IN hObject] -- Handle to the open object
  1506. // [IN ObjectType] -- Type of the object
  1507. // [IN pwszProperty] -- Optional. The name of the
  1508. // property on the object to revoke
  1509. // for
  1510. // [OUT ppAccessList] -- Optional. Where to return the
  1511. // access list
  1512. // [OUT ppAuditList] -- Optional. Where to return the
  1513. // audit list.
  1514. // [OUT ppOwner] -- Number of trustees in list
  1515. // [OUT ppGroup] -- List of trustees to revoke
  1516. //
  1517. // Returns: ERROR_SUCCESS -- The operation succeeded
  1518. // ERROR_INVALID_PARAMETER -- An non-NULL property name was
  1519. // given on an object that doesn't
  1520. // support properties.
  1521. //
  1522. // Notes:
  1523. //
  1524. //----------------------------------------------------------------------------
  1525. DWORD
  1526. WINAPI
  1527. AccProvHandleGetAllRights(IN HANDLE hObject,
  1528. IN SE_OBJECT_TYPE ObjectType,
  1529. IN LPCWSTR pwszProperty,
  1530. OUT OPTIONAL PACTRL_ACCESS *ppAccessList,
  1531. OUT OPTIONAL PACTRL_AUDIT *ppAuditList,
  1532. OUT OPTIONAL PTRUSTEE *ppOwner,
  1533. OUT OPTIONAL PTRUSTEE *ppGroup)
  1534. {
  1535. acDebugOut((DEB_TRACE_API,"in AccProvHandleGetAllRights\n"));
  1536. DWORD dwErr = ERROR_SUCCESS;
  1537. //
  1538. // Do the simple parameter checks first...
  1539. //
  1540. if(pwszProperty != NULL &&
  1541. (ObjectType != SE_DS_OBJECT_ALL && ObjectType != SE_DS_OBJECT))
  1542. {
  1543. return(ERROR_INVALID_PARAMETER);
  1544. }
  1545. SECURITY_INFORMATION SeInfo = 0;
  1546. //
  1547. // Determine what we need to read
  1548. //
  1549. if(ppAccessList != NULL)
  1550. {
  1551. SeInfo |= DACL_SECURITY_INFORMATION;
  1552. *ppAccessList = NULL;
  1553. }
  1554. if(ppAuditList != NULL)
  1555. {
  1556. SeInfo |= SACL_SECURITY_INFORMATION;
  1557. *ppAuditList = NULL;
  1558. }
  1559. if(ppOwner != NULL)
  1560. {
  1561. SeInfo |= OWNER_SECURITY_INFORMATION;
  1562. *ppOwner = NULL;
  1563. }
  1564. if(ppGroup != NULL)
  1565. {
  1566. SeInfo |= GROUP_SECURITY_INFORMATION;
  1567. *ppGroup = NULL;
  1568. }
  1569. //
  1570. // If nothing was requested, do nothing...
  1571. //
  1572. if(SeInfo == 0)
  1573. {
  1574. return(ERROR_SUCCESS);
  1575. }
  1576. //
  1577. // Now, go ahead and do the read...
  1578. //
  1579. CAccessList *pAccList;
  1580. ACTRL_RIGHTS_INFO RI;
  1581. RI.pwszProperty = (PWSTR)pwszProperty;
  1582. RI.SeInfo = SeInfo;
  1583. dwErr = NtProvGetAccessListForHandle(hObject,
  1584. ObjectType,
  1585. &RI,
  1586. 1,
  1587. &pAccList);
  1588. //
  1589. // Now, get the data in the form we need
  1590. //
  1591. if(dwErr == ERROR_SUCCESS)
  1592. {
  1593. //
  1594. // Now, convert the stuff that we need to...
  1595. //
  1596. dwErr = pAccList->MarshalAccessLists(SeInfo,
  1597. ppAccessList,
  1598. ppAuditList);
  1599. if(dwErr == ERROR_SUCCESS && ppOwner != NULL)
  1600. {
  1601. dwErr = pAccList->GetSDSidAsTrustee(OWNER_SECURITY_INFORMATION,
  1602. ppOwner);
  1603. }
  1604. if(dwErr == ERROR_SUCCESS && ppGroup != NULL)
  1605. {
  1606. dwErr = pAccList->GetSDSidAsTrustee(GROUP_SECURITY_INFORMATION,
  1607. ppGroup);
  1608. }
  1609. //
  1610. // Ok, if anything failed, we'll do the cleanup
  1611. //
  1612. if(dwErr != ERROR_SUCCESS)
  1613. {
  1614. if((SeInfo & DACL_SECURITY_INFORMATION) != 0)
  1615. {
  1616. AccFree(*ppAccessList);
  1617. }
  1618. if((SeInfo & SACL_SECURITY_INFORMATION) != 0)
  1619. {
  1620. AccFree(*ppAuditList);
  1621. }
  1622. if((SeInfo & OWNER_SECURITY_INFORMATION) != 0)
  1623. {
  1624. AccFree(*ppOwner);
  1625. }
  1626. if((SeInfo & GROUP_SECURITY_INFORMATION) != 0)
  1627. {
  1628. AccFree(*ppGroup);
  1629. }
  1630. }
  1631. delete pAccList;
  1632. }
  1633. //
  1634. // The destruction of the CAclList class will clean up all of the
  1635. // memory we obtained
  1636. //
  1637. acDebugOut((DEB_TRACE_API,"out AccProvHandleGetAllRights: %lu\n", dwErr));
  1638. return(dwErr);
  1639. }
  1640. DWORD
  1641. AccProvpDoTrusteeAccessCalculations(IN CAccessList *pAccList,
  1642. IN PTRUSTEE pTrustee,
  1643. IN OUT PTRUSTEE_ACCESS pTrusteeAccess)
  1644. {
  1645. DWORD dwErr;
  1646. ULONG DeniedMask;
  1647. ULONG AllowedMask;
  1648. dwErr = pAccList->GetExplicitAccess(pTrustee,
  1649. (PWSTR)pTrusteeAccess->lpProperty,
  1650. &DeniedMask,
  1651. &AllowedMask);
  1652. if(dwErr == ERROR_SUCCESS)
  1653. {
  1654. //
  1655. // Process the entries
  1656. //
  1657. //
  1658. // It depends on what it is we're looking for...
  1659. //
  1660. pTrusteeAccess->fReturnedAccess = 0;
  1661. if(pTrusteeAccess->fAccessFlags == TRUSTEE_ACCESS_EXPLICIT)
  1662. {
  1663. //
  1664. // Ok, we'll look for these explicit rights
  1665. //
  1666. //
  1667. // First, see if any of our denieds match...
  1668. //
  1669. if (pTrusteeAccess->Access == TRUSTEE_ACCESS_ALL)
  1670. {
  1671. pTrusteeAccess->fReturnedAccess = AllowedMask & ~DeniedMask;
  1672. }
  1673. else
  1674. {
  1675. if((pTrusteeAccess->Access & DeniedMask) == 0)
  1676. {
  1677. //
  1678. // Now, see if we're allowed
  1679. //
  1680. if((pTrusteeAccess->Access & AllowedMask) ==
  1681. pTrusteeAccess->Access)
  1682. {
  1683. pTrusteeAccess->fReturnedAccess =
  1684. TRUSTEE_ACCESS_ALLOWED;
  1685. }
  1686. }
  1687. }
  1688. }
  1689. else if(FLAG_ON(pTrusteeAccess->fAccessFlags, TRUSTEE_ACCESS_READ) ||
  1690. FLAG_ON(pTrusteeAccess->fAccessFlags, TRUSTEE_ACCESS_WRITE))
  1691. {
  1692. //
  1693. // We're only looking for read/write access
  1694. //
  1695. ACCESS_RIGHTS Access[2];
  1696. ULONG fValue[2], i = 0;
  1697. if(FLAG_ON(pTrusteeAccess->fAccessFlags, TRUSTEE_ACCESS_READ))
  1698. {
  1699. Access[i] = ACTRL_READ_CONTROL;
  1700. fValue[i] = TRUSTEE_ACCESS_READ;
  1701. i++;
  1702. }
  1703. if(FLAG_ON(pTrusteeAccess->fAccessFlags, TRUSTEE_ACCESS_WRITE))
  1704. {
  1705. Access[i] = ACTRL_CHANGE_ACCESS | ACTRL_CHANGE_OWNER;
  1706. fValue[i] = TRUSTEE_ACCESS_WRITE;
  1707. i++;
  1708. }
  1709. for(ULONG iIndex = 0; iIndex < i; iIndex++)
  1710. {
  1711. if((Access[iIndex] & DeniedMask) == 0)
  1712. {
  1713. //
  1714. // Now, see if we're allowed
  1715. //
  1716. if((Access[iIndex] & AllowedMask) == Access[iIndex])
  1717. {
  1718. pTrusteeAccess->fReturnedAccess |= fValue[iIndex];
  1719. }
  1720. }
  1721. }
  1722. }
  1723. else
  1724. {
  1725. dwErr = ERROR_INVALID_PARAMETER;
  1726. }
  1727. //
  1728. // If we asked for read/write access, make sure we have them both
  1729. //
  1730. if(dwErr == ERROR_SUCCESS && pTrusteeAccess->fAccessFlags == TRUSTEE_ACCESS_READ_WRITE)
  1731. {
  1732. if( pTrusteeAccess->fReturnedAccess != TRUSTEE_ACCESS_READ_WRITE )
  1733. {
  1734. pTrusteeAccess->fReturnedAccess = 0;
  1735. }
  1736. }
  1737. }
  1738. return(dwErr);
  1739. }
  1740. //+---------------------------------------------------------------------------
  1741. //
  1742. // Function: AccProvGetTrusteesAccess
  1743. //
  1744. // Synopsis: Determines whether the given trustee has the specified
  1745. // rights to the object
  1746. //
  1747. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  1748. // [IN ObjectType] -- Type of the object
  1749. // [IN OUT pTrusteeAccess] -- Type of access to check for
  1750. // and where the access is returned
  1751. //
  1752. // Returns: ERROR_SUCCESS -- The operation succeeded
  1753. //
  1754. // Notes:
  1755. //
  1756. //----------------------------------------------------------------------------
  1757. DWORD
  1758. WINAPI
  1759. AccProvGetTrusteesAccess(IN LPCWSTR pwszObjectPath,
  1760. IN SE_OBJECT_TYPE ObjectType,
  1761. IN PTRUSTEE pTrustee,
  1762. IN OUT PTRUSTEE_ACCESS pTrusteeAccess)
  1763. {
  1764. DWORD dwErr = ERROR_SUCCESS;
  1765. //
  1766. // Ok, first, we'll load all the objects entries that we need
  1767. //
  1768. CAccessList *pAccList;
  1769. ACTRL_RIGHTS_INFO RI;
  1770. RI.pwszProperty = (PWSTR)pTrusteeAccess->lpProperty;
  1771. RI.SeInfo = DACL_SECURITY_INFORMATION;
  1772. PWSTR pwszTmpObjectPath = (PWSTR)AccAlloc( (wcslen(pwszObjectPath) + 1) * sizeof( WCHAR ) );
  1773. if (pwszTmpObjectPath)
  1774. {
  1775. wcscpy( pwszTmpObjectPath, pwszObjectPath );
  1776. pwszTmpObjectPath[wcslen(pwszObjectPath)] = UNICODE_NULL;
  1777. dwErr = NtProvGetAccessListForObject(pwszTmpObjectPath,
  1778. ObjectType,
  1779. &RI,
  1780. 1,
  1781. &pAccList);
  1782. AccFree( pwszTmpObjectPath );
  1783. }
  1784. else
  1785. {
  1786. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1787. }
  1788. if(dwErr == ERROR_SUCCESS)
  1789. {
  1790. dwErr = AccProvpDoTrusteeAccessCalculations(pAccList,
  1791. pTrustee,
  1792. pTrusteeAccess);
  1793. delete pAccList;
  1794. }
  1795. return(dwErr);
  1796. }
  1797. //+---------------------------------------------------------------------------
  1798. //
  1799. // Function: AccProvHandleGetTrusteesAccess
  1800. //
  1801. // Synopsis: Determines whether the given trustee has the specified
  1802. // rights to the object
  1803. //
  1804. // Arguments: [IN hObject] -- Handle to the open object
  1805. // [IN ObjectType] -- Type of the object
  1806. // [IN OUT pTrusteeAccess] -- Type of access to check for
  1807. // and where the access is returned
  1808. //
  1809. // Returns: ERROR_SUCCESS -- The operation succeeded
  1810. //
  1811. // Notes:
  1812. //
  1813. //----------------------------------------------------------------------------
  1814. DWORD
  1815. WINAPI
  1816. AccProvHandleGetTrusteesAccess(IN HANDLE hObject,
  1817. IN SE_OBJECT_TYPE ObjectType,
  1818. IN PTRUSTEE pTrustee,
  1819. IN OUT PTRUSTEE_ACCESS pTrusteeAccess)
  1820. {
  1821. DWORD dwErr = ERROR_SUCCESS;
  1822. //
  1823. // Ok, first, we'll load all the objects entries that we need
  1824. //
  1825. CAccessList *pAccList;
  1826. ACTRL_RIGHTS_INFO RI;
  1827. RI.pwszProperty = (PWSTR)pTrusteeAccess->lpProperty;
  1828. RI.SeInfo = DACL_SECURITY_INFORMATION;
  1829. dwErr = NtProvGetAccessListForHandle(hObject,
  1830. ObjectType,
  1831. &RI,
  1832. 1,
  1833. &pAccList);
  1834. if(dwErr == ERROR_SUCCESS)
  1835. {
  1836. dwErr = AccProvpDoTrusteeAccessCalculations(pAccList,
  1837. pTrustee,
  1838. pTrusteeAccess);
  1839. delete pAccList;
  1840. }
  1841. return(dwErr);
  1842. }
  1843. DWORD
  1844. AccProvpDoAccessAuditedCalculations(IN CAccessList *pAccList,
  1845. IN LPCWSTR pwszProperty,
  1846. IN PTRUSTEE pTrustee,
  1847. IN ACCESS_RIGHTS ulAuditRights,
  1848. OUT PBOOL pfAuditedSuccess,
  1849. OUT PBOOL pfAuditedFailure)
  1850. {
  1851. ULONG SuccessMask;
  1852. ULONG FailureMask;
  1853. DWORD dwErr = pAccList->GetExplicitAudits(pTrustee,
  1854. (PWSTR)pwszProperty,
  1855. &SuccessMask,
  1856. &FailureMask);
  1857. if(dwErr == ERROR_SUCCESS)
  1858. {
  1859. //
  1860. // Process the entries
  1861. //
  1862. *pfAuditedSuccess = FALSE;
  1863. *pfAuditedFailure = FALSE;
  1864. if((ulAuditRights & SuccessMask) == ulAuditRights)
  1865. {
  1866. *pfAuditedSuccess = TRUE;
  1867. }
  1868. if((ulAuditRights & FailureMask) == ulAuditRights)
  1869. {
  1870. *pfAuditedFailure = TRUE;
  1871. }
  1872. }
  1873. return(dwErr);
  1874. }
  1875. //+---------------------------------------------------------------------------
  1876. //
  1877. // Function: AccProvIsAccessAudited
  1878. //
  1879. // Synopsis: Determines whether the given trustee will envoke an audit
  1880. // entry by accessing the object
  1881. //
  1882. // Arguments: [IN pwszObjectPath] -- Path to the object in question
  1883. // [IN ObjectType] -- Type of the object
  1884. // [IN pwszProperty] -- Optional. The name of the
  1885. // property on the object to revoke
  1886. // for
  1887. // [IN pTrustee] -- Trustee for which to check access
  1888. // [IN AuditRights] -- Type of audit we care about
  1889. // [OUT pfAccessAllowed] -- Where the results are returned.
  1890. //
  1891. // Returns: ERROR_SUCCESS -- The operation succeeded
  1892. //
  1893. // Notes:
  1894. //
  1895. //----------------------------------------------------------------------------
  1896. DWORD
  1897. WINAPI
  1898. AccProvIsAccessAudited(IN LPCWSTR pwszObjectPath,
  1899. IN SE_OBJECT_TYPE ObjectType,
  1900. IN LPCWSTR pwszProperty,
  1901. IN PTRUSTEE pTrustee,
  1902. IN ACCESS_RIGHTS AuditRights,
  1903. OUT PBOOL pfAuditedSuccess,
  1904. OUT PBOOL pfAuditedFailure)
  1905. {
  1906. DWORD dwErr = ERROR_SUCCESS;
  1907. //
  1908. // Ok, first, we'll load all the objects entries that we need
  1909. //
  1910. CAccessList *pAccList;
  1911. ACTRL_RIGHTS_INFO RI;
  1912. RI.pwszProperty = (PWSTR)pwszProperty;
  1913. RI.SeInfo = SACL_SECURITY_INFORMATION;
  1914. PWSTR pwszTmpObjectPath = (PWSTR)AccAlloc( (wcslen(pwszObjectPath) + 1) * sizeof( WCHAR ) );
  1915. if (pwszTmpObjectPath)
  1916. {
  1917. wcscpy( pwszTmpObjectPath, pwszObjectPath );
  1918. pwszTmpObjectPath[wcslen(pwszObjectPath)] = UNICODE_NULL;
  1919. dwErr = NtProvGetAccessListForObject(pwszTmpObjectPath,
  1920. ObjectType,
  1921. &RI,
  1922. 1,
  1923. &pAccList);
  1924. AccFree( pwszTmpObjectPath );
  1925. }
  1926. else
  1927. {
  1928. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1929. }
  1930. if(dwErr == ERROR_SUCCESS)
  1931. {
  1932. dwErr = AccProvpDoAccessAuditedCalculations(pAccList,
  1933. pwszProperty,
  1934. pTrustee,
  1935. AuditRights,
  1936. pfAuditedSuccess,
  1937. pfAuditedFailure);
  1938. delete pAccList;
  1939. }
  1940. return(dwErr);
  1941. }
  1942. //+---------------------------------------------------------------------------
  1943. //
  1944. // Function: AccProvHandleIsAccessAudited
  1945. //
  1946. // Synopsis: Determines whether the given trustee will envoke an audit
  1947. // entry by accessing the object
  1948. //
  1949. // Arguments: [IN hObject] -- Handle to the open object
  1950. // [IN ObjectType] -- Type of the object
  1951. // [IN pwszProperty] -- Optional. The name of the
  1952. // property on the object to revoke
  1953. // for
  1954. // [IN pTrustee] -- Trustee for which to check access
  1955. // [IN ulAuditRights] -- Type of audit we care about
  1956. // [OUT pfAccessAllowed] -- Where the results are returned.
  1957. //
  1958. // Returns: ERROR_SUCCESS -- The operation succeeded
  1959. //
  1960. // Notes:
  1961. //
  1962. //----------------------------------------------------------------------------
  1963. DWORD
  1964. WINAPI
  1965. AccProvHandleIsAccessAudited(IN HANDLE hObject,
  1966. IN SE_OBJECT_TYPE ObjectType,
  1967. IN LPCWSTR pwszProperty,
  1968. IN PTRUSTEE pTrustee,
  1969. IN ACCESS_RIGHTS AuditRights,
  1970. OUT PBOOL pfAuditedSuccess,
  1971. OUT PBOOL pfAuditedFailure)
  1972. {
  1973. DWORD dwErr = ERROR_SUCCESS;
  1974. //
  1975. // Ok, first, we'll load all the objects entries that we need
  1976. //
  1977. CAccessList *pAccList;
  1978. ACTRL_RIGHTS_INFO RI;
  1979. RI.pwszProperty = (PWSTR)pwszProperty;
  1980. RI.SeInfo = SACL_SECURITY_INFORMATION;
  1981. dwErr = NtProvGetAccessListForHandle(hObject,
  1982. ObjectType,
  1983. &RI,
  1984. 1,
  1985. &pAccList);
  1986. if(dwErr == ERROR_SUCCESS)
  1987. {
  1988. dwErr = AccProvpDoAccessAuditedCalculations(pAccList,
  1989. pwszProperty,
  1990. pTrustee,
  1991. AuditRights,
  1992. pfAuditedSuccess,
  1993. pfAuditedFailure);
  1994. delete pAccList;
  1995. }
  1996. return(dwErr);
  1997. }
  1998. //+---------------------------------------------------------------------------
  1999. //
  2000. // Function: AccProvpGetAccessInfoPerObjectType
  2001. //
  2002. // Synopsis: Returns the list of available access permissions for the
  2003. // specified object type
  2004. //
  2005. // Arguments: [IN ObjectType] -- Type of the object
  2006. // [IN DsObjType] -- If this is a DS object, the type
  2007. // of the object
  2008. // [IN pwszDsPath] -- Full path to the object
  2009. //
  2010. // [IN lpProperty] -- Optional. If present, the name of
  2011. // the property to get the access
  2012. // rights for.
  2013. // [IN fIsDir] -- If TRUE, the path is a directory
  2014. // [OUT pcEntries] -- Where the count of items is returned
  2015. // [OUT ppAccessInfo] -- Where the list of items is returned
  2016. // [OUT pcControlRights] -- Count of control rights are
  2017. // is returned here
  2018. // [OUT ppControlRights] -- Where the list of control rights
  2019. // is returned
  2020. // [OUT pfAccessFlags] -- Where the provider flags are
  2021. // returned.
  2022. //
  2023. // Returns: ERROR_SUCCESS -- The operation succeeded
  2024. // ERROR_INVALID_PARAMETER -- The operation failed
  2025. //
  2026. // Notes:
  2027. //
  2028. //----------------------------------------------------------------------------
  2029. DWORD
  2030. WINAPI
  2031. AccProvpGetAccessInfoPerObjectType(IN SE_OBJECT_TYPE ObjectType,
  2032. IN BOOL fIsDir,
  2033. IN PWSTR pwszDsPath,
  2034. IN PWSTR lpProperty,
  2035. OUT PULONG pcEntries,
  2036. OUT PACTRL_ACCESS_INFO *ppAccessInfoList,
  2037. OUT PULONG pcControlRights,
  2038. OUT PACTRL_CONTROL_INFOW *ppControlRights,
  2039. OUT PULONG pfAccessFlags)
  2040. {
  2041. DWORD dwErr = ERROR_SUCCESS;
  2042. BOOL ControlRightsValid = FALSE;
  2043. ULONG cStart = 0;
  2044. ULONG cItems = 0;
  2045. #define LENGTH_OF_STR_GUID 37
  2046. #define LENGTH_OF_LONGEST_STRING 20
  2047. //
  2048. // DS control rights
  2049. //
  2050. *pfAccessFlags = ACTRL_ACCESS_NO_OPTIONS;
  2051. *ppControlRights = NULL;
  2052. *pcControlRights = 0;
  2053. *ppAccessInfoList = 0;
  2054. *pcEntries = 0;
  2055. //
  2056. // Do the right thing based on the object type
  2057. //
  2058. switch (ObjectType)
  2059. {
  2060. case SE_LMSHARE: // FALL THROUGH
  2061. case SE_FILE_OBJECT:
  2062. if(fIsDir == TRUE)
  2063. {
  2064. cStart = ACCPROV_DIR_ACCESS;
  2065. cItems = ACCPROV_NUM_DIR;
  2066. }
  2067. else
  2068. {
  2069. cStart = ACCPROV_FILE_ACCESS;
  2070. cItems = ACCPROV_NUM_FILE;
  2071. }
  2072. break;
  2073. case SE_SERVICE:
  2074. cStart = ACCPROV_SERVICE_ACCESS;
  2075. cItems = ACCPROV_NUM_SERVICE;
  2076. break;
  2077. case SE_PRINTER:
  2078. cStart = ACCPROV_PRINT_ACCESS;
  2079. cItems = ACCPROV_NUM_PRINT;
  2080. break;
  2081. case SE_REGISTRY_KEY:
  2082. cStart = ACCPROV_REGISTRY_ACCESS;
  2083. cItems = ACCPROV_NUM_REGISTRY;
  2084. break;
  2085. case SE_KERNEL_OBJECT: // FALL THROUGH
  2086. case SE_WMIGUID_OBJECT:
  2087. cStart = ACCPROV_KERNEL_ACCESS;
  2088. cItems = ACCPROV_NUM_KERNEL;
  2089. break;
  2090. case SE_DS_OBJECT: // FALL THROUGH
  2091. case SE_DS_OBJECT_ALL:
  2092. cStart = ACCPROV_DS_ACCESS;
  2093. cItems = ACCPROV_NUM_DS;
  2094. ControlRightsValid = TRUE;
  2095. break;
  2096. case SE_WINDOW_OBJECT:
  2097. cStart = ACCPROV_WIN_ACCESS;
  2098. cItems = ACCPROV_NUM_WIN;
  2099. break;
  2100. default:
  2101. dwErr = ERROR_INVALID_PARAMETER;
  2102. }
  2103. if(dwErr == ERROR_SUCCESS && ControlRightsValid == FALSE && lpProperty != NULL)
  2104. {
  2105. dwErr = ERROR_INVALID_PARAMETER;
  2106. }
  2107. if(dwErr == ERROR_SUCCESS)
  2108. {
  2109. //
  2110. // Ok, we go through and size all of the strings that we need to add
  2111. //
  2112. ULONG cSize = 0;
  2113. WCHAR wszBuff[ACCPROV_LONGEST_STRING + 1];
  2114. for(ULONG iIndex = 0; iIndex < cItems; iIndex++)
  2115. {
  2116. LoadString(ghDll, cStart + iIndex, wszBuff, ACCPROV_LONGEST_STRING);
  2117. cSize += SIZE_PWSTR(wszBuff);
  2118. }
  2119. //
  2120. // Always return the standard rights, as well...
  2121. //
  2122. for(iIndex = 0; iIndex < ACCPROV_NUM_STD; iIndex++)
  2123. {
  2124. LoadString(ghDll,
  2125. ACCPROV_STD_ACCESS + iIndex,
  2126. wszBuff,
  2127. ACCPROV_LONGEST_STRING);
  2128. cSize += SIZE_PWSTR(wszBuff);
  2129. }
  2130. //
  2131. // Make sure to return the proper count
  2132. //
  2133. *pcEntries = cItems + ACCPROV_NUM_STD;
  2134. //
  2135. // Ok, now we can allocate, and do the same thing again
  2136. //
  2137. *ppAccessInfoList = (PACTRL_ACCESS_INFO)AccAlloc(
  2138. (cItems + ACCPROV_NUM_STD) * sizeof(ACTRL_ACCESS_INFO) +
  2139. cSize);
  2140. if(*ppAccessInfoList == NULL)
  2141. {
  2142. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2143. }
  2144. if(*ppAccessInfoList == NULL)
  2145. {
  2146. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2147. }
  2148. else
  2149. {
  2150. PWSTR pwszStart = (PWSTR)((PBYTE)(*ppAccessInfoList) +
  2151. (cItems + ACCPROV_NUM_STD) * sizeof(ACTRL_ACCESS_INFO));
  2152. //
  2153. // Start with the standard items
  2154. //
  2155. ULONG iLst = 0;
  2156. for(iIndex = 0; iIndex < ACCPROV_NUM_STD; iIndex++)
  2157. {
  2158. LoadString(ghDll,
  2159. ACCPROV_STD_ACCESS + iIndex,
  2160. wszBuff,
  2161. ACCPROV_LONGEST_STRING);
  2162. cSize = SIZE_PWSTR(wszBuff);
  2163. memcpy(pwszStart,
  2164. wszBuff,
  2165. cSize);
  2166. //
  2167. // Handle STD_RIGTHS_ALL as a special case...
  2168. //
  2169. if(iIndex == ACCPROV_NUM_STD - 1)
  2170. {
  2171. (*ppAccessInfoList)[iLst].fAccessPermission = ACTRL_STD_RIGHTS_ALL;
  2172. }
  2173. else
  2174. {
  2175. (*ppAccessInfoList)[iLst].fAccessPermission =
  2176. ACTRL_SYSTEM_ACCESS << iIndex;
  2177. }
  2178. (*ppAccessInfoList)[iLst].lpAccessPermissionName = pwszStart;
  2179. pwszStart = (PWSTR)Add2Ptr(pwszStart,cSize);
  2180. iLst++;
  2181. }
  2182. for(ULONG iIndex = 0; iIndex < cItems; iIndex++)
  2183. {
  2184. LoadString(ghDll,
  2185. cStart + iIndex, wszBuff, ACCPROV_LONGEST_STRING);
  2186. cSize = SIZE_PWSTR(wszBuff);
  2187. memcpy(pwszStart,
  2188. wszBuff,
  2189. cSize);
  2190. (*ppAccessInfoList)[iLst].fAccessPermission =
  2191. ACTRL_PERM_1 << iIndex;
  2192. (*ppAccessInfoList)[iLst].lpAccessPermissionName = pwszStart;
  2193. pwszStart = (PWSTR)Add2Ptr(pwszStart,cSize);
  2194. iLst++;
  2195. }
  2196. //
  2197. // Now, add extra control rights
  2198. //
  2199. if(ObjectType == SE_DS_OBJECT || ObjectType == SE_DS_OBJECT_ALL )
  2200. {
  2201. dwErr = AccctrlLookupRightsByName( NULL,
  2202. pwszDsPath,
  2203. lpProperty,
  2204. pcControlRights,
  2205. ppControlRights);
  2206. //
  2207. // If we can't find the entry we want, return 0 items...
  2208. //
  2209. if(dwErr == ERROR_NOT_FOUND)
  2210. {
  2211. *pcControlRights = 0;
  2212. *ppControlRights = NULL;
  2213. dwErr = ERROR_SUCCESS;
  2214. }
  2215. }
  2216. }
  2217. }
  2218. if(dwErr == ERROR_SUCCESS)
  2219. {
  2220. *pcEntries = cItems + ACCPROV_NUM_STD;
  2221. }
  2222. else
  2223. {
  2224. if(*ppAccessInfoList != NULL)
  2225. {
  2226. AccFree(*ppAccessInfoList);
  2227. *pcEntries = 0;
  2228. }
  2229. }
  2230. return(dwErr);
  2231. }
  2232. //+---------------------------------------------------------------------------
  2233. //
  2234. // Function: AccProvGetAccessInfoPerObjectType
  2235. //
  2236. // Synopsis: Returns the list of available access permissions for the
  2237. // specified object type
  2238. //
  2239. // Arguments: [IN lpObject] -- Full path to the object
  2240. // [IN ObjectType] -- Type of the object
  2241. // [IN lpProperty] -- Optional. If present, the name of
  2242. // the property to get the access
  2243. // rights for.
  2244. // [OUT pcEntries] -- Where the count of items is returned
  2245. // [OUT ppAccessInfo] -- Where the list of items is returned
  2246. // [OUT pfAccessFlags] -- Where the provider flags are
  2247. // returned.
  2248. //
  2249. // Returns: ERROR_SUCCESS -- The operation succeeded
  2250. // ERROR_INVALID_PARAMETER -- The operation failed
  2251. //
  2252. // Notes:
  2253. //
  2254. //----------------------------------------------------------------------------
  2255. DWORD
  2256. WINAPI
  2257. AccProvGetAccessInfoPerObjectType(IN LPCWSTR lpObject,
  2258. IN SE_OBJECT_TYPE ObjectType,
  2259. IN LPCWSTR lpProperty,
  2260. OUT PULONG pcEntries,
  2261. OUT PACTRL_ACCESS_INFO *ppAccessInfoList,
  2262. OUT PULONG pcControlRights,
  2263. OUT PACTRL_CONTROL_INFOW *ppControlRights,
  2264. OUT PULONG pfAccessFlags)
  2265. {
  2266. DWORD dwErr = ERROR_SUCCESS;
  2267. BOOL fIsDir = FALSE;
  2268. if(ObjectType == SE_LMSHARE || ObjectType == SE_FILE_OBJECT)
  2269. {
  2270. //
  2271. // Check to see whether this is a file or a directory...
  2272. //
  2273. ULONG ulAttribs = GetFileAttributes((PWSTR)lpObject);
  2274. if(FLAG_ON(ulAttribs, FILE_ATTRIBUTE_DIRECTORY))
  2275. {
  2276. fIsDir = TRUE;
  2277. }
  2278. }
  2279. if(dwErr == ERROR_SUCCESS)
  2280. {
  2281. dwErr = AccProvpGetAccessInfoPerObjectType(ObjectType,
  2282. fIsDir,
  2283. (LPWSTR)lpObject,
  2284. (LPWSTR)lpProperty,
  2285. pcEntries,
  2286. ppAccessInfoList,
  2287. pcControlRights,
  2288. ppControlRights,
  2289. pfAccessFlags);
  2290. }
  2291. return(dwErr);
  2292. }
  2293. //+---------------------------------------------------------------------------
  2294. //
  2295. // Function: AccProvHandleGetAccessInfoPerObjectType
  2296. //
  2297. // Synopsis: Returns the list of available access permissions for the
  2298. // specified object type
  2299. //
  2300. // Arguments: [IN hObject] -- Handle to the open object
  2301. // [IN ObjectType] -- Type of the object
  2302. // [IN lpProperty] -- Optional. If present, the name of
  2303. // the property to get the access
  2304. // rights for.
  2305. // [OUT pcEntries] -- Where the count of items is returned
  2306. // [OUT ppAccessInfo] -- Where the list of items is returned
  2307. // [OUT pfAccessFlags] -- Where the provider flags are
  2308. // returned.
  2309. //
  2310. // Returns: ERROR_SUCCESS -- The operation succeeded
  2311. // ERROR_INVALID_PARAMETER -- The operation failed
  2312. //
  2313. // Notes:
  2314. //
  2315. //----------------------------------------------------------------------------
  2316. DWORD
  2317. WINAPI
  2318. AccProvHandleGetAccessInfoPerObjectType(IN HANDLE hObject,
  2319. IN SE_OBJECT_TYPE ObjectType,
  2320. IN LPCWSTR lpProperty,
  2321. OUT PULONG pcEntries,
  2322. OUT PACTRL_ACCESS_INFO *ppAccessInfoList,
  2323. OUT PULONG pcControlRights,
  2324. OUT PACTRL_CONTROL_INFOW *ppControlRights,
  2325. OUT PULONG pfAccessFlags)
  2326. {
  2327. DWORD dwErr = ERROR_SUCCESS;
  2328. BOOL fIsDir = FALSE;
  2329. if(ObjectType == SE_LMSHARE || ObjectType == SE_FILE_OBJECT)
  2330. {
  2331. BY_HANDLE_FILE_INFORMATION BHFI;
  2332. //
  2333. // Check to see whether this is a file or a directory...
  2334. //
  2335. if(GetFileInformationByHandle(hObject,
  2336. &BHFI) == FALSE)
  2337. {
  2338. dwErr = GetLastError();
  2339. }
  2340. else
  2341. {
  2342. if(FLAG_ON(BHFI.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY))
  2343. fIsDir = TRUE;
  2344. }
  2345. }
  2346. if(dwErr == ERROR_SUCCESS)
  2347. {
  2348. dwErr = AccProvpGetAccessInfoPerObjectType(ObjectType,
  2349. fIsDir,
  2350. NULL,
  2351. (LPWSTR)lpProperty,
  2352. pcEntries,
  2353. ppAccessInfoList,
  2354. pcControlRights,
  2355. ppControlRights,
  2356. pfAccessFlags);
  2357. }
  2358. return(dwErr);
  2359. }