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.

1158 lines
25 KiB

  1. // Copyright (c) 2000-2002 Microsoft Corporation, All Rights Reserved
  2. //
  3. // Created: 4/21/2000, Kevin Hughes
  4. #include "precomp.h"
  5. #include <vector>
  6. #include <assertbreak.h>
  7. #include "AccessEntry.h" // CAccessEntry class
  8. #include "AccessEntryList.h"
  9. #include "DACL.h" // CDACL class
  10. #include "SACL.h"
  11. #include "securitydescriptor.h"
  12. #include "CToken.h"
  13. #include <autoptr.h>
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // CToken base class
  16. ///////////////////////////////////////////////////////////////////////////////
  17. CToken::CToken()
  18. : m_hToken(NULL),
  19. m_fIsValid(false),
  20. m_fClose(true),
  21. m_dwLastError(ERROR_SUCCESS),
  22. m_psdDefault(NULL)
  23. {
  24. ::SetLastError(ERROR_SUCCESS);
  25. }
  26. // Copy constructor
  27. CToken::CToken(
  28. const CToken &rTok)
  29. : m_hToken(NULL),
  30. m_fIsValid(false),
  31. m_fClose(true),
  32. m_dwLastError(ERROR_SUCCESS),
  33. m_psdDefault(NULL)
  34. {
  35. Duplicate(rTok);
  36. }
  37. CToken::~CToken(void)
  38. {
  39. CleanToken () ;
  40. }
  41. void CToken::CleanToken ()
  42. {
  43. // Close token handle
  44. if ( m_fClose )
  45. {
  46. if ( m_hToken && INVALID_HANDLE_VALUE != m_hToken )
  47. {
  48. ::CloseHandle( m_hToken );
  49. }
  50. }
  51. if(m_psdDefault)
  52. {
  53. delete m_psdDefault;
  54. m_psdDefault = NULL;
  55. }
  56. // Initialize data
  57. m_hToken = NULL;
  58. m_fIsValid = false;
  59. m_fClose = true;
  60. m_dwLastError = ERROR_SUCCESS;
  61. }
  62. // tokenType
  63. BOOL CToken::GetTokenType ( TOKEN_TYPE& type ) const
  64. {
  65. BOOL bResult = FALSE ;
  66. DWORD dwReturnLength = 0L ;
  67. bResult = GetTokenInformation (
  68. m_hToken ,
  69. TokenType ,
  70. &type ,
  71. sizeof ( TOKEN_TYPE ) ,
  72. &dwReturnLength
  73. ) ;
  74. return bResult ;
  75. }
  76. // Duplicate CToken
  77. BOOL CToken::Duplicate (
  78. const CToken& tokDup,
  79. BOOL bReInit,
  80. DWORD dwDesiredAccess,
  81. SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  82. TOKEN_TYPE type
  83. )
  84. {
  85. CleanToken () ;
  86. // Duplicate token handle
  87. HANDLE hTmp = NULL;
  88. BOOL fResult = FALSE;
  89. if ( bReInit )
  90. {
  91. fResult = ::DuplicateTokenEx (
  92. tokDup.GetTokenHandle(),
  93. dwDesiredAccess,
  94. NULL,
  95. ImpersonationLevel,
  96. type,
  97. &hTmp
  98. );
  99. }
  100. else
  101. {
  102. DWORD dwError = ERROR_SUCCESS;
  103. SECURITY_INFORMATION siFlags = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
  104. // Determine the length needed for self-relative SD
  105. DWORD dwLengthNeeded = 0;
  106. fResult = ::GetKernelObjectSecurity (
  107. tokDup.GetTokenHandle(),
  108. siFlags,
  109. NULL,
  110. 0,
  111. &dwLengthNeeded
  112. );
  113. dwError = ::GetLastError();
  114. if( !fResult )
  115. {
  116. PSECURITY_DESCRIPTOR pSD = NULL;
  117. wmilib::auto_buffer < BYTE > pDeleteSD ;
  118. if ( ERROR_ACCESS_DENIED == dwError )
  119. {
  120. #if DBG == 1
  121. // for testing purpose I will let process break
  122. ::DebugBreak();
  123. #endif
  124. }
  125. if ( ERROR_INSUFFICIENT_BUFFER == dwError )
  126. {
  127. pSD = new BYTE[dwLengthNeeded];
  128. pDeleteSD.reset( reinterpret_cast < BYTE* > ( pSD ) ) ;
  129. if(pSD)
  130. {
  131. // Now obtain security descriptor
  132. if(::GetKernelObjectSecurity (
  133. tokDup.GetTokenHandle(),
  134. siFlags,
  135. pSD,
  136. dwLengthNeeded,
  137. &dwLengthNeeded
  138. )
  139. )
  140. {
  141. dwError = ERROR_SUCCESS;
  142. }
  143. }
  144. }
  145. if ( ERROR_SUCCESS == dwError )
  146. {
  147. SECURITY_ATTRIBUTES t_SecurityAttributes ;
  148. t_SecurityAttributes.nLength = ( pSD ) ? GetSecurityDescriptorLength ( pSD ) : 0 ;
  149. t_SecurityAttributes.lpSecurityDescriptor = pSD ;
  150. t_SecurityAttributes.bInheritHandle = FALSE ;
  151. fResult = ::DuplicateTokenEx (
  152. tokDup.GetTokenHandle() ,
  153. dwDesiredAccess ,
  154. ( pSD ) ? &t_SecurityAttributes : NULL ,
  155. ImpersonationLevel ,
  156. type ,
  157. &hTmp
  158. );
  159. }
  160. }
  161. }
  162. if(!fResult)
  163. {
  164. m_dwLastError = ::GetLastError();
  165. }
  166. else
  167. {
  168. m_hToken = hTmp;
  169. if ( bReInit )
  170. {
  171. m_dwLastError = ReinitializeAll();
  172. }
  173. m_fIsValid = true;
  174. }
  175. return fResult ;
  176. }
  177. CToken& CToken::operator=(
  178. const CToken& rTok)
  179. {
  180. Duplicate(rTok);
  181. return *this;
  182. }
  183. DWORD CToken::ReinitializeAll()
  184. {
  185. DWORD dwRet = ERROR_SUCCESS;
  186. dwRet = ReinitializeOwnerSid();
  187. if(dwRet == ERROR_SUCCESS )
  188. {
  189. dwRet = ReinitializeDefaultSD();
  190. }
  191. if(dwRet == ERROR_SUCCESS )
  192. {
  193. dwRet = RebuildGroupList();
  194. }
  195. if(dwRet == ERROR_SUCCESS )
  196. {
  197. dwRet = RebuildPrivilegeList();
  198. }
  199. return dwRet;
  200. }
  201. DWORD CToken::ReinitializeOwnerSid()
  202. {
  203. m_dwLastError = ERROR_SUCCESS;
  204. PTOKEN_USER ptokusr = NULL;
  205. try
  206. {
  207. GTI(TokenUser, (void**)&ptokusr);
  208. if(ptokusr)
  209. {
  210. if(m_dwLastError == ERROR_SUCCESS)
  211. {
  212. m_sidTokenOwner = CSid(ptokusr->User.Sid);
  213. }
  214. delete ptokusr; ptokusr = NULL;
  215. }
  216. }
  217. catch(...)
  218. {
  219. if(ptokusr)
  220. {
  221. delete ptokusr; ptokusr = NULL;
  222. }
  223. throw;
  224. }
  225. return m_dwLastError;
  226. }
  227. DWORD CToken::ReinitializeDefaultSD()
  228. {
  229. m_dwLastError = ERROR_SUCCESS;
  230. // Clean up default SD
  231. if(m_psdDefault)
  232. {
  233. delete m_psdDefault;
  234. m_psdDefault = NULL;
  235. }
  236. CSid* psidDefOwner = NULL;
  237. CDACL* pdaclDefault = NULL;
  238. PTOKEN_OWNER ptokowner = NULL;
  239. PTOKEN_DEFAULT_DACL pdefdacl = NULL;
  240. // Get default owner
  241. try
  242. {
  243. GTI(TokenOwner, (void**)&ptokowner);
  244. if(ptokowner)
  245. {
  246. if(m_dwLastError == ERROR_SUCCESS)
  247. {
  248. psidDefOwner = new CSid(ptokowner->Owner);
  249. }
  250. }
  251. GTI(TokenDefaultDacl, (void**)&pdefdacl);
  252. if(pdefdacl)
  253. {
  254. if(m_dwLastError == ERROR_SUCCESS)
  255. {
  256. pdaclDefault = new CDACL;
  257. m_dwLastError = pdaclDefault->Init(
  258. pdefdacl->DefaultDacl);
  259. }
  260. }
  261. if(m_dwLastError == ERROR_SUCCESS)
  262. {
  263. m_psdDefault = new CSecurityDescriptor(
  264. psidDefOwner,
  265. false,
  266. NULL,
  267. false,
  268. pdaclDefault,
  269. false,
  270. false,
  271. NULL,
  272. false,
  273. false);
  274. }
  275. if(psidDefOwner)
  276. {
  277. delete psidDefOwner; psidDefOwner = NULL;
  278. }
  279. if(pdaclDefault)
  280. {
  281. delete pdaclDefault; pdaclDefault = NULL;
  282. }
  283. if(ptokowner)
  284. {
  285. delete ptokowner; ptokowner = NULL;
  286. }
  287. if(pdefdacl)
  288. {
  289. delete pdefdacl; pdefdacl = NULL;
  290. }
  291. }
  292. catch(...)
  293. {
  294. if(psidDefOwner)
  295. {
  296. delete psidDefOwner; psidDefOwner = NULL;
  297. }
  298. if(pdaclDefault)
  299. {
  300. delete pdaclDefault; pdaclDefault = NULL;
  301. }
  302. if(ptokowner)
  303. {
  304. delete ptokowner; ptokowner = NULL;
  305. }
  306. if(pdefdacl)
  307. {
  308. delete pdefdacl; pdefdacl = NULL;
  309. }
  310. throw;
  311. }
  312. return m_dwLastError;
  313. }
  314. DWORD CToken::RebuildGroupList( void )
  315. {
  316. m_dwLastError = ERROR_SUCCESS;
  317. // Release the old list
  318. m_vecGroupsAndAttributes.clear();
  319. // Obtain and initialize groups from token
  320. PTOKEN_GROUPS ptg = NULL;
  321. try
  322. {
  323. GTI(TokenGroups, (void**)&ptg);
  324. if(ptg)
  325. {
  326. if(m_dwLastError == ERROR_SUCCESS)
  327. {
  328. for(long m = 0;
  329. m < ptg->GroupCount;
  330. m++)
  331. {
  332. m_vecGroupsAndAttributes.push_back(
  333. CSidAndAttribute(
  334. CSid(ptg->Groups[m].Sid),
  335. ptg->Groups[m].Attributes));
  336. }
  337. }
  338. delete ptg; ptg = NULL;
  339. }
  340. }
  341. catch(...)
  342. {
  343. if(ptg)
  344. {
  345. delete ptg; ptg = NULL;
  346. }
  347. }
  348. // If we are here, then groups are initialized
  349. return m_dwLastError;
  350. }
  351. DWORD CToken::RebuildPrivilegeList()
  352. {
  353. // Release the old list
  354. m_vecPrivileges.clear();
  355. // Obtain and initialize groups from token
  356. PTOKEN_PRIVILEGES ptp = NULL;
  357. const int NAME_SIZE = 128;
  358. BYTE bytePrivilegeName[NAME_SIZE];
  359. DWORD dwNameSize;
  360. try
  361. {
  362. GTI(TokenPrivileges, (void**)&ptp);
  363. if(ptp)
  364. {
  365. if(m_dwLastError == ERROR_SUCCESS)
  366. {
  367. for(long m = 0;
  368. m < ptp->PrivilegeCount &&
  369. m_dwLastError == ERROR_SUCCESS;
  370. m++)
  371. {
  372. dwNameSize = NAME_SIZE;
  373. if(::LookupPrivilegeName(
  374. NULL,
  375. &(ptp->Privileges[m].Luid),
  376. (WCHAR*) bytePrivilegeName,
  377. &dwNameSize))
  378. {
  379. m_vecPrivileges.push_back(Privilege(
  380. CHString((LPWSTR) bytePrivilegeName),
  381. ptp->Privileges[m].Attributes));
  382. }
  383. else
  384. {
  385. m_dwLastError = ::GetLastError();
  386. }
  387. }
  388. }
  389. delete ptp; ptp = NULL;
  390. }
  391. }
  392. catch(...)
  393. {
  394. if(ptp)
  395. {
  396. delete ptp; ptp = NULL;
  397. }
  398. }
  399. // If we are here, then privileges are initialized
  400. return m_dwLastError;
  401. }
  402. DWORD CToken::GTI(
  403. TOKEN_INFORMATION_CLASS TokenInformationClass,
  404. PVOID* ppvBuff)
  405. {
  406. ::SetLastError(ERROR_SUCCESS);
  407. m_dwLastError = ERROR_SUCCESS;
  408. DWORD dwRetSize = 0;
  409. if(!::GetTokenInformation(
  410. m_hToken,
  411. TokenInformationClass,
  412. NULL,
  413. 0L,
  414. &dwRetSize))
  415. {
  416. m_dwLastError = ::GetLastError();
  417. }
  418. if(m_dwLastError == ERROR_INSUFFICIENT_BUFFER)
  419. {
  420. // now get it for real...
  421. ::SetLastError(ERROR_SUCCESS);
  422. m_dwLastError = ERROR_SUCCESS;
  423. *ppvBuff = (PVOID) new BYTE[dwRetSize];
  424. DWORD dwTmp = dwRetSize;
  425. if(*ppvBuff)
  426. {
  427. if(!::GetTokenInformation(
  428. m_hToken,
  429. TokenInformationClass,
  430. *ppvBuff,
  431. dwTmp,
  432. &dwRetSize))
  433. {
  434. m_dwLastError = ::GetLastError();
  435. }
  436. }
  437. else
  438. {
  439. m_dwLastError = ::GetLastError();
  440. }
  441. }
  442. return m_dwLastError;
  443. }
  444. bool CToken::GetPrivilege(
  445. Privilege* privOut,
  446. long lPos) const
  447. {
  448. bool fRet = false;
  449. if(privOut)
  450. {
  451. if(lPos >= 0 &&
  452. lPos < m_vecPrivileges.size())
  453. {
  454. *privOut = m_vecPrivileges[lPos];
  455. fRet = true;
  456. }
  457. }
  458. return fRet;
  459. }
  460. bool CToken::GetGroup(
  461. CSid* sidOut,
  462. long lPos) const
  463. {
  464. bool fRet = false;
  465. if(sidOut)
  466. {
  467. if(lPos >= 0 &&
  468. lPos < m_vecGroupsAndAttributes.size())
  469. {
  470. *sidOut = m_vecGroupsAndAttributes[lPos].m_sid;
  471. fRet = true;
  472. }
  473. }
  474. return fRet;
  475. }
  476. long CToken::GetPrivCount() const
  477. {
  478. return m_vecPrivileges.size();
  479. }
  480. long CToken::GetGroupCount() const
  481. {
  482. return m_vecGroupsAndAttributes.size();
  483. }
  484. HANDLE CToken::GetTokenHandle() const
  485. {
  486. return m_hToken;
  487. }
  488. bool CToken::GetTokenOwner(
  489. CSid* sidOwner) const
  490. {
  491. bool fRet = false;
  492. if(sidOwner)
  493. {
  494. sidOwner = new CSid(m_sidTokenOwner);
  495. fRet = true;
  496. }
  497. return fRet;
  498. }
  499. // NOTE: hands back internal descriptor.
  500. bool CToken::GetDefaultSD(
  501. CSecurityDescriptor** ppsdDefault)
  502. {
  503. bool fRet = false;
  504. if(ppsdDefault)
  505. {
  506. if(m_psdDefault)
  507. {
  508. *ppsdDefault = m_psdDefault;
  509. fRet = true;
  510. }
  511. }
  512. return fRet;
  513. }
  514. DWORD CToken::SetDefaultSD(
  515. CSecurityDescriptor& SourceSD)
  516. {
  517. ::SetLastError(ERROR_SUCCESS);
  518. // Inject new default info into token
  519. // Set new default owner
  520. CSid SidOwner;
  521. CDACL cd;
  522. SourceSD.GetOwner(SidOwner);
  523. TOKEN_OWNER to;
  524. to.Owner = SidOwner.GetPSid();
  525. BOOL fResult = ::SetTokenInformation(
  526. m_hToken,
  527. TokenOwner,
  528. &to,
  529. sizeof(TOKEN_OWNER));
  530. if(!fResult)
  531. {
  532. m_dwLastError = ::GetLastError();
  533. }
  534. if(m_dwLastError == ERROR_SUCCESS)
  535. {
  536. // Set new default DACL
  537. TOKEN_DEFAULT_DACL tdd;
  538. if(SourceSD.GetDACL(cd))
  539. {
  540. CAccessEntryList cael;
  541. if(cd.GetMergedACL(cael))
  542. {
  543. PACL paclOut = NULL;
  544. if((m_dwLastError =
  545. cael.FillWin32ACL(paclOut)) ==
  546. ERROR_SUCCESS)
  547. {
  548. tdd.DefaultDacl = paclOut;
  549. fResult = ::SetTokenInformation(
  550. m_hToken,
  551. TokenDefaultDacl,
  552. &tdd,
  553. sizeof(TOKEN_DEFAULT_DACL));
  554. if(fResult)
  555. {
  556. // Reference new CSD in member variable
  557. if(m_psdDefault)
  558. {
  559. delete m_psdDefault; m_psdDefault = NULL;
  560. }
  561. m_psdDefault = new CSecurityDescriptor(
  562. &SidOwner,
  563. false,
  564. NULL,
  565. false,
  566. &cd,
  567. false,
  568. false,
  569. NULL,
  570. false,
  571. false);
  572. }
  573. else
  574. {
  575. m_dwLastError = ERROR_SUCCESS;
  576. }
  577. }
  578. }
  579. else
  580. {
  581. m_dwLastError = ERROR_SUCCESS;
  582. }
  583. }
  584. else
  585. {
  586. m_dwLastError = ERROR_SUCCESS;
  587. }
  588. }
  589. return m_dwLastError;
  590. }
  591. DWORD CToken::EnablePrivilege(
  592. CHString& strPrivilegeName )
  593. {
  594. // Check whether privilege exists
  595. bool fPrivilegeListed = false;
  596. for(long m = 0;
  597. m < m_vecPrivileges.size();
  598. m++)
  599. {
  600. if(m_vecPrivileges[m].chstrName.CompareNoCase(strPrivilegeName) == 0)
  601. {
  602. fPrivilegeListed = true;
  603. break;
  604. }
  605. }
  606. if(!fPrivilegeListed )
  607. {
  608. m_dwLastError = ERROR_INVALID_PARAMETER;
  609. }
  610. else
  611. {
  612. LUID luid;
  613. BOOL fResult = ::LookupPrivilegeValue(
  614. NULL, // use local computer
  615. strPrivilegeName,
  616. &luid);
  617. if(!fResult)
  618. {
  619. m_dwLastError = ::GetLastError();
  620. }
  621. else
  622. {
  623. TOKEN_PRIVILEGES tpNewState;
  624. tpNewState.PrivilegeCount = 1;
  625. tpNewState.Privileges[0].Luid = luid;
  626. tpNewState.Privileges[0].Attributes =
  627. SE_PRIVILEGE_ENABLED;
  628. TOKEN_PRIVILEGES tpPreviousState;
  629. DWORD dwSizePreviousState =
  630. sizeof(TOKEN_PRIVILEGES);
  631. fResult = ::AdjustTokenPrivileges(
  632. m_hToken,
  633. FALSE,
  634. &tpNewState,
  635. sizeof(TOKEN_PRIVILEGES),
  636. &tpPreviousState,
  637. &dwSizePreviousState);
  638. if(!fResult)
  639. {
  640. m_dwLastError = ::GetLastError();
  641. }
  642. else
  643. {
  644. m_dwLastError = RebuildPrivilegeList();
  645. }
  646. }
  647. }
  648. return m_dwLastError;
  649. }
  650. DWORD CToken::DisablePrivilege(
  651. CHString& chstrPrivilegeName)
  652. {
  653. // Check whether privilege exists
  654. bool fPrivilegeListed = false;
  655. for(long m = 0;
  656. m < m_vecPrivileges.size();
  657. m++)
  658. {
  659. if(m_vecPrivileges[m].chstrName.CompareNoCase(chstrPrivilegeName) == 0)
  660. {
  661. fPrivilegeListed = true;
  662. break;
  663. }
  664. }
  665. if(!fPrivilegeListed )
  666. {
  667. m_dwLastError = ERROR_INVALID_PARAMETER;
  668. }
  669. else
  670. {
  671. LUID luid;
  672. BOOL fResult = ::LookupPrivilegeValue(
  673. NULL, // use local computer
  674. chstrPrivilegeName,
  675. &luid);
  676. if(!fResult)
  677. {
  678. m_dwLastError = ::GetLastError();
  679. }
  680. else
  681. {
  682. TOKEN_PRIVILEGES tpNewState;
  683. tpNewState.PrivilegeCount = 1;
  684. tpNewState.Privileges[0].Luid = luid;
  685. tpNewState.Privileges[0].Attributes =
  686. 0;
  687. TOKEN_PRIVILEGES tpPreviousState;
  688. DWORD dwSizePreviousState =
  689. sizeof(TOKEN_PRIVILEGES);
  690. fResult = ::AdjustTokenPrivileges(
  691. m_hToken,
  692. FALSE,
  693. &tpNewState,
  694. sizeof(TOKEN_PRIVILEGES),
  695. &tpPreviousState,
  696. &dwSizePreviousState);
  697. if(!fResult)
  698. {
  699. m_dwLastError = ::GetLastError();
  700. }
  701. else
  702. {
  703. m_dwLastError = RebuildPrivilegeList();
  704. }
  705. }
  706. }
  707. return m_dwLastError;
  708. }
  709. void CToken::Dump(WCHAR* pszFileName)
  710. {
  711. /*
  712. * Algorithm:
  713. * 1. Dump token owner SID, name, and domain.
  714. * 2. Dump all group SIDs with names and domains.
  715. * 3. Dump list of privileges with attributes.
  716. * 4. Dump default owner.
  717. * 5. Dump default DACL.
  718. */
  719. CHString strFileName = pszFileName;
  720. // If file name is not empty - create the file
  721. FILE* fp = NULL;
  722. if(!strFileName.IsEmpty())
  723. {
  724. fp = _wfopen((LPCWSTR)strFileName, L"a");
  725. }
  726. else
  727. {
  728. return;
  729. }
  730. if(!fp) return;
  731. // Write to the file
  732. DWORD dwBytesWritten = 0;
  733. CHString strCRLF = L"\r\n";
  734. CHString strDump;
  735. {
  736. strDump = L"Token owner: " + m_sidTokenOwner.GetAccountName() + strCRLF;
  737. fputws(strDump, fp);
  738. strDump = L"Domain: " + m_sidTokenOwner.GetDomainName() + strCRLF;
  739. fputws(strDump, fp);
  740. strDump = L"SID: " + m_sidTokenOwner.GetSidString() + strCRLF + strCRLF;
  741. fputws(strDump, fp);
  742. }
  743. // Dump all groups
  744. fputws(strCRLF, fp);
  745. fputws(strCRLF, fp);
  746. for(long m = 0;
  747. m < m_vecGroupsAndAttributes.size();
  748. m++)
  749. {
  750. // Write to the file as well
  751. {
  752. strDump = L"Member of this group: " + m_vecGroupsAndAttributes[m].m_sid.GetSidString() + strCRLF;
  753. fputws(strDump, fp);
  754. strDump = L"\t(" + m_vecGroupsAndAttributes[m].m_sid.GetAccountName() + L" in " +
  755. m_vecGroupsAndAttributes[m].m_sid.GetDomainName() + L" domain)" + strCRLF;
  756. fputws(strDump, fp);
  757. }
  758. }
  759. // Dump all privileges
  760. fputws(strCRLF, fp);
  761. fputws(strCRLF, fp);
  762. for(m = 0;
  763. m < m_vecPrivileges.size();
  764. m++)
  765. {
  766. // Write to the file as well
  767. {
  768. strDump.Format( L"%d", m_vecPrivileges[m].dwAttributes );
  769. strDump = L"Holds a " + m_vecPrivileges[m].chstrName + L" with attributes: " + strDump + strCRLF;
  770. fputws(strDump, fp);
  771. }
  772. }
  773. // Dump default information
  774. fputws(strCRLF, fp);
  775. fputws(strCRLF, fp);
  776. {
  777. strDump = strCRLF + L"Default information:" + strCRLF;
  778. fputws(strDump, fp);
  779. }
  780. fputws(strCRLF, fp);
  781. fputws(strCRLF, fp);
  782. fclose(fp);
  783. if(m_psdDefault)
  784. {
  785. m_psdDefault->DumpDescriptor(pszFileName);
  786. }
  787. }
  788. // Deletes a member from the access token's
  789. // member list, and applies the change.
  790. bool CToken::DeleteGroup(
  791. CSid& sidToDelete)
  792. {
  793. bool fRet = false;
  794. // See if the group is in the membership
  795. // vector...
  796. bool fFoundIt = false;
  797. SANDATTRIBUTE_VECTOR::iterator iter;
  798. for(iter = m_vecGroupsAndAttributes.begin();
  799. iter != m_vecGroupsAndAttributes.end();
  800. iter++)
  801. {
  802. if(iter->m_sid.GetSidString().CompareNoCase(
  803. sidToDelete.GetSidString()) == 0)
  804. {
  805. fFoundIt = true;
  806. break;
  807. }
  808. }
  809. if(fFoundIt)
  810. {
  811. m_vecGroupsAndAttributes.erase(iter);
  812. // Now need to apply the changes. To do
  813. // so, we need to construct a TOKEN_GROUPS
  814. // structure...
  815. fRet = ApplyTokenGroups();
  816. }
  817. return fRet;
  818. }
  819. // Adds a member to the specified group to
  820. // the list of token groups.
  821. bool CToken::AddGroup(
  822. CSid& sidToAdd,
  823. DWORD dwAttributes)
  824. {
  825. bool fRet = false;
  826. // See if the group is in the membership
  827. // vector...
  828. bool fFoundIt = false;
  829. SANDATTRIBUTE_VECTOR::iterator iter;
  830. for(iter = m_vecGroupsAndAttributes.begin();
  831. iter != m_vecGroupsAndAttributes.end();
  832. iter++)
  833. {
  834. if(iter->m_sid.GetSidString().CompareNoCase(
  835. sidToAdd.GetSidString()) == 0)
  836. {
  837. fFoundIt = true;
  838. break;
  839. }
  840. }
  841. if(!fFoundIt)
  842. {
  843. m_vecGroupsAndAttributes.push_back(
  844. CSidAndAttribute(
  845. sidToAdd,
  846. dwAttributes));
  847. // Now need to apply the changes. To do
  848. // so, we need to construct a TOKEN_GROUPS
  849. // structure...
  850. fRet = ApplyTokenGroups();
  851. }
  852. return fRet;
  853. }
  854. bool CToken::ApplyTokenGroups()
  855. {
  856. bool fRet = false;
  857. PTOKEN_GROUPS ptg = NULL;
  858. try
  859. {
  860. ptg = (PTOKEN_GROUPS) new BYTE[sizeof(DWORD) +
  861. m_vecGroupsAndAttributes.size() * sizeof(SID_AND_ATTRIBUTES)];
  862. if(ptg)
  863. {
  864. ptg->GroupCount = m_vecGroupsAndAttributes.size();
  865. for(long m = 0;
  866. m < m_vecGroupsAndAttributes.size();
  867. m++)
  868. {
  869. ptg->Groups[m].Sid =
  870. m_vecGroupsAndAttributes[m].m_sid.GetPSid();
  871. ptg->Groups[m].Attributes =
  872. m_vecGroupsAndAttributes[m].m_dwAttributes;
  873. }
  874. // Now we can alter the groups...
  875. fRet = ::AdjustTokenGroups(
  876. m_hToken,
  877. FALSE,
  878. ptg,
  879. 0,
  880. NULL,
  881. NULL);
  882. delete ((PBYTE) ptg);
  883. ptg = NULL;
  884. }
  885. }
  886. catch(...)
  887. {
  888. if(ptg)
  889. {
  890. delete ((PBYTE) ptg);
  891. ptg = NULL;
  892. }
  893. throw;
  894. }
  895. return fRet;
  896. }
  897. ///////////////////////////////////////////////////////////////////////////////
  898. // CProcessToken class
  899. ///////////////////////////////////////////////////////////////////////////////
  900. CProcessToken::CProcessToken (
  901. HANDLE hProcess,
  902. bool fGetHandleOnly,
  903. DWORD dwDesiredAccess
  904. )
  905. {
  906. // Open handle to process access token
  907. m_dwLastError = ERROR_SUCCESS;
  908. // If they didn't give us a process handle,
  909. // use the current process.
  910. if ( NULL == hProcess || INVALID_HANDLE_VALUE == hProcess )
  911. {
  912. if(!::OpenProcessToken(
  913. GetCurrentProcess(),
  914. dwDesiredAccess,
  915. &m_hToken ))
  916. {
  917. m_dwLastError = ::GetLastError();
  918. }
  919. }
  920. else
  921. {
  922. m_hToken = hProcess;
  923. m_fClose = false ;
  924. }
  925. if(!fGetHandleOnly)
  926. {
  927. m_dwLastError = ReinitializeAll();
  928. }
  929. if(m_dwLastError == ERROR_SUCCESS )
  930. {
  931. m_fIsValid = true;
  932. }
  933. }
  934. ///////////////////////////////////////////////////////////////////////////////
  935. // CThreadToken class
  936. ///////////////////////////////////////////////////////////////////////////////
  937. CThreadToken::CThreadToken (
  938. HANDLE hThread,
  939. bool fGetHandleOnly,
  940. bool fAccessCheckProcess,
  941. DWORD dwDesiredAccess
  942. )
  943. {
  944. m_dwLastError = ERROR_SUCCESS;
  945. // If they didn't give us a thread handle,
  946. // use the current thread.
  947. if ( NULL == hThread || hThread == INVALID_HANDLE_VALUE )
  948. {
  949. // Open thread access token
  950. HANDLE hToken = NULL;
  951. if(!::OpenThreadToken(
  952. GetCurrentThread(),
  953. dwDesiredAccess,
  954. fAccessCheckProcess,
  955. &hToken))
  956. {
  957. m_dwLastError = ::GetLastError();
  958. }
  959. else
  960. {
  961. m_hToken = hToken ;
  962. }
  963. }
  964. else
  965. {
  966. m_hToken = hThread ;
  967. m_fClose = false ;
  968. }
  969. if ( ERROR_SUCCESS == m_dwLastError )
  970. {
  971. if ( !fGetHandleOnly )
  972. {
  973. m_dwLastError = ReinitializeAll();
  974. }
  975. }
  976. if(m_dwLastError == ERROR_SUCCESS)
  977. {
  978. // If we are here, everything is initialized
  979. m_fIsValid = TRUE;
  980. }
  981. }