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.

930 lines
30 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. faxsecinfo.h
  5. Abstract:
  6. This header is the ISecurityInformation implmentation used to instantiate a
  7. security page.
  8. Environment:
  9. WIN32 User Mode
  10. Author:
  11. Darwin Ouyang (t-darouy) 30-Sept-1997
  12. --*/
  13. // FaxSnapin.cpp : Implementation of CFaxSnapinAbout
  14. #include "stdafx.h"
  15. #include "faxadmin.h"
  16. #include "faxsecinfo.h"
  17. #include "faxstrt.h" // string table
  18. #include "faxcompd.h" // IComponentData
  19. #include "inode.h" // CInternalNode
  20. #include "iroot.h" // CInternalRoot
  21. #include <faxreg.h> // contains FAXSTAT_WINCLASS definition
  22. #pragma hdrstop
  23. GENERIC_MAPPING FaxGenericMapping[] =
  24. {
  25. {
  26. STANDARD_RIGHTS_READ,
  27. STANDARD_RIGHTS_WRITE,
  28. STANDARD_RIGHTS_EXECUTE,
  29. STANDARD_RIGHTS_REQUIRED
  30. }
  31. };
  32. SI_ACCESS siFaxAccesses[] =
  33. {
  34. // submit permission
  35. {
  36. &GUID_NULL,
  37. FAX_JOB_SUBMIT | STANDARD_RIGHTS_WRITE,
  38. MAKEINTRESOURCE(IDS_FAXSEC_JOB_SUB),
  39. SI_ACCESS_GENERAL
  40. },
  41. // query permission
  42. {
  43. &GUID_NULL,
  44. FAX_JOB_QUERY | STANDARD_RIGHTS_READ,
  45. MAKEINTRESOURCE(IDS_FAXSEC_JOB_QRY),
  46. SI_ACCESS_GENERAL
  47. },
  48. {
  49. &GUID_NULL,
  50. FAX_CONFIG_QUERY | STANDARD_RIGHTS_READ,
  51. MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_QRY),
  52. SI_ACCESS_GENERAL
  53. },
  54. {
  55. &GUID_NULL,
  56. FAX_PORT_QUERY | STANDARD_RIGHTS_READ,
  57. MAKEINTRESOURCE(IDS_FAXSEC_PORT_QRY),
  58. SI_ACCESS_GENERAL
  59. },
  60. // manage permission
  61. {
  62. &GUID_NULL,
  63. FAX_JOB_MANAGE | STANDARD_RIGHTS_ALL,
  64. MAKEINTRESOURCE(IDS_FAXSEC_JOB_MNG),
  65. SI_ACCESS_GENERAL
  66. },
  67. {
  68. &GUID_NULL,
  69. FAX_CONFIG_SET | STANDARD_RIGHTS_ALL,
  70. MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_SET),
  71. SI_ACCESS_GENERAL
  72. },
  73. {
  74. &GUID_NULL,
  75. FAX_PORT_SET | STANDARD_RIGHTS_ALL,
  76. MAKEINTRESOURCE(IDS_FAXSEC_PORT_SET),
  77. SI_ACCESS_GENERAL
  78. },
  79. // custom access (We don't expose this access, but it is the default access when adding new permissions)
  80. {
  81. &GUID_NULL,
  82. FAX_READ | FAX_WRITE,
  83. TEXT("foobar"),
  84. SI_ACCESS_GENERAL
  85. }
  86. };
  87. #define iFaxDefSecurity 7
  88. CFaxSecurityInformation::CFaxSecurityInformation()
  89. : m_pDescriptor( NULL ),
  90. m_pCompData( NULL ),
  91. m_pOwner( NULL ),
  92. m_dwDescID( 0 ),
  93. m_pAbsoluteDescriptor( NULL ),
  94. m_pDacl( NULL ),
  95. m_pSacl( NULL ),
  96. m_pDescOwner( NULL ),
  97. m_pPrimaryGroup( NULL )
  98. {
  99. DebugPrint(( TEXT("CFaxSecurityInfo Created") ));
  100. }
  101. CFaxSecurityInformation::~CFaxSecurityInformation()
  102. {
  103. DebugPrint(( TEXT("CFaxSecurityInfo Destroyed") ));
  104. if( m_pDescriptor != NULL ) {
  105. ::LocalFree( m_pDescriptor );
  106. m_pDescriptor = NULL;
  107. }
  108. }
  109. /////////////////////////////////////////////////////////////////////////////
  110. // CFaxSecurityInformation
  111. // *** ISecurityInformation methods ***
  112. HRESULT
  113. STDMETHODCALLTYPE
  114. CFaxSecurityInformation::GetObjectInformation(
  115. IN OUT PSI_OBJECT_INFO pObjectInfo
  116. )
  117. {
  118. DebugPrint(( TEXT("Trace: CFaxSecurityInformation::GetObjectInformation") ));
  119. assert( pObjectInfo != NULL );
  120. if( pObjectInfo == NULL ) {
  121. return E_POINTER;
  122. }
  123. pObjectInfo->dwFlags = SI_NO_TREE_APPLY | SI_EDIT_ALL | SI_NO_ACL_PROTECT;
  124. pObjectInfo->hInstance = ::GlobalStringTable->GetInstance();
  125. pObjectInfo->pszServerName = m_pCompData->globalRoot->GetMachine();
  126. pObjectInfo->pszObjectName = ::GlobalStringTable->GetString( IDS_SECURITY_CAT_NODE_DESC );
  127. return S_OK;
  128. }
  129. HRESULT
  130. STDMETHODCALLTYPE
  131. CFaxSecurityInformation::GetSecurity(
  132. IN SECURITY_INFORMATION RequestedInformation,
  133. OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  134. IN BOOL fDefault
  135. )
  136. {
  137. DebugPrint(( TEXT("Trace: CFaxSecurityInformation::GetSecurity") ));
  138. SetSecurityDescriptor( m_dwDescID );
  139. if( fDefault == TRUE ) {
  140. return E_NOTIMPL;
  141. } else {
  142. if( RequestedInformation & DACL_SECURITY_INFORMATION ||
  143. RequestedInformation & OWNER_SECURITY_INFORMATION ||
  144. RequestedInformation & GROUP_SECURITY_INFORMATION ||
  145. RequestedInformation & SACL_SECURITY_INFORMATION
  146. )
  147. {
  148. if( IsValidSecurityDescriptor( m_pDescriptor ) ) {
  149. if( FAILED( MakeSelfRelativeCopy( m_pDescriptor, ppSecurityDescriptor ) ) ) {
  150. assert( FALSE );
  151. return E_UNEXPECTED;
  152. }
  153. // paranoia check
  154. if( !IsValidSecurityDescriptor( *ppSecurityDescriptor ) ) {
  155. assert( FALSE );
  156. return E_UNEXPECTED;
  157. }
  158. return S_OK;
  159. } else {
  160. assert( FALSE );
  161. return E_UNEXPECTED;
  162. }
  163. } else {
  164. return E_NOTIMPL;
  165. }
  166. }
  167. }
  168. HRESULT
  169. STDMETHODCALLTYPE
  170. CFaxSecurityInformation::SetSecurity(
  171. IN SECURITY_INFORMATION SecurityInformation,
  172. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  173. )
  174. {
  175. DebugPrint(( TEXT("Trace: CFaxSecurityInformation::SetSecurity") ));
  176. FAX_SECURITY_DESCRIPTOR temp;
  177. BOOL bResult;
  178. BOOL bPresent;
  179. BOOL bDefaulted;
  180. PACL pDacl = NULL;
  181. PACL pOldDacl = NULL;
  182. DWORD dwDaclSize = 0;
  183. PACL pSacl = NULL;
  184. DWORD dwSaclSize = 0;
  185. PSID pSidOwner = NULL;
  186. DWORD dwOwnerSize = 0;
  187. PSID pPrimaryGroup = NULL;
  188. DWORD dwPrimaryGroupSize = 0;
  189. SetSecurityDescriptor( m_dwDescID );
  190. // paranoia check
  191. if( !IsValidSecurityDescriptor( pSecurityDescriptor ) ) {
  192. assert( FALSE );
  193. return E_UNEXPECTED;
  194. }
  195. if( !IsValidSecurityDescriptor( m_pAbsoluteDescriptor ) ) {
  196. assert( FALSE );
  197. return E_UNEXPECTED;
  198. }
  199. if( !IsValidSecurityDescriptor( m_pDescriptor ) ) {
  200. assert( FALSE );
  201. return E_UNEXPECTED;
  202. }
  203. if( SecurityInformation & DACL_SECURITY_INFORMATION ) {
  204. // if the descriptor we got has a DACL
  205. if( !GetSecurityDescriptorDacl(
  206. pSecurityDescriptor, // address of security descriptor
  207. &bPresent, // address of flag for presence of disc. ACL
  208. &pDacl, // address of pointer to ACL
  209. &bDefaulted // address of flag for default disc. ACL
  210. )
  211. ) {
  212. assert( FALSE );
  213. return E_UNEXPECTED;
  214. } else {
  215. if( bPresent ) {
  216. // delete the old DACL
  217. if( m_pDacl != NULL ) {
  218. ::LocalFree( (PVOID) m_pDacl );
  219. m_pDacl = NULL;
  220. }
  221. m_pDacl = pDacl;
  222. // set the new DACL
  223. if( !SetSecurityDescriptorDacl(
  224. m_pAbsoluteDescriptor,
  225. bPresent,
  226. pDacl,
  227. FALSE
  228. )
  229. ) {
  230. assert( FALSE );
  231. return E_UNEXPECTED;
  232. }
  233. }
  234. }
  235. }
  236. if( SecurityInformation & SACL_SECURITY_INFORMATION ) {
  237. // if the descriptor we got has a SACL
  238. if( !GetSecurityDescriptorSacl(
  239. pSecurityDescriptor, // address of security descriptor
  240. &bPresent, // address of flag for presence of disc. ACL
  241. &pDacl, // address of pointer to ACL
  242. &bDefaulted // address of flag for default disc. ACL
  243. )
  244. ) {
  245. assert( FALSE );
  246. return E_UNEXPECTED;
  247. } else {
  248. if( bPresent ) {
  249. // delete the old SACL
  250. if( m_pSacl != NULL ) {
  251. ::LocalFree( (PVOID) m_pSacl );
  252. m_pSacl = NULL;
  253. }
  254. m_pSacl = pSacl;
  255. // set the new SACL
  256. if( !SetSecurityDescriptorSacl(
  257. m_pAbsoluteDescriptor,
  258. bPresent,
  259. pSacl,
  260. FALSE
  261. )
  262. ) {
  263. assert( FALSE );
  264. return E_UNEXPECTED;
  265. }
  266. }
  267. }
  268. }
  269. if( SecurityInformation & OWNER_SECURITY_INFORMATION ) {
  270. // if the descriptor we got has a OWNER
  271. if( !GetSecurityDescriptorOwner(
  272. pSecurityDescriptor, // address of security descriptor
  273. &pSidOwner, // address of pointer to ACL
  274. &bDefaulted // address of flag for default disc. ACL
  275. )
  276. ) {
  277. assert( FALSE );
  278. return E_UNEXPECTED;
  279. } else {
  280. if( pSidOwner != NULL ) {
  281. // delete the old OWNER
  282. if( m_pDescOwner != NULL ) {
  283. ::LocalFree( (PVOID) m_pDescOwner );
  284. m_pDescOwner = NULL;
  285. }
  286. m_pDescOwner = pSidOwner;
  287. // set the new owner
  288. if( !SetSecurityDescriptorOwner(
  289. m_pAbsoluteDescriptor,
  290. pSidOwner,
  291. FALSE
  292. )
  293. ) {
  294. assert( FALSE );
  295. return E_UNEXPECTED;
  296. }
  297. }
  298. }
  299. }
  300. if( SecurityInformation & GROUP_SECURITY_INFORMATION ) {
  301. // if the descriptor we got has a GROUP
  302. if( !GetSecurityDescriptorGroup(
  303. pSecurityDescriptor, // address of security descriptor
  304. &pPrimaryGroup, // address of pointer to ACL
  305. &bDefaulted // address of flag for default disc. ACL
  306. )
  307. ) {
  308. assert( FALSE );
  309. return E_UNEXPECTED;
  310. } else {
  311. if( pPrimaryGroup != NULL ) {
  312. // delete the old group
  313. if( m_pPrimaryGroup != NULL ) {
  314. ::LocalFree( (PVOID) m_pPrimaryGroup );
  315. m_pPrimaryGroup = NULL;
  316. }
  317. m_pPrimaryGroup = pPrimaryGroup;
  318. // set the new group
  319. if( !SetSecurityDescriptorGroup(
  320. m_pAbsoluteDescriptor,
  321. pPrimaryGroup,
  322. FALSE
  323. )
  324. ) {
  325. assert( FALSE );
  326. return E_UNEXPECTED;
  327. }
  328. }
  329. }
  330. }
  331. // release the old relative desciptor
  332. if( m_pDescriptor != NULL ) {
  333. ::LocalFree( (PVOID)m_pDescriptor );
  334. m_pDescriptor = NULL;
  335. }
  336. // paranoia check
  337. if( !IsValidSecurityDescriptor( m_pAbsoluteDescriptor ) ) {
  338. assert( FALSE );
  339. return E_UNEXPECTED;
  340. }
  341. // copy the new absolute descriptor to a relative version
  342. if( FAILED( MakeSelfRelativeCopy( m_pAbsoluteDescriptor, &m_pDescriptor ) ) ) {
  343. assert( FALSE );
  344. return E_UNEXPECTED;
  345. }
  346. // paranoia check
  347. if( !IsValidSecurityDescriptor( m_pDescriptor ) ) {
  348. assert( FALSE );
  349. return E_UNEXPECTED;
  350. }
  351. if( !IsValidSecurityDescriptor( m_pAbsoluteDescriptor ) ) {
  352. assert( FALSE );
  353. return E_UNEXPECTED;
  354. }
  355. // save the new relative descriptor to the fax server
  356. temp.Id = m_dwDescID;
  357. temp.FriendlyName = NULL;
  358. temp.SecurityDescriptor = (unsigned char *)m_pDescriptor;
  359. try {
  360. bResult = FaxSetSecurityDescriptor( m_pCompData->m_FaxHandle, &temp );
  361. if( bResult == FALSE ) {
  362. ::GlobalStringTable->SystemErrorMsg( GetLastError() );
  363. assert( FALSE );
  364. }
  365. } catch( ... ) {
  366. bResult = FALSE;
  367. m_pCompData->NotifyRpcError( TRUE );
  368. assert( FALSE );
  369. ::GlobalStringTable->SystemErrorMsg( GetLastError() );
  370. }
  371. // paranoia check
  372. if( !IsValidSecurityDescriptor( m_pDescriptor ) ) {
  373. assert( FALSE );
  374. return E_UNEXPECTED;
  375. }
  376. if( !IsValidSecurityDescriptor( m_pAbsoluteDescriptor ) ) {
  377. assert( FALSE );
  378. return E_UNEXPECTED;
  379. }
  380. // See if faxstat is running
  381. HWND hWndFaxStat = FindWindow(FAXSTAT_WINCLASS, NULL);
  382. if (hWndFaxStat) {
  383. PostMessage(hWndFaxStat, WM_FAXSTAT_MMC, 0, 0);
  384. }
  385. return S_OK;
  386. }
  387. HRESULT
  388. STDMETHODCALLTYPE
  389. CFaxSecurityInformation::GetAccessRights(
  390. IN const GUID* pguidObjectType,
  391. IN DWORD dwFlags, // SI_EDIT_AUDITS, SI_EDIT_PROPERTIES
  392. OUT PSI_ACCESS *ppAccess,
  393. OUT ULONG *pcAccesses,
  394. OUT ULONG *piDefaultAccess
  395. )
  396. {
  397. DebugPrint(( TEXT("Trace: CFaxSecurityInformation::GetAccessRights") ));
  398. *ppAccess = siFaxAccesses;
  399. *pcAccesses = 7;
  400. *piDefaultAccess = iFaxDefSecurity;
  401. return S_OK;
  402. }
  403. HRESULT
  404. STDMETHODCALLTYPE
  405. CFaxSecurityInformation::MapGeneric(
  406. IN const GUID *pguidObjectType,
  407. IN UCHAR *pAceFlags,
  408. IN OUT ACCESS_MASK *pMask
  409. )
  410. {
  411. DebugPrint(( TEXT("Trace: CFaxSecurityInformation::MapGeneric") ));
  412. MapGenericMask( pMask, FaxGenericMapping );
  413. return S_OK;
  414. }
  415. // no need to impl these
  416. HRESULT
  417. STDMETHODCALLTYPE
  418. CFaxSecurityInformation::GetInheritTypes(
  419. OUT PSI_INHERIT_TYPE *ppInheritTypes,
  420. OUT ULONG *pcInheritTypes
  421. )
  422. {
  423. DebugPrint(( TEXT("Trace: CFaxSecurityInformation::GetInheritTypes") ));
  424. return E_NOTIMPL;
  425. }
  426. HRESULT
  427. STDMETHODCALLTYPE
  428. CFaxSecurityInformation::PropertySheetPageCallback(
  429. IN HWND hwnd,
  430. IN UINT uMsg,
  431. IN SI_PAGE_TYPE uPage
  432. )
  433. {
  434. DebugPrint(( TEXT("Trace: CFaxSecurityInformation::PropertySheetPageCallback") ));
  435. if( uMsg == PSPCB_RELEASE ) {
  436. DestroyAbsoluteDescriptor();
  437. }
  438. return S_OK;
  439. }
  440. // Internal Methods
  441. HRESULT
  442. CFaxSecurityInformation::SetOwner(
  443. CInternalNode * toSet )
  444. {
  445. DebugPrint(( TEXT(" * Trace: CFaxSecurityInformation::SetOwner") ));
  446. assert( toSet != NULL );
  447. m_pOwner = toSet;
  448. m_pCompData = m_pOwner->m_pCompData;
  449. return S_OK;
  450. }
  451. HRESULT
  452. CFaxSecurityInformation::SetSecurityDescriptor(
  453. DWORD FaxDescriptorId
  454. )
  455. {
  456. DebugPrint(( TEXT(" * Trace: CFaxSecurityInformation::SetSecurityDescriptor") ));
  457. DWORD descLen = 0;
  458. HRESULT hr = S_OK;
  459. PFAX_SECURITY_DESCRIPTOR FaxDescriptor = NULL;
  460. BOOL bResult;
  461. try {
  462. bResult = FaxGetSecurityDescriptor( m_pOwner->m_pCompData->m_FaxHandle, FaxDescriptorId, &FaxDescriptor );
  463. } catch( ... ) {
  464. bResult = FALSE;
  465. assert( FALSE );
  466. }
  467. if( bResult ) {
  468. if( !IsValidSecurityDescriptor( FaxDescriptor->SecurityDescriptor ) ) {
  469. assert( FALSE );
  470. return E_UNEXPECTED;
  471. }
  472. m_dwDescID = FaxDescriptor->Id;
  473. hr = MakeSelfRelativeCopy( FaxDescriptor->SecurityDescriptor, &m_pDescriptor );
  474. if( FAILED( hr ) ) {
  475. assert( FALSE );
  476. return hr;
  477. }
  478. FaxFreeBuffer( FaxDescriptor );
  479. hr = MakeAbsoluteCopyFromRelative( m_pDescriptor, &m_pAbsoluteDescriptor );
  480. if( FAILED( hr ) ) {
  481. assert( FALSE );
  482. return hr;
  483. }
  484. // paranoia check
  485. if( !IsValidSecurityDescriptor( m_pDescriptor ) ) {
  486. assert( FALSE );
  487. return E_UNEXPECTED;
  488. }
  489. // paranoia check
  490. if( !IsValidSecurityDescriptor( m_pAbsoluteDescriptor ) ) {
  491. assert( FALSE );
  492. return E_UNEXPECTED;
  493. }
  494. } else {
  495. if (GetLastError() != ERROR_ACCESS_DENIED) {
  496. assert( FALSE );
  497. m_pOwner->m_pCompData->NotifyRpcError( TRUE );
  498. }
  499. ::GlobalStringTable->SystemErrorMsg( GetLastError() );
  500. hr = E_UNEXPECTED;
  501. }
  502. return hr;
  503. }
  504. // stolen from \private\admin\snapin\filemgmt\permpage.cpp and modified
  505. HRESULT CFaxSecurityInformation::MakeSelfRelativeCopy(
  506. PSECURITY_DESCRIPTOR psdOriginal,
  507. PSECURITY_DESCRIPTOR* ppsdNew
  508. )
  509. {
  510. DebugPrint(( TEXT(" * Trace: CFaxSecurityInformation::MakeSelfRelativeCopy") ));
  511. assert( NULL != psdOriginal );
  512. // we have to find out whether the original is already self-relative
  513. SECURITY_DESCRIPTOR_CONTROL sdc = 0;
  514. PSECURITY_DESCRIPTOR psdSelfRelativeCopy = NULL;
  515. DWORD dwRevision = 0;
  516. DWORD cb = 0;
  517. if( !IsValidSecurityDescriptor( psdOriginal ) ) {
  518. assert( FALSE );
  519. return E_INVALIDARG;
  520. }
  521. if( !::GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) ) {
  522. assert( FALSE );
  523. DWORD err = ::GetLastError();
  524. return HRESULT_FROM_WIN32( err );
  525. }
  526. if( sdc & SE_SELF_RELATIVE ) {
  527. // the original is in self-relative format, just byte-copy it
  528. // get size
  529. cb = ::GetSecurityDescriptorLength( psdOriginal );
  530. // alloc the memory
  531. psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb );
  532. if(NULL == psdSelfRelativeCopy) {
  533. assert( FALSE );
  534. return E_OUTOFMEMORY;
  535. }
  536. // make the copy
  537. ::memcpy( psdSelfRelativeCopy, psdOriginal, cb );
  538. } else {
  539. // the original is in absolute format, convert-copy it
  540. // get new size - it will fail and set cb to the correct buffer size
  541. ::MakeSelfRelativeSD( psdOriginal, NULL, &cb );
  542. // alloc the new amount of memory
  543. psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb );
  544. if(NULL == psdSelfRelativeCopy) {
  545. assert( FALSE );
  546. return E_OUTOFMEMORY; // just in case the exception is ignored
  547. }
  548. if( !::MakeSelfRelativeSD( psdOriginal, psdSelfRelativeCopy, &cb ) ) {
  549. assert( FALSE );
  550. if( NULL == ::LocalFree( psdSelfRelativeCopy ) ) {
  551. DWORD err = ::GetLastError();
  552. return HRESULT_FROM_WIN32( err );
  553. }
  554. psdSelfRelativeCopy = NULL;
  555. }
  556. }
  557. *ppsdNew = psdSelfRelativeCopy;
  558. return S_OK;
  559. }
  560. HRESULT CFaxSecurityInformation::MakeAbsoluteCopyFromRelative(
  561. PSECURITY_DESCRIPTOR psdOriginal,
  562. PSECURITY_DESCRIPTOR* ppsdNew
  563. )
  564. {
  565. assert( NULL != psdOriginal );
  566. DebugPrint(( TEXT(" * Trace: CFaxSecurityInformation::MakeAbsoluteCopyFromRelative") ));
  567. // we have to find out whether the original is already self-relative
  568. SECURITY_DESCRIPTOR_CONTROL sdc = 0;
  569. PSECURITY_DESCRIPTOR psdAbsoluteCopy = NULL;
  570. DWORD dwRevision = 0;
  571. DWORD cb = 0;
  572. BOOL bDefaulted;
  573. DWORD dwDaclSize = 0;
  574. BOOL bDaclPresent = FALSE;
  575. DWORD dwSaclSize = 0;
  576. BOOL bSaclPresent = FALSE;
  577. DWORD dwOwnerSize = 0;
  578. DWORD dwPrimaryGroupSize = 0;
  579. HRESULT hr = S_OK;
  580. if( !IsValidSecurityDescriptor( psdOriginal ) ) {
  581. assert( FALSE );
  582. return E_INVALIDARG;
  583. }
  584. if( !::GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) ) {
  585. assert( FALSE );
  586. DWORD err = ::GetLastError();
  587. hr = HRESULT_FROM_WIN32( err );
  588. goto cleanup;
  589. }
  590. if( sdc & SE_SELF_RELATIVE ) {
  591. // the original is in self-relative format, build an absolute copy
  592. // get the dacl
  593. if( !GetSecurityDescriptorDacl(
  594. psdOriginal, // address of security descriptor
  595. &bDaclPresent, // address of flag for presence of disc. ACL
  596. &m_pDacl, // address of pointer to ACL
  597. &bDefaulted // address of flag for default disc. ACL
  598. )
  599. ) {
  600. assert( FALSE );
  601. hr = E_INVALIDARG;
  602. goto cleanup;
  603. }
  604. // get the sacl
  605. if( !GetSecurityDescriptorSacl(
  606. psdOriginal, // address of security descriptor
  607. &bSaclPresent, // address of flag for presence of disc. ACL
  608. &m_pSacl, // address of pointer to ACL
  609. &bDefaulted // address of flag for default disc. ACL
  610. )
  611. ) {
  612. assert( FALSE );
  613. hr = E_INVALIDARG;
  614. goto cleanup;
  615. }
  616. // get the owner
  617. if( !GetSecurityDescriptorOwner(
  618. psdOriginal, // address of security descriptor
  619. &m_pDescOwner, // address of pointer to owner security
  620. // identifier (SID)
  621. &bDefaulted // address of flag for default
  622. )
  623. ) {
  624. assert( FALSE );
  625. hr = E_INVALIDARG;
  626. goto cleanup;
  627. }
  628. // get the group
  629. if( !GetSecurityDescriptorGroup(
  630. psdOriginal, // address of security descriptor
  631. &m_pPrimaryGroup, // address of pointer to owner security
  632. // identifier (SID)
  633. &bDefaulted // address of flag for default
  634. )
  635. ) {
  636. assert( FALSE );
  637. hr = E_INVALIDARG;
  638. goto cleanup;
  639. }
  640. // get required buffer size
  641. cb = 0;
  642. MakeAbsoluteSD(
  643. psdOriginal, // address of self-relative SD
  644. psdAbsoluteCopy, // address of absolute SD
  645. &cb, // address of size of absolute SD
  646. NULL, // address of discretionary ACL
  647. &dwDaclSize, // address of size of discretionary ACL
  648. NULL, // address of system ACL
  649. &dwSaclSize, // address of size of system ACL
  650. NULL, // address of owner SID
  651. &dwOwnerSize, // address of size of owner SID
  652. NULL, // address of primary-group SID
  653. &dwPrimaryGroupSize // address of size of group SID
  654. );
  655. // alloc the memory
  656. psdAbsoluteCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb );
  657. m_pDacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwDaclSize );
  658. m_pSacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwSaclSize );
  659. m_pDescOwner = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwOwnerSize );
  660. m_pPrimaryGroup = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwPrimaryGroupSize );
  661. if(NULL == psdAbsoluteCopy ||
  662. NULL == m_pDacl ||
  663. NULL == m_pSacl ||
  664. NULL == m_pDescOwner ||
  665. NULL == m_pPrimaryGroup
  666. ) {
  667. assert( FALSE );
  668. hr = E_OUTOFMEMORY;
  669. goto cleanup;
  670. }
  671. // make the copy
  672. if( !MakeAbsoluteSD(
  673. psdOriginal, // address of self-relative SD
  674. psdAbsoluteCopy, // address of absolute SD
  675. &cb, // address of size of absolute SD
  676. m_pDacl, // address of discretionary ACL
  677. &dwDaclSize, // address of size of discretionary ACL
  678. m_pSacl, // address of system ACL
  679. &dwSaclSize, // address of size of system ACL
  680. m_pDescOwner, // address of owner SID
  681. &dwOwnerSize, // address of size of owner SID
  682. m_pPrimaryGroup, // address of primary-group SID
  683. &dwPrimaryGroupSize // address of size of group SID
  684. )
  685. ) {
  686. assert( FALSE );
  687. hr = E_UNEXPECTED;
  688. goto cleanup;
  689. }
  690. } else {
  691. // the original is in absolute format, fail
  692. *ppsdNew = NULL;
  693. hr = E_INVALIDARG;
  694. goto cleanup;
  695. }
  696. *ppsdNew = psdAbsoluteCopy;
  697. // paranoia check
  698. if( !IsValidSecurityDescriptor( *ppsdNew ) ) {
  699. assert( FALSE );
  700. hr = E_UNEXPECTED;
  701. goto cleanup;
  702. }
  703. if( !IsValidSecurityDescriptor( psdOriginal ) ) {
  704. assert( FALSE );
  705. hr = E_UNEXPECTED;
  706. goto cleanup;
  707. }
  708. return hr;
  709. cleanup:
  710. if( m_pDacl != NULL && bDaclPresent == TRUE ) {
  711. ::LocalFree((PVOID) m_pDacl );
  712. m_pDacl = NULL;
  713. }
  714. if( m_pSacl != NULL && bSaclPresent == TRUE ) {
  715. ::LocalFree((PVOID) m_pSacl );
  716. m_pSacl = NULL;
  717. }
  718. if( m_pDescOwner != NULL ) {
  719. ::LocalFree((PVOID) m_pOwner );
  720. m_pDescOwner = NULL;
  721. }
  722. if( m_pPrimaryGroup != NULL ) {
  723. ::LocalFree((PVOID) m_pPrimaryGroup );
  724. m_pPrimaryGroup = NULL;
  725. }
  726. if( psdAbsoluteCopy != NULL ) {
  727. ::LocalFree((PVOID) psdAbsoluteCopy );
  728. psdAbsoluteCopy = NULL;
  729. }
  730. return hr;
  731. }
  732. // cleanup function only called by destructor.
  733. HRESULT CFaxSecurityInformation::DestroyAbsoluteDescriptor()
  734. {
  735. DebugPrint(( TEXT(" * Trace: CFaxSecurityInformation::DestroyAbsoluteDescriptor") ));
  736. SECURITY_DESCRIPTOR_CONTROL sdc = 0;
  737. DWORD dwRevision = 0;
  738. DWORD cb = 0;
  739. HRESULT hr = S_OK;
  740. if( m_pAbsoluteDescriptor == NULL ) {
  741. assert( FALSE );
  742. return E_POINTER;
  743. }
  744. if( !IsValidSecurityDescriptor( m_pAbsoluteDescriptor ) ) {
  745. // BUGBUG this assertion always fails for some reason unknown if
  746. // you hit apply then ok on the property sheet. something is wrong.
  747. //
  748. // for some reason, this bug does not manifest on Alpha?!
  749. //
  750. assert( FALSE );
  751. return E_INVALIDARG;
  752. }
  753. if( !::GetSecurityDescriptorControl( m_pAbsoluteDescriptor, &sdc, &dwRevision ) ) {
  754. assert( FALSE );
  755. DWORD err = ::GetLastError();
  756. hr = HRESULT_FROM_WIN32( err );
  757. goto cleanup;
  758. }
  759. if( !(sdc & SE_SELF_RELATIVE) ) {
  760. if( m_pDacl != NULL ) {
  761. ::LocalFree((PVOID) m_pDacl );
  762. m_pDacl = NULL;
  763. }
  764. if( m_pSacl != NULL ) {
  765. ::LocalFree((PVOID) m_pSacl );
  766. m_pSacl = NULL;
  767. }
  768. if( m_pDescOwner != NULL ) {
  769. ::LocalFree((PVOID) m_pDescOwner );
  770. m_pDescOwner = NULL;
  771. }
  772. if( m_pPrimaryGroup != NULL ) {
  773. ::LocalFree((PVOID) m_pPrimaryGroup );
  774. m_pPrimaryGroup = NULL;
  775. }
  776. if( m_pAbsoluteDescriptor != NULL ) {
  777. ::LocalFree((PVOID) m_pAbsoluteDescriptor );
  778. m_pAbsoluteDescriptor = NULL;
  779. }
  780. } else {
  781. // not in absolute!!
  782. assert( FALSE );
  783. return E_INVALIDARG;
  784. }
  785. return hr;
  786. cleanup:
  787. assert( FALSE );
  788. return hr;
  789. }