Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1219 lines
29 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1997
  3. All rights reserved.
  4. Module Name:
  5. prtsec.cxx
  6. Abstract:
  7. Print queue administration.
  8. Author:
  9. Albert Ting (AlbertT) 28-Aug-1995
  10. Environment:
  11. Revision History:
  12. 28-Aug-1995 AlbertT Munged from prtq32.c.
  13. --*/
  14. #include "precomp.hxx"
  15. #pragma hdrstop
  16. #include "time.hxx"
  17. #include "psetup.hxx"
  18. #include "drvsetup.hxx"
  19. #include "instarch.hxx"
  20. #include "portslv.hxx"
  21. #include "dsinterf.hxx"
  22. #include "prtprop.hxx"
  23. #ifdef SECURITY
  24. #ifndef UNICODE
  25. #error "Acledit entrypoints are Unicode only."
  26. #endif
  27. LPCTSTR gpszAclEdit = TEXT( "acledit.dll" );
  28. LPCSTR gpszSedDiscretionaryAclEditor = "SedDiscretionaryAclEditor";
  29. LPCSTR gpszSedSystemAclEditor = "SedSystemAclEditor";
  30. LPCSTR gpszSedTakeOwnership = "SedTakeOwnership";
  31. HINSTANCE TPrinterSecurity::ghLibraryAcledit;
  32. TPrinterSecurity::PFNSED_DISCRETIONARY_ACL_EDITOR
  33. TPrinterSecurity::gpfnSedDiscretionaryAclEditor;
  34. TPrinterSecurity::PFNSED_SYSTEM_ACL_EDITOR
  35. TPrinterSecurity::gpfnSedSystemAclEditor;
  36. TPrinterSecurity::PFNSED_TAKE_OWNERSHIP
  37. TPrinterSecurity::gpfnSedTakeOwnership;
  38. BOOL TPrinterSecurity::gbStringsLoaded = FALSE;
  39. GENERIC_MAPPING
  40. TPrinterSecurity::gGenericMappingPrinters = {
  41. PRINTER_READ,
  42. PRINTER_WRITE,
  43. PRINTER_EXECUTE,
  44. PRINTER_ALL_ACCESS
  45. };
  46. GENERIC_MAPPING
  47. TPrinterSecurity::gGenericMappingDocuments = {
  48. JOB_READ,
  49. JOB_WRITE,
  50. JOB_EXECUTE,
  51. JOB_ALL_ACCESS
  52. };
  53. SED_HELP_INFO
  54. TPrinterSecurity::gHelpInfoPermissions = {
  55. NULL,
  56. {
  57. ID_HELP_PERMISSIONS_MAIN_DLG,
  58. 0,
  59. 0,
  60. ID_HELP_PERMISSIONS_ADD_USER_DLG,
  61. ID_HELP_PERMISSIONS_LOCAL_GROUP,
  62. ID_HELP_PERMISSIONS_GLOBAL_GROUP,
  63. ID_HELP_PERMISSIONS_FIND_ACCOUNT
  64. }
  65. };
  66. SED_HELP_INFO
  67. TPrinterSecurity::gHelpInfoAuditing = {
  68. NULL,
  69. {
  70. ID_HELP_AUDITING_MAIN_DLG,
  71. 0,
  72. 0,
  73. ID_HELP_AUDITING_ADD_USER_DLG,
  74. ID_HELP_AUDITING_LOCAL_GROUP,
  75. ID_HELP_AUDITING_GLOBAL_GROUP,
  76. ID_HELP_AUDITING_FIND_ACCOUNT
  77. }
  78. };
  79. SED_HELP_INFO
  80. TPrinterSecurity::gHelpInfoTakeOwnership = {
  81. NULL,
  82. {
  83. ID_HELP_TAKE_OWNERSHIP
  84. }
  85. };
  86. SED_OBJECT_TYPE_DESCRIPTOR
  87. TPrinterSecurity::gObjectTypeDescriptor = {
  88. SED_REVISION1, // Revision
  89. TRUE, // IsContainer
  90. TRUE, // AllowNewObjectPerms
  91. TRUE, // MapSpecificPermsToGeneric
  92. &TPrinterSecurity::gGenericMappingPrinters, // GenericMapping
  93. &TPrinterSecurity::gGenericMappingDocuments, // GenericMappingNewObjects
  94. NULL, // ObjectTypeName
  95. NULL, // HelpInfo
  96. NULL, // ApplyToSubContainerTitle
  97. NULL, // ApplyToObjectsTitle
  98. NULL, // ApplyToSubContainerConfirmation
  99. NULL, // SpecialObjectAccessTitle
  100. NULL // SpecialNewObjectAccessTitle
  101. };
  102. //
  103. // Application accesses passed to the discretionary ACL editor
  104. // as well as the Take Ownership dialog.
  105. //
  106. SED_APPLICATION_ACCESS
  107. TPrinterSecurity::gpDiscretionaryAccessGroup[TPrinterSecurity::PERMS_COUNT] = {
  108. //
  109. // No Access:
  110. //
  111. {
  112. SED_DESC_TYPE_CONT_AND_NEW_OBJECT, // Type
  113. 0, // AccessMask1
  114. 0, // AccessMask2
  115. NULL // PermissionTitle
  116. },
  117. //
  118. // Print permission:
  119. //
  120. {
  121. SED_DESC_TYPE_CONT_AND_NEW_OBJECT,
  122. GENERIC_EXECUTE | GENERIC_READ | GENERIC_WRITE,
  123. ACCESS_MASK_NEW_OBJ_NOT_SPECIFIED,
  124. NULL
  125. },
  126. //
  127. // Document Administer permission:
  128. //
  129. {
  130. SED_DESC_TYPE_CONT_AND_NEW_OBJECT,
  131. STANDARD_RIGHTS_READ,
  132. GENERIC_ALL,
  133. NULL
  134. },
  135. //
  136. // Administer permission:
  137. //
  138. {
  139. SED_DESC_TYPE_CONT_AND_NEW_OBJECT,
  140. GENERIC_ALL,
  141. GENERIC_ALL,
  142. NULL
  143. }
  144. };
  145. //
  146. // Application accesses passed to the system ACL editor:
  147. //
  148. SED_APPLICATION_ACCESS
  149. TPrinterSecurity::gpSystemAccessGroup[TPrinterSecurity::PERMS_AUDIT_COUNT] = {
  150. //
  151. // Print permission:
  152. //
  153. {
  154. SED_DESC_TYPE_AUDIT,
  155. PRINTER_ACCESS_USE,
  156. ACCESS_MASK_NEW_OBJ_NOT_SPECIFIED,
  157. NULL
  158. },
  159. {
  160. SED_DESC_TYPE_AUDIT,
  161. PRINTER_ACCESS_ADMINISTER | ACCESS_SYSTEM_SECURITY,
  162. ACCESS_MASK_NEW_OBJ_NOT_SPECIFIED,
  163. NULL
  164. },
  165. {
  166. SED_DESC_TYPE_AUDIT,
  167. DELETE,
  168. ACCESS_MASK_NEW_OBJ_NOT_SPECIFIED,
  169. NULL
  170. },
  171. {
  172. SED_DESC_TYPE_AUDIT,
  173. WRITE_DAC,
  174. ACCESS_MASK_NEW_OBJ_NOT_SPECIFIED,
  175. NULL
  176. },
  177. {
  178. SED_DESC_TYPE_AUDIT,
  179. WRITE_OWNER,
  180. ACCESS_MASK_NEW_OBJ_NOT_SPECIFIED,
  181. NULL
  182. }
  183. };
  184. /********************************************************************
  185. Acquire a single privilege. This routine needs to be rewritten
  186. if multiple privleges are required at once.
  187. ********************************************************************/
  188. class TAcquirePrivilege {
  189. SIGNATURE( 'acpr' )
  190. public:
  191. TAcquirePrivilege( LPTSTR pszPrivilegeName );
  192. ~TAcquirePrivilege();
  193. BOOL
  194. bValid(
  195. VOID
  196. )
  197. {
  198. return _pPrivilegesOld ? TRUE : FALSE;
  199. }
  200. private:
  201. enum _CONSTANTS {
  202. kPrivilegeSizeHint = 256,
  203. kPrivCount = 1
  204. };
  205. HANDLE _hToken;
  206. PTOKEN_PRIVILEGES _pPrivilegesOld;
  207. };
  208. /********************************************************************
  209. TAcquirePrivilege
  210. ********************************************************************/
  211. TAcquirePrivilege::
  212. TAcquirePrivilege(
  213. LPTSTR pszPrivilegeName
  214. ) : _hToken( NULL ), _pPrivilegesOld( NULL )
  215. /*++
  216. Routine Description:
  217. This adjusts the token to acquire one privilege.
  218. Note: This is efficient only for acquiring a single privilege.
  219. For multiple privileges, this routine should be rewritten
  220. so that the _hToken is reused.
  221. Arguments:
  222. pszPrivilegeName - Privilege string to acquire.
  223. Return Value:
  224. --*/
  225. {
  226. if( !OpenThreadToken( GetCurrentThread( ),
  227. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  228. TRUE,
  229. &_hToken )){
  230. SPLASSERT( !_hToken );
  231. if( GetLastError() == ERROR_NO_TOKEN ){
  232. //
  233. // This means we are not impersonating anybody.
  234. // Get the token out of the process.
  235. //
  236. if( !OpenProcessToken( GetCurrentProcess( ),
  237. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  238. &_hToken )){
  239. SPLASSERT( !_hToken );
  240. return;
  241. }
  242. } else {
  243. SPLASSERT( !_hToken );
  244. return;
  245. }
  246. }
  247. //
  248. // We have a valid _hToken at this point.
  249. //
  250. BYTE abyPrivileges[sizeof( TOKEN_PRIVILEGES ) +
  251. (( kPrivCount - 1 ) *
  252. sizeof( LUID_AND_ATTRIBUTES ))];
  253. PTOKEN_PRIVILEGES pPrivilegesNew;
  254. pPrivilegesNew = (PTOKEN_PRIVILEGES)abyPrivileges;
  255. ZeroMemory( abyPrivileges, sizeof( abyPrivileges ));
  256. if( !LookupPrivilegeValue( NULL,
  257. pszPrivilegeName,
  258. &pPrivilegesNew->Privileges[0].Luid )){
  259. DBGMSG( DBG_WARN,
  260. ( "AcquirePrivilege.ctr: LookupPrivilegeValue failed: %d\n",
  261. GetLastError( )));
  262. return;
  263. }
  264. //
  265. // Save previous privileges.
  266. //
  267. DWORD cbPrivilegesOld = kPrivilegeSizeHint;
  268. TStatusB bStatus;
  269. Retry:
  270. _pPrivilegesOld = (PTOKEN_PRIVILEGES)AllocMem( cbPrivilegesOld );
  271. if( !_pPrivilegesOld ){
  272. return;
  273. }
  274. //
  275. // Set up the privilege set we will need.
  276. //
  277. pPrivilegesNew->PrivilegeCount = kPrivCount;
  278. //
  279. // Luid set above.
  280. //
  281. pPrivilegesNew->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  282. bStatus DBGCHK = AdjustTokenPrivileges( _hToken,
  283. FALSE,
  284. pPrivilegesNew,
  285. cbPrivilegesOld,
  286. _pPrivilegesOld,
  287. &cbPrivilegesOld );
  288. if( !bStatus ){
  289. FreeMem( _pPrivilegesOld );
  290. _pPrivilegesOld = NULL;
  291. if( GetLastError() == ERROR_INSUFFICIENT_BUFFER ){
  292. goto Retry;
  293. }
  294. DBGMSG( DBG_WARN,
  295. ( "AcquirePrivilege.ctr: AdjustTokenPrivileges failed: Error %d\n",
  296. GetLastError( )));
  297. return;
  298. }
  299. //
  300. // _pPrivilegesOld is our valid check.
  301. //
  302. }
  303. TAcquirePrivilege::
  304. ~TAcquirePrivilege(
  305. VOID
  306. )
  307. /*++
  308. Routine Description:
  309. Restore privileges and free buffer.
  310. _hToken needs to be close if it is non-NULL. _pPrivilegeOld
  311. is our valid check.
  312. Arguments:
  313. Return Value:
  314. --*/
  315. {
  316. if( _pPrivilegesOld ){
  317. TStatusB bStatus;
  318. bStatus DBGCHK = AdjustTokenPrivileges( _hToken,
  319. FALSE,
  320. _pPrivilegesOld,
  321. 0,
  322. NULL,
  323. NULL );
  324. FreeMem( _pPrivilegesOld );
  325. }
  326. if( _hToken ){
  327. CloseHandle( _hToken );
  328. }
  329. }
  330. /********************************************************************
  331. Security.
  332. ********************************************************************/
  333. BOOL
  334. TPrinterSecurity::
  335. bInitStrings(
  336. VOID
  337. )
  338. {
  339. //
  340. // Check whether the strings have been loaded.
  341. //
  342. if( gbStringsLoaded == TRUE ){
  343. return TRUE;
  344. }
  345. gbStringsLoaded = TRUE;
  346. gHelpInfoPermissions.pszHelpFileName = (LPTSTR)gszWindowsHlp;
  347. gHelpInfoAuditing.pszHelpFileName = (LPTSTR)gszWindowsHlp;
  348. gHelpInfoTakeOwnership.pszHelpFileName = (LPTSTR)gszWindowsHlp;
  349. gObjectTypeDescriptor.ObjectTypeName =
  350. pszLoadString( ghInst, IDS_PRINTER );
  351. gpDiscretionaryAccessGroup[PERMS_NOACC].PermissionTitle =
  352. pszLoadString( ghInst, IDS_SEC_NOACCESS );
  353. gpDiscretionaryAccessGroup[PERMS_PRINT].PermissionTitle =
  354. pszLoadString( ghInst, IDS_SEC_PRINT );
  355. gpDiscretionaryAccessGroup[PERMS_DOCAD].PermissionTitle =
  356. pszLoadString( ghInst, IDS_SEC_ADMINISTERDOCUMENTS );
  357. gpDiscretionaryAccessGroup[PERMS_ADMIN].PermissionTitle =
  358. pszLoadString( ghInst, IDS_SEC_ADMINISTER );
  359. gpSystemAccessGroup[PERMS_AUDIT_PRINT].PermissionTitle =
  360. pszLoadString( ghInst, IDS_SEC_AUDIT_PRINT );
  361. gpSystemAccessGroup[PERMS_AUDIT_ADMINISTER].PermissionTitle =
  362. pszLoadString( ghInst, IDS_SEC_AUDIT_ADMINISTER );
  363. gpSystemAccessGroup[PERMS_AUDIT_DELETE].PermissionTitle =
  364. pszLoadString( ghInst, IDS_SEC_AUDIT_DELETE );
  365. gpSystemAccessGroup[PERMS_AUDIT_CHANGE_PERMISSIONS].PermissionTitle =
  366. pszLoadString( ghInst, IDS_SEC_CHANGE_PERMISSIONS );
  367. gpSystemAccessGroup[PERMS_AUDIT_TAKE_OWNERSHIP].PermissionTitle =
  368. pszLoadString( ghInst, IDS_SEC_TAKE_OWNERSHIP );
  369. return TRUE;
  370. }
  371. BOOL
  372. TPrinterSecurity::
  373. bHandleMessage(
  374. UINT uMsg,
  375. WPARAM wParam,
  376. LPARAM lParam
  377. )
  378. {
  379. switch( uMsg ){
  380. case WM_INITDIALOG:
  381. if( !bInitStrings( )){
  382. DBGMSG( DBG_ERROR,
  383. ( "PrinterSecurity.bHandlMessage: InitStrings failed %d\n",
  384. GetLastError( )));
  385. }
  386. return TRUE;
  387. case WM_HELP:
  388. case WM_CONTEXTMENU:
  389. return PrintUIHelp( uMsg, _hDlg, wParam, lParam );
  390. case WM_DESTROY:
  391. return TRUE;
  392. case WM_COMMAND:
  393. switch( GET_WM_COMMAND_ID( wParam, lParam )){
  394. case IDC_SEC_PERMS:
  395. vCallDiscretionaryAclEditor();
  396. break;
  397. case IDC_SEC_AUDIT:
  398. vCallSystemAclEditor();
  399. break;
  400. case IDC_SEC_OWNER:
  401. vCallTakeOwnershipDialog();
  402. break;
  403. }
  404. }
  405. return FALSE;
  406. }
  407. /********************************************************************
  408. Load the dll.
  409. ********************************************************************/
  410. BOOL
  411. TPrinterSecurity::
  412. bLoadAcledit(
  413. VOID
  414. )
  415. /*++
  416. Routine Description:
  417. Loads acledit and sets pfns.
  418. Note: Not multithread safe, no unloading done.
  419. Arguments:
  420. Return Value:
  421. TRUE = success, FALSE = error.
  422. --*/
  423. {
  424. if( ghLibraryAcledit ){
  425. return TRUE;
  426. }
  427. ghLibraryAcledit = LoadLibrary( gpszAclEdit );
  428. if( !ghLibraryAcledit ){
  429. goto Fail;
  430. }
  431. gpfnSedDiscretionaryAclEditor =
  432. (PFNSED_DISCRETIONARY_ACL_EDITOR)GetProcAddress(
  433. ghLibraryAcledit,
  434. gpszSedDiscretionaryAclEditor );
  435. gpfnSedSystemAclEditor =
  436. (PFNSED_SYSTEM_ACL_EDITOR)GetProcAddress(
  437. ghLibraryAcledit,
  438. gpszSedSystemAclEditor );
  439. gpfnSedTakeOwnership =
  440. (PFNSED_TAKE_OWNERSHIP)GetProcAddress(
  441. ghLibraryAcledit,
  442. gpszSedTakeOwnership );
  443. if( !gpfnSedDiscretionaryAclEditor ||
  444. !gpfnSedSystemAclEditor ||
  445. !gpfnSedTakeOwnership ){
  446. FreeLibrary( ghLibraryAcledit );
  447. ghLibraryAcledit = NULL;
  448. goto Fail;
  449. }
  450. return TRUE;
  451. Fail:
  452. vShowUnexpectedError( NULL, IDS_ERR_PRINTER_PROP_TITLE );
  453. return FALSE;
  454. }
  455. /********************************************************************
  456. Bring up each of the dialogs.
  457. ********************************************************************/
  458. VOID
  459. TPrinterSecurity::
  460. vCallDiscretionaryAclEditor(
  461. VOID
  462. )
  463. /*++
  464. Routine Description:
  465. Edit access privileges of print queue.
  466. Arguments:
  467. Return Values:
  468. --*/
  469. {
  470. HANDLE hPrinterWriteDac = NULL;;
  471. DWORD dwAccess = WRITE_DAC;
  472. SED_APPLICATION_ACCESSES ApplicationAccesses;
  473. DWORD SedStatus;
  474. TStatusB bStatus;
  475. TStatus Status;
  476. Status DBGNOCHK = 0;
  477. PPRINTER_INFO_3 pInfo3 = NULL;
  478. DWORD cbInfo3 = 0;
  479. if( !bLoadAcledit( )){
  480. goto Fail;
  481. }
  482. //
  483. // Get the security descriptor.
  484. //
  485. if( !_pPrinterData->hPrinter( )){
  486. Status DBGCHK = ERROR_ACCESS_DENIED;
  487. goto Fail;
  488. }
  489. bStatus DBGCHK = VDataRefresh::bGetPrinter( _pPrinterData->hPrinter(),
  490. 3,
  491. (PVOID*)&pInfo3,
  492. &cbInfo3 );
  493. if( !bStatus ){
  494. SPLASSERT( !pInfo3 );
  495. Status DBGCHK = GetLastError();
  496. goto Fail;
  497. }
  498. SECURITY_CONTEXT SecurityContext;
  499. Status DBGCHK = TPrinter::sOpenPrinter( _pPrinterData->strPrinterName(),
  500. &dwAccess,
  501. &hPrinterWriteDac );
  502. if( Status == ERROR_SUCCESS){
  503. SPLASSERT( hPrinterWriteDac );
  504. SecurityContext.hPrinter = hPrinterWriteDac;
  505. } else {
  506. SPLASSERT( !hPrinterWriteDac );
  507. SecurityContext.hPrinter = _pPrinterData->hPrinter();
  508. }
  509. SecurityContext.SecurityInformation = DACL_SECURITY_INFORMATION;
  510. SecurityContext.pPrinterSecurity = this;
  511. //
  512. // Pass all the permissions to the ACL editor,
  513. // and set up the type required:
  514. //
  515. ApplicationAccesses.Count = PERMS_COUNT;
  516. ApplicationAccesses.AccessGroup = gpDiscretionaryAccessGroup;
  517. ApplicationAccesses.DefaultPermName =
  518. gpDiscretionaryAccessGroup[PERMS_PRINT].PermissionTitle;
  519. COUNT i;
  520. for( i = 0; i < PERMS_COUNT; ++i ){
  521. ApplicationAccesses.AccessGroup[i].Type =
  522. SED_DESC_TYPE_CONT_AND_NEW_OBJECT;
  523. }
  524. SED_OBJECT_TYPE_DESCRIPTOR Descriptor = gObjectTypeDescriptor;
  525. Descriptor.AllowNewObjectPerms = TRUE;
  526. Descriptor.HelpInfo = &gHelpInfoPermissions;
  527. Status DBGCHK = (*gpfnSedDiscretionaryAclEditor)(
  528. _hDlg,
  529. ghInst,
  530. (LPTSTR)(LPCTSTR)_pPrinterData->strServerName(),
  531. &Descriptor,
  532. &ApplicationAccesses,
  533. (LPTSTR)(LPCTSTR)_pPrinterData->strPrinterName(),
  534. SedCallback2,
  535. (DWORD)&SecurityContext,
  536. pInfo3->pSecurityDescriptor,
  537. FALSE,
  538. (BOOLEAN)!hPrinterWriteDac,
  539. &SedStatus,
  540. 0 );
  541. Fail:
  542. if( Status ){
  543. SetLastError( Status );
  544. vShowUnexpectedError( NULL, IDS_ERR_PRINTER_PROP_TITLE );
  545. }
  546. //
  547. // Close the printer use to write the Dac.
  548. //
  549. if( hPrinterWriteDac ){
  550. ClosePrinter( hPrinterWriteDac );
  551. }
  552. FreeMem( pInfo3 );
  553. }
  554. VOID
  555. TPrinterSecurity::
  556. vCallSystemAclEditor(
  557. VOID
  558. )
  559. /*++
  560. Routine Description:
  561. Edit auditing properties of print queue.
  562. Arguments:
  563. Return Values:
  564. --*/
  565. {
  566. HANDLE hPrinterSystemAccess = NULL;
  567. SED_APPLICATION_ACCESSES ApplicationAccesses;
  568. DWORD SedStatus;
  569. TStatusB bStatus;
  570. TStatus Status;
  571. Status DBGNOCHK = 0;
  572. if( !bLoadAcledit( )){
  573. return;
  574. }
  575. {
  576. TAcquirePrivilege AcquirePrivilege( SE_SECURITY_NAME );
  577. if( !VALID_OBJ( AcquirePrivilege )){
  578. vShowUnexpectedError( NULL, IDS_ERR_PRINTER_PROP_TITLE );
  579. return;
  580. }
  581. DWORD dwAccess = ACCESS_SYSTEM_SECURITY;
  582. Status DBGCHK = TPrinter::sOpenPrinter(
  583. _pPrinterData->strPrinterName(),
  584. &dwAccess,
  585. &hPrinterSystemAccess );
  586. if( Status != ERROR_SUCCESS ){
  587. vShowUnexpectedError( NULL, IDS_ERR_PRINTER_PROP_TITLE );
  588. return;
  589. }
  590. }
  591. //
  592. // Get the security descriptor.
  593. //
  594. PPRINTER_INFO_3 pInfo3 = NULL;
  595. DWORD cbInfo3 = 0;
  596. bStatus DBGCHK = VDataRefresh::bGetPrinter( hPrinterSystemAccess,
  597. 3,
  598. (PVOID*)&pInfo3,
  599. &cbInfo3 );
  600. if( !bStatus ){
  601. Status DBGCHK = GetLastError();
  602. goto Fail;
  603. }
  604. SECURITY_CONTEXT SecurityContext;
  605. SecurityContext.SecurityInformation = SACL_SECURITY_INFORMATION;
  606. SecurityContext.pPrinterSecurity = this;
  607. SPLASSERT( hPrinterSystemAccess );
  608. SecurityContext.hPrinter = hPrinterSystemAccess;
  609. //
  610. // Pass only the Print and Administer permissions to the ACL editor,
  611. // and set up the type required:
  612. //
  613. ApplicationAccesses.Count = PERMS_AUDIT_COUNT;
  614. ApplicationAccesses.AccessGroup = gpSystemAccessGroup;
  615. ApplicationAccesses.DefaultPermName =
  616. gpDiscretionaryAccessGroup[PERMS_PRINT].PermissionTitle;
  617. SED_OBJECT_TYPE_DESCRIPTOR Descriptor = gObjectTypeDescriptor;
  618. Descriptor.AllowNewObjectPerms = FALSE;
  619. Descriptor.HelpInfo = &gHelpInfoAuditing;
  620. Status DBGCHK = (*gpfnSedSystemAclEditor)(
  621. _hDlg,
  622. ghInst,
  623. (LPTSTR)(LPCTSTR)_pPrinterData->strServerName(),
  624. &Descriptor,
  625. &ApplicationAccesses,
  626. (LPTSTR)(LPCTSTR)_pPrinterData->strPrinterName(),
  627. SedCallback2,
  628. (DWORD)&SecurityContext,
  629. pInfo3->pSecurityDescriptor,
  630. FALSE,
  631. &SedStatus,
  632. 0 );
  633. Fail:
  634. if( Status ){
  635. SetLastError( Status );
  636. vShowUnexpectedError( NULL, IDS_ERR_PRINTER_PROP_TITLE );
  637. }
  638. FreeMem( pInfo3 );
  639. if( hPrinterSystemAccess ){
  640. ClosePrinter( hPrinterSystemAccess );
  641. }
  642. }
  643. VOID
  644. TPrinterSecurity::
  645. vCallTakeOwnershipDialog(
  646. VOID
  647. )
  648. /*++
  649. Routine Description:
  650. Edit ownership of print queue.
  651. How does a user get to this dialog if they can't get properties
  652. on a printer?
  653. Arguments:
  654. Return Values:
  655. --*/
  656. {
  657. SED_APPLICATION_ACCESSES ApplicationAccesses;
  658. DWORD SedStatus;
  659. TStatusB bStatus;
  660. TStatus Status;
  661. HANDLE hPrinterWriteOwner = NULL;
  662. Status DBGNOCHK = 0;
  663. if( !bLoadAcledit( )){
  664. return;
  665. }
  666. //
  667. // Get the security descriptor.
  668. //
  669. PPRINTER_INFO_3 pInfo3 = NULL;
  670. DWORD cbInfo3 = 0;
  671. //
  672. // Attempt to retrieve the previous owner.
  673. //
  674. if( _pPrinterData->hPrinter( )){
  675. bStatus DBGCHK = VDataRefresh::bGetPrinter( _pPrinterData->hPrinter(),
  676. 3,
  677. (PVOID*)&pInfo3,
  678. &cbInfo3 );
  679. }
  680. {
  681. TAcquirePrivilege AcquirePrivilege( SE_TAKE_OWNERSHIP_NAME );
  682. SECURITY_CONTEXT SecurityContext;
  683. DWORD dwAccess = WRITE_OWNER;
  684. Status DBGCHK = TPrinter::sOpenPrinter( _pPrinterData->strPrinterName(),
  685. &dwAccess,
  686. &hPrinterWriteOwner );
  687. if( Status == ERROR_SUCCESS){
  688. SPLASSERT( hPrinterWriteOwner );
  689. SecurityContext.hPrinter = hPrinterWriteOwner;
  690. } else {
  691. SPLASSERT( !hPrinterWriteOwner );
  692. SecurityContext.hPrinter = _pPrinterData->hPrinter();
  693. }
  694. SecurityContext.SecurityInformation = OWNER_SECURITY_INFORMATION;
  695. SecurityContext.pPrinterSecurity = this;
  696. ApplicationAccesses.Count = PERMS_COUNT;
  697. ApplicationAccesses.AccessGroup = gpDiscretionaryAccessGroup;
  698. ApplicationAccesses.DefaultPermName =
  699. gpDiscretionaryAccessGroup[PERMS_PRINT].PermissionTitle;
  700. COUNT i;
  701. for( i = 0; i < PERMS_COUNT; ++i ){
  702. ApplicationAccesses.AccessGroup[i].Type = SED_DESC_TYPE_AUDIT;
  703. }
  704. BOOL bCantReadOwner;
  705. PSECURITY_DESCRIPTOR pSecurityDescriptor;
  706. bCantReadOwner = pInfo3 ? FALSE : TRUE;
  707. pSecurityDescriptor = pInfo3 ?
  708. pInfo3->pSecurityDescriptor :
  709. NULL;
  710. TString strPrinter;
  711. bStatus DBGCHK = strPrinter.bLoadString( ghInst, IDS_PRINTER );
  712. Status DBGCHK = (*gpfnSedTakeOwnership)(
  713. _hDlg,
  714. ghInst,
  715. (LPTSTR)(LPCTSTR)_pPrinterData->strServerName(),
  716. (LPTSTR)(LPCTSTR)strPrinter,
  717. (LPTSTR)(LPCTSTR)_pPrinterData->strPrinterName(),
  718. 1,
  719. SedCallback2,
  720. (DWORD)&SecurityContext,
  721. pSecurityDescriptor,
  722. (BOOLEAN)bCantReadOwner,
  723. (BOOLEAN)!hPrinterWriteOwner,
  724. &SedStatus,
  725. &gHelpInfoTakeOwnership,
  726. 0 );
  727. }
  728. if( hPrinterWriteOwner ){
  729. ClosePrinter( hPrinterWriteOwner );
  730. }
  731. FreeMem( pInfo3 );
  732. }
  733. /********************************************************************
  734. Security callback routine.
  735. ********************************************************************/
  736. DWORD
  737. TPrinterSecurity::
  738. SedCallback2(
  739. HWND hwndParent,
  740. HANDLE hInstance,
  741. DWORD dwCallBackContext,
  742. PSECURITY_DESCRIPTOR psdUpdated,
  743. PSECURITY_DESCRIPTOR pSecDescNewObjects,
  744. BOOLEAN bApplyToSubContainers,
  745. BOOLEAN bApplyToSubObjects,
  746. LPDWORD pdwStatusReturn
  747. )
  748. /*++
  749. Routine Description:
  750. Called by acledit to process writes.
  751. Arguments:
  752. <insert>.
  753. Return Values:
  754. <insert>.
  755. --*/
  756. {
  757. UNREFERENCED_PARAMETER( pdwStatusReturn );
  758. UNREFERENCED_PARAMETER( bApplyToSubObjects );
  759. UNREFERENCED_PARAMETER( bApplyToSubContainers );
  760. UNREFERENCED_PARAMETER( pSecDescNewObjects );
  761. UNREFERENCED_PARAMETER( hInstance );
  762. UNREFERENCED_PARAMETER( hwndParent );
  763. PSECURITY_CONTEXT pSecurityContext;
  764. SECURITY_DESCRIPTOR SecurityDescriptorNew;
  765. PSECURITY_DESCRIPTOR pSelfRelativeSD = NULL;
  766. DWORD cbSelfRelativeSD;
  767. TStatusB bStatus;
  768. pSecurityContext = (PSECURITY_CONTEXT)dwCallBackContext;
  769. SPLASSERT( pSecurityContext->hPrinter );
  770. if( InitializeSecurityDescriptor( &SecurityDescriptorNew,
  771. SECURITY_DESCRIPTOR_REVISION1 ) &&
  772. BuildNewSecurityDescriptor( &SecurityDescriptorNew,
  773. pSecurityContext->SecurityInformation,
  774. psdUpdated )){
  775. pSelfRelativeSD = AllocCopySecurityDescriptor( &SecurityDescriptorNew,
  776. &cbSelfRelativeSD );
  777. } else {
  778. DBGMSG( DBG_ERROR, ( "PrinterSecurity.SedCallback2: InitializeSD failedt %d\n",
  779. GetLastError( )));
  780. }
  781. if( !pSelfRelativeSD ){
  782. DBGMSG( DBG_WARN,
  783. ( "PrinterSecurity.SedCallback2: Alloc copy sd failed %d\n",
  784. GetLastError( )));
  785. SPLASSERT( GetLastError( ));
  786. vShowUnexpectedError( NULL, IDS_ERR_PRINTER_PROP_TITLE );
  787. return GetLastError();
  788. }
  789. PRINTER_INFO_3 PrinterInfo3;
  790. PrinterInfo3.pSecurityDescriptor = pSelfRelativeSD;
  791. bStatus DBGCHK = SetPrinter( pSecurityContext->hPrinter,
  792. 3,
  793. (PBYTE)&PrinterInfo3,
  794. 0 );
  795. //
  796. // Free the newly created sd.
  797. //
  798. FreeMem( pSelfRelativeSD );
  799. if( !bStatus ){
  800. SPLASSERT( GetLastError( ));
  801. iMessage( NULL,
  802. IDS_ERR_PRINTER_PROP_TITLE,
  803. IDS_ERR_SAVE_PRINTER,
  804. MB_OK|MB_ICONHAND,
  805. kMsgGetLastError,
  806. NULL );
  807. return GetLastError();
  808. }
  809. //
  810. // Refresh the property page set.
  811. //
  812. pSecurityContext->pPrinterSecurity->vReloadPages();
  813. return ERROR_SUCCESS;
  814. }
  815. /********************************************************************
  816. Helpers.
  817. ********************************************************************/
  818. BOOL
  819. TPrinterSecurity::
  820. BuildNewSecurityDescriptor(
  821. PSECURITY_DESCRIPTOR psdNew,
  822. SECURITY_INFORMATION SecurityInformation,
  823. PSECURITY_DESCRIPTOR psdUpdated
  824. )
  825. /*++
  826. Routine Description:
  827. Builds new security desriptor.
  828. Arguments:
  829. Return Values:
  830. --*/
  831. {
  832. BOOL bDefaulted = FALSE;
  833. PSID pOwnerSid = NULL;
  834. PSID pGroupSid = NULL;
  835. BOOL bDaclPresent = FALSE;
  836. PACL pDacl = NULL;
  837. BOOL bSaclPresent = FALSE;
  838. PACL pSacl = NULL;
  839. TStatusB bStatus;
  840. switch( SecurityInformation ){
  841. case OWNER_SECURITY_INFORMATION:
  842. if( GetSecurityDescriptorOwner( psdUpdated,
  843. &pOwnerSid,
  844. &bDefaulted )){
  845. bStatus DBGCHK = SetSecurityDescriptorOwner( psdNew,
  846. pOwnerSid,
  847. bDefaulted );
  848. }
  849. break;
  850. case DACL_SECURITY_INFORMATION:
  851. if( GetSecurityDescriptorDacl( psdUpdated,
  852. &bDaclPresent,
  853. &pDacl,
  854. &bDefaulted )) {
  855. bStatus DBGCHK = SetSecurityDescriptorDacl( psdNew,
  856. bDaclPresent,
  857. pDacl,
  858. bDefaulted );
  859. }
  860. break;
  861. case SACL_SECURITY_INFORMATION:
  862. if( GetSecurityDescriptorSacl( psdUpdated,
  863. &bSaclPresent,
  864. &pSacl,
  865. &bDefaulted )) {
  866. bStatus DBGCHK = SetSecurityDescriptorSacl( psdNew,
  867. bSaclPresent,
  868. pSacl,
  869. bDefaulted );
  870. }
  871. break;
  872. default:
  873. DBGMSG( DBG_ERROR, ( "PrinterSecurity.BuildSD: Unknown type %d\n",
  874. SecurityInformation ));
  875. return FALSE;
  876. }
  877. return bStatus;
  878. }
  879. PSECURITY_DESCRIPTOR
  880. TPrinterSecurity::
  881. AllocCopySecurityDescriptor(
  882. IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
  883. OUT PDWORD pdwLength
  884. )
  885. /*++
  886. Routine Description:
  887. Alloc copy of security descriptor.
  888. Arguments:
  889. pSecurityDescriptor - sd to copy.
  890. pdwLength - Output length.
  891. Return Value:
  892. Newly allocated sd. NULL if failed.
  893. --*/
  894. {
  895. PSECURITY_DESCRIPTOR psdCopy;
  896. DWORD dwLength;
  897. dwLength = GetSecurityDescriptorLength(pSecurityDescriptor);
  898. psdCopy = AllocMem( dwLength );
  899. if( psdCopy ){
  900. MakeSelfRelativeSD( pSecurityDescriptor,
  901. psdCopy,
  902. &dwLength);
  903. *pdwLength = dwLength;
  904. }
  905. return psdCopy;
  906. }
  907. #endif // def SECURITY