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.

2231 lines
44 KiB

  1. /*++
  2. Copyright (C) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. CALLSEC.CPP
  5. Abstract:
  6. History:
  7. raymcc 29-Jul-98 First draft.
  8. --*/
  9. #include "precomp.h"
  10. #include <initguid.h>
  11. #ifndef INITGUID
  12. #define INITGUID
  13. #endif
  14. #include <stdio.h>
  15. #include <wbemint.h>
  16. #include "CallSec.h"
  17. // {4551AB1A-C16F-40f3-A192-6A6264FE89D6}
  18. DEFINE_GUID(IID_CWbemCallSecurity,
  19. 0x4551ab1a, 0xc16f, 0x40f3, 0xa1, 0x92, 0x6a, 0x62, 0x64, 0xfe, 0x89, 0xd6);
  20. // {60B9F5CA-036E-4795-BB7C-017B9807E9B3}
  21. DEFINE_GUID(IID_CWbemThreadSecurityHandle,
  22. 0x60b9f5ca, 0x36e, 0x4795, 0xbb, 0x7c, 0x1, 0x7b, 0x98, 0x7, 0xe9, 0xb3);
  23. /******************************************************************************
  24. *
  25. * Name:
  26. *
  27. *
  28. * Description:
  29. *
  30. *
  31. *****************************************************************************/
  32. HRESULT IsNetworkLogin (
  33. HANDLE a_Token ,
  34. BOOL &a_Truth
  35. )
  36. {
  37. HRESULT t_Result = S_OK ;
  38. PSID t_NetworkSid = NULL ;
  39. SID_IDENTIFIER_AUTHORITY t_NtAuthority = SECURITY_NT_AUTHORITY ;
  40. BOOL t_Status = AllocateAndInitializeSid (
  41. &t_NtAuthority,
  42. 1,
  43. SECURITY_NETWORK_RID,
  44. 0,
  45. 0,
  46. 0,
  47. 0,
  48. 0,
  49. 0,
  50. 0,
  51. & t_NetworkSid
  52. ) ;
  53. if ( t_Status )
  54. {
  55. t_Status = CheckTokenMembership ( a_Token, t_NetworkSid, & a_Truth ) ;
  56. if ( t_Status )
  57. {
  58. }
  59. else
  60. {
  61. t_Result = WBEM_E_FAILED ;
  62. }
  63. FreeSid ( t_NetworkSid ) ;
  64. }
  65. else
  66. {
  67. t_Result = WBEM_E_FAILED ;
  68. }
  69. return t_Result ;
  70. }
  71. /******************************************************************************
  72. *
  73. * Name:
  74. *
  75. *
  76. * Description:
  77. *
  78. *
  79. *****************************************************************************/
  80. HRESULT GetImpersonationLevel (
  81. HANDLE a_Token ,
  82. SECURITY_IMPERSONATION_LEVEL &a_Level ,
  83. TOKEN_TYPE &a_TokenType
  84. )
  85. {
  86. HRESULT t_Result = S_OK ;
  87. DWORD t_ReturnLength = 0 ;
  88. BOOL t_TokenStatus = GetTokenInformation (
  89. a_Token ,
  90. TokenType ,
  91. ( void * ) & a_TokenType ,
  92. sizeof ( a_TokenType ) ,
  93. & t_ReturnLength
  94. ) ;
  95. if ( t_TokenStatus )
  96. {
  97. if ( a_TokenType == TokenImpersonation )
  98. {
  99. BOOL t_TempTokenStatus = GetTokenInformation (
  100. a_Token ,
  101. TokenImpersonationLevel ,
  102. ( void * ) & a_Level ,
  103. sizeof ( a_Level ) ,
  104. & t_ReturnLength
  105. ) ;
  106. if ( t_TempTokenStatus )
  107. {
  108. t_Result = S_OK ;
  109. }
  110. else
  111. {
  112. t_Result = WBEM_E_FAILED ;
  113. }
  114. }
  115. }
  116. else
  117. {
  118. t_Result = WBEM_E_FAILED ;
  119. }
  120. return t_Result ;
  121. }
  122. /******************************************************************************
  123. *
  124. * Name:
  125. *
  126. *
  127. * Description:
  128. *
  129. *
  130. *****************************************************************************/
  131. HRESULT GetUserSid (
  132. HANDLE a_Token ,
  133. ULONG *a_Size ,
  134. PSID a_Sid
  135. )
  136. {
  137. HRESULT t_Result = WBEM_E_FAILED ;
  138. if ( a_Token )
  139. {
  140. if ( a_Size )
  141. {
  142. TOKEN_USER *t_TokenUser = NULL ;
  143. DWORD t_ReturnLength = 0 ;
  144. TOKEN_INFORMATION_CLASS t_TokenInformationClass = TokenUser ;
  145. BOOL t_TokenStatus = GetTokenInformation (
  146. a_Token ,
  147. t_TokenInformationClass ,
  148. t_TokenUser ,
  149. t_ReturnLength ,
  150. & t_ReturnLength
  151. ) ;
  152. if ( ! t_TokenStatus )
  153. {
  154. DWORD t_LastError = GetLastError () ;
  155. switch ( t_LastError )
  156. {
  157. case ERROR_INSUFFICIENT_BUFFER:
  158. {
  159. if ( a_Sid )
  160. {
  161. if ( *a_Size >= t_ReturnLength )
  162. {
  163. t_TokenUser = ( TOKEN_USER * ) new BYTE [ t_ReturnLength ] ;
  164. if ( t_TokenUser )
  165. {
  166. t_TokenStatus = GetTokenInformation (
  167. a_Token ,
  168. t_TokenInformationClass ,
  169. t_TokenUser ,
  170. t_ReturnLength ,
  171. & t_ReturnLength
  172. ) ;
  173. if ( t_TokenStatus )
  174. {
  175. DWORD t_SidLength = GetLengthSid ( t_TokenUser->User.Sid ) ;
  176. *a_Size = t_SidLength ;
  177. CopyMemory ( a_Sid , t_TokenUser->User.Sid , t_SidLength ) ;
  178. t_Result = S_OK ;
  179. }
  180. delete [] t_TokenUser ;
  181. }
  182. else
  183. {
  184. t_Result = WBEM_E_OUT_OF_MEMORY ;
  185. }
  186. }
  187. else
  188. {
  189. t_Result = WBEM_E_BUFFER_TOO_SMALL ;
  190. }
  191. }
  192. else
  193. {
  194. *a_Size = t_ReturnLength ;
  195. t_Result = S_OK ;
  196. }
  197. }
  198. break ;
  199. default:
  200. {
  201. }
  202. break ;
  203. }
  204. }
  205. }
  206. else
  207. {
  208. t_Result = WBEM_E_INVALID_PARAMETER ;
  209. }
  210. }
  211. else
  212. {
  213. t_Result = ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  214. }
  215. return t_Result ;
  216. }
  217. /******************************************************************************
  218. *
  219. * Name:
  220. *
  221. *
  222. * Description:
  223. *
  224. *
  225. *****************************************************************************/
  226. HRESULT GetUser (
  227. HANDLE a_Token ,
  228. ULONG *a_Size ,
  229. LPWSTR a_Buffer
  230. )
  231. {
  232. HRESULT t_Result = S_OK ;
  233. if ( a_Token )
  234. {
  235. if ( a_Size && a_Buffer )
  236. {
  237. TOKEN_USER *t_TokenUser = NULL ;
  238. DWORD t_ReturnLength = 0 ;
  239. TOKEN_INFORMATION_CLASS t_TokenInformationClass = TokenUser ;
  240. BOOL t_TokenStatus = GetTokenInformation (
  241. a_Token ,
  242. t_TokenInformationClass ,
  243. t_TokenUser ,
  244. t_ReturnLength ,
  245. & t_ReturnLength
  246. ) ;
  247. if ( ! t_TokenStatus )
  248. {
  249. DWORD t_LastError = GetLastError () ;
  250. switch ( t_LastError )
  251. {
  252. case ERROR_INSUFFICIENT_BUFFER:
  253. {
  254. t_TokenUser = ( TOKEN_USER * ) new BYTE [ t_ReturnLength ] ;
  255. t_TokenStatus = GetTokenInformation (
  256. a_Token ,
  257. t_TokenInformationClass ,
  258. t_TokenUser ,
  259. t_ReturnLength ,
  260. & t_ReturnLength
  261. ) ;
  262. }
  263. break ;
  264. default:
  265. {
  266. }
  267. break ;
  268. }
  269. }
  270. if ( t_TokenStatus )
  271. {
  272. SID_NAME_USE t_SidNameUse ;
  273. wchar_t *t_Domain = NULL ;
  274. wchar_t *t_User = NULL ;
  275. ULONG t_DomainSize = 0 ;
  276. ULONG t_UserSize = 0 ;
  277. BOOL t_LookupStatus = LookupAccountSidW (
  278. NULL ,
  279. t_TokenUser->User.Sid ,
  280. t_User ,
  281. & t_UserSize ,
  282. t_Domain ,
  283. & t_DomainSize ,
  284. & t_SidNameUse
  285. ) ;
  286. if ( ! t_LookupStatus )
  287. {
  288. DWORD t_LastError = GetLastError () ;
  289. switch ( t_LastError )
  290. {
  291. case ERROR_INSUFFICIENT_BUFFER:
  292. {
  293. t_User = new wchar_t [ t_UserSize ] ;
  294. if ( t_User )
  295. {
  296. t_Domain = new wchar_t [ t_DomainSize ] ;
  297. if ( t_Domain )
  298. {
  299. t_LookupStatus = LookupAccountSidW (
  300. NULL ,
  301. t_TokenUser->User.Sid ,
  302. t_User ,
  303. & t_UserSize ,
  304. t_Domain ,
  305. & t_DomainSize ,
  306. & t_SidNameUse
  307. ) ;
  308. if ( t_LookupStatus )
  309. {
  310. ULONG t_Size = wcslen ( t_User ) + wcslen ( t_Domain ) + 2 ;
  311. if ( *a_Size >= t_Size )
  312. {
  313. StringCchPrintfW ( a_Buffer , *a_Size, L"%s\\%s" , t_Domain , t_User ) ;
  314. }
  315. else
  316. {
  317. t_Result = WBEM_E_BUFFER_TOO_SMALL ;
  318. }
  319. *a_Size = t_Size ;
  320. }
  321. else
  322. {
  323. if ( GetLastError () == ERROR_NONE_MAPPED )
  324. {
  325. t_Result = WBEM_E_NOT_FOUND ;
  326. }
  327. else
  328. {
  329. t_Result = WBEM_E_FAILED ;
  330. }
  331. }
  332. delete [] t_Domain ;
  333. }
  334. else
  335. {
  336. t_Result = WBEM_E_OUT_OF_MEMORY ;
  337. }
  338. delete [] t_User ;
  339. }
  340. else
  341. {
  342. t_Result = WBEM_E_OUT_OF_MEMORY ;
  343. }
  344. }
  345. break ;
  346. case ERROR_NONE_MAPPED:
  347. {
  348. t_Result = WBEM_E_NOT_FOUND ;
  349. }
  350. break ;
  351. default:
  352. {
  353. t_Result = WBEM_E_FAILED ;
  354. }
  355. break ;
  356. }
  357. }
  358. else
  359. {
  360. t_Result = WBEM_E_UNEXPECTED ;
  361. }
  362. }
  363. else
  364. {
  365. t_Result = WBEM_E_FAILED ;
  366. DWORD t_LastError = GetLastError () ;
  367. }
  368. if ( t_TokenUser )
  369. {
  370. delete [] ( ( BYTE * ) t_TokenUser ) ;
  371. }
  372. }
  373. else
  374. {
  375. t_Result = WBEM_E_INVALID_PARAMETER ;
  376. }
  377. }
  378. else
  379. {
  380. t_Result = ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  381. }
  382. return t_Result ;
  383. }
  384. /******************************************************************************
  385. *
  386. * Name:
  387. *
  388. *
  389. * Description:
  390. *
  391. *
  392. *****************************************************************************/
  393. HRESULT GetAuthenticationLuid (
  394. HANDLE a_Token ,
  395. LPVOID a_Luid
  396. )
  397. {
  398. if ( a_Token )
  399. {
  400. TOKEN_STATISTICS t_Statistics ;
  401. DWORD t_Returned = 0 ;
  402. BOOL t_Status = GetTokenInformation (
  403. a_Token,
  404. TokenStatistics,
  405. ( void * ) & t_Statistics ,
  406. sizeof ( t_Statistics ) ,
  407. & t_Returned
  408. ) ;
  409. if ( t_Status )
  410. {
  411. * ( ( LUID * ) a_Luid ) = t_Statistics.AuthenticationId ;
  412. }
  413. else
  414. {
  415. return WBEM_E_ACCESS_DENIED ;
  416. }
  417. }
  418. else
  419. {
  420. return ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  421. }
  422. return S_OK ;
  423. }
  424. /******************************************************************************
  425. *
  426. * Name:
  427. *
  428. *
  429. * Description:
  430. *
  431. *
  432. *****************************************************************************/
  433. CWbemThreadSecurityHandle :: CWbemThreadSecurityHandle ( CLifeControl *a_Control ) :
  434. m_ReferenceCount ( 0 ) ,
  435. m_ThreadToken ( NULL ) ,
  436. m_ImpersonationLevel ( 0 ) ,
  437. m_AuthorizationService ( 0 ) ,
  438. m_AuthenticationService ( 0 ) ,
  439. m_AuthenticationLevel ( 0 ) ,
  440. m_ServerPrincipalName ( 0 ) ,
  441. m_Identity ( NULL ) ,
  442. m_Origin ( WMI_ORIGIN_UNDEFINED ) ,
  443. m_Control ( a_Control )
  444. {
  445. if ( m_Control )
  446. {
  447. m_Control->ObjectCreated ( ( IServerSecurity * ) this ) ;
  448. }
  449. }
  450. /******************************************************************************
  451. *
  452. * Name:
  453. *
  454. *
  455. * Description:
  456. *
  457. *
  458. *****************************************************************************/
  459. CWbemThreadSecurityHandle :: CWbemThreadSecurityHandle (
  460. const CWbemThreadSecurityHandle &a_Copy
  461. ) : m_ReferenceCount ( 0 ) ,
  462. m_ThreadToken ( NULL ) ,
  463. m_ImpersonationLevel ( 0 ) ,
  464. m_AuthorizationService ( 0 ) ,
  465. m_AuthenticationService ( 0 ) ,
  466. m_AuthenticationLevel ( 0 ) ,
  467. m_ServerPrincipalName ( 0 ) ,
  468. m_Identity ( NULL ) ,
  469. m_Origin ( WMI_ORIGIN_UNDEFINED ) ,
  470. m_Control ( NULL )
  471. {
  472. *this = a_Copy ;
  473. }
  474. /******************************************************************************
  475. *
  476. * Name:
  477. *
  478. *
  479. * Description:
  480. *
  481. *
  482. *****************************************************************************/
  483. CWbemThreadSecurityHandle :: ~CWbemThreadSecurityHandle ()
  484. {
  485. if ( m_ThreadToken )
  486. {
  487. CloseHandle ( m_ThreadToken ) ;
  488. }
  489. if ( m_ServerPrincipalName )
  490. {
  491. CoTaskMemFree ( m_ServerPrincipalName ) ;
  492. }
  493. if ( m_Identity )
  494. {
  495. CoTaskMemFree ( m_Identity ) ;
  496. }
  497. if ( m_Control )
  498. {
  499. m_Control->ObjectDestroyed ( ( IServerSecurity * ) this ) ;
  500. }
  501. }
  502. /******************************************************************************
  503. *
  504. * Name:
  505. *
  506. *
  507. * Description:
  508. *
  509. *
  510. *****************************************************************************/
  511. CWbemThreadSecurityHandle &CWbemThreadSecurityHandle :: operator= ( const CWbemThreadSecurityHandle &a_Copy )
  512. {
  513. if ( m_ThreadToken )
  514. {
  515. CloseHandle ( m_ThreadToken ) ;
  516. m_ThreadToken = NULL ;
  517. }
  518. if ( a_Copy.m_ThreadToken )
  519. {
  520. BOOL t_Status = DuplicateHandle (
  521. GetCurrentProcess () ,
  522. a_Copy.m_ThreadToken ,
  523. GetCurrentProcess () ,
  524. & m_ThreadToken ,
  525. 0 ,
  526. TRUE ,
  527. DUPLICATE_SAME_ACCESS
  528. ) ;
  529. }
  530. m_Origin = a_Copy.m_Origin ;
  531. m_ImpersonationLevel = a_Copy.m_ImpersonationLevel ;
  532. m_AuthenticationService = a_Copy.m_AuthenticationService ;
  533. m_AuthorizationService = a_Copy.m_AuthorizationService ;
  534. m_AuthenticationLevel = a_Copy.m_AuthenticationLevel ;
  535. if ( m_ServerPrincipalName )
  536. {
  537. CoTaskMemFree ( m_ServerPrincipalName ) ;
  538. m_ServerPrincipalName = NULL ;
  539. }
  540. if ( a_Copy.m_ServerPrincipalName )
  541. {
  542. m_ServerPrincipalName = ( LPWSTR ) CoTaskMemAlloc ( ( wcslen ( a_Copy.m_ServerPrincipalName ) + 1 ) * 2 ) ;
  543. if ( m_ServerPrincipalName )
  544. {
  545. StringCchCopyW ( m_ServerPrincipalName, wcslen ( a_Copy.m_ServerPrincipalName ) + 1, a_Copy.m_ServerPrincipalName ) ;
  546. }
  547. }
  548. if ( m_Identity )
  549. {
  550. CoTaskMemFree ( m_Identity ) ;
  551. m_Identity = NULL ;
  552. }
  553. if ( a_Copy.m_Identity )
  554. {
  555. m_Identity = ( LPWSTR ) CoTaskMemAlloc ( ( wcslen ( a_Copy.m_Identity ) + 1 ) * 2 ) ;
  556. if ( m_Identity )
  557. {
  558. StringCchCopyW ( m_Identity , wcslen ( a_Copy.m_Identity ) + 1, a_Copy.m_Identity ) ;
  559. }
  560. }
  561. if ( a_Copy.m_Control )
  562. {
  563. m_Control = a_Copy.m_Control ;
  564. if ( m_Control )
  565. {
  566. m_Control->ObjectCreated ( ( IServerSecurity * ) this ) ;
  567. }
  568. }
  569. return *this ;
  570. }
  571. /******************************************************************************
  572. *
  573. * Name:
  574. *
  575. *
  576. * Description:
  577. *
  578. *
  579. *****************************************************************************/
  580. ULONG CWbemThreadSecurityHandle :: AddRef ()
  581. {
  582. return InterlockedIncrement ( & m_ReferenceCount ) ;
  583. }
  584. /******************************************************************************
  585. *
  586. * Name:
  587. *
  588. *
  589. * Description:
  590. *
  591. *
  592. *****************************************************************************/
  593. ULONG CWbemThreadSecurityHandle :: Release ()
  594. {
  595. LONG t_ReferenceCount = InterlockedDecrement( & m_ReferenceCount ) ;
  596. if ( t_ReferenceCount == 0 )
  597. {
  598. delete this ;
  599. }
  600. return t_ReferenceCount ;
  601. }
  602. /******************************************************************************
  603. *
  604. * Name:
  605. *
  606. *
  607. * Description:
  608. *
  609. *
  610. *****************************************************************************/
  611. HRESULT CWbemThreadSecurityHandle :: QueryInterface ( REFIID a_Riid , void **a_Void )
  612. {
  613. if ( a_Riid == IID_IUnknown )
  614. {
  615. *a_Void = ( void ** ) this ;
  616. AddRef () ;
  617. return S_OK ;
  618. }
  619. else if ( a_Riid == IID__IWmiThreadSecHandle )
  620. {
  621. *a_Void = ( void ** ) ( _IWmiThreadSecHandle * ) this ;
  622. AddRef () ;
  623. return S_OK ;
  624. }
  625. else if ( a_Riid == IID_CWbemThreadSecurityHandle )
  626. {
  627. *a_Void = ( void ** ) ( CWbemThreadSecurityHandle * ) this ;
  628. AddRef () ;
  629. return S_OK ;
  630. }
  631. else
  632. {
  633. return E_NOINTERFACE ;
  634. }
  635. }
  636. /******************************************************************************
  637. *
  638. * Name:
  639. *
  640. *
  641. * Description:
  642. *
  643. *
  644. *****************************************************************************/
  645. HRESULT CWbemThreadSecurityHandle :: GetToken ( HANDLE *a_ThreadToken )
  646. {
  647. HRESULT t_Result = S_OK ;
  648. if ( a_ThreadToken )
  649. {
  650. if ( m_ThreadToken )
  651. {
  652. HANDLE t_ThreadToken = NULL ;
  653. BOOL t_Status = DuplicateHandle (
  654. GetCurrentProcess () ,
  655. m_ThreadToken ,
  656. GetCurrentProcess () ,
  657. & t_ThreadToken ,
  658. 0 ,
  659. TRUE ,
  660. DUPLICATE_SAME_ACCESS
  661. ) ;
  662. if ( t_Status )
  663. {
  664. *a_ThreadToken = t_ThreadToken ;
  665. }
  666. else
  667. {
  668. t_Result = WBEM_E_ACCESS_DENIED ;
  669. }
  670. }
  671. else
  672. {
  673. t_Result = ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  674. }
  675. }
  676. else
  677. {
  678. t_Result = WBEM_E_INVALID_PARAMETER ;
  679. }
  680. return t_Result ;
  681. }
  682. /******************************************************************************
  683. *
  684. * Name:
  685. *
  686. *
  687. * Description:
  688. *
  689. *
  690. *****************************************************************************/
  691. HRESULT CWbemThreadSecurityHandle :: GetUser (
  692. ULONG *a_Size ,
  693. LPWSTR a_Buffer
  694. )
  695. {
  696. HRESULT t_Result = S_OK ;
  697. if ( m_ThreadToken )
  698. {
  699. t_Result = :: GetUser ( m_ThreadToken , a_Size , a_Buffer ) ;
  700. }
  701. else
  702. {
  703. t_Result = ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  704. }
  705. return t_Result ;
  706. }
  707. /******************************************************************************
  708. *
  709. * Name:
  710. *
  711. *
  712. * Description:
  713. *
  714. *
  715. *****************************************************************************/
  716. HRESULT CWbemThreadSecurityHandle :: GetUserSid (
  717. ULONG *a_Size ,
  718. PSID a_Sid
  719. )
  720. {
  721. HRESULT t_Result = S_OK ;
  722. if ( m_ThreadToken )
  723. {
  724. t_Result = :: GetUserSid ( m_ThreadToken , a_Size , a_Sid ) ;
  725. }
  726. else
  727. {
  728. t_Result = ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  729. }
  730. return t_Result ;
  731. }
  732. /******************************************************************************
  733. *
  734. * Name:
  735. *
  736. *
  737. * Description:
  738. *
  739. *
  740. *****************************************************************************/
  741. HRESULT CWbemThreadSecurityHandle :: GetAuthenticationLuid ( LPVOID a_Luid )
  742. {
  743. HRESULT t_Result = S_OK ;
  744. if ( m_ThreadToken )
  745. {
  746. t_Result = :: GetAuthenticationLuid ( m_ThreadToken , a_Luid ) ;
  747. }
  748. else
  749. {
  750. t_Result = ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  751. }
  752. return t_Result ;
  753. }
  754. /******************************************************************************
  755. *
  756. * Name:
  757. *
  758. *
  759. * Description:
  760. *
  761. *
  762. *****************************************************************************/
  763. HRESULT CWbemThreadSecurityHandle :: GetImpersonation ( DWORD *a_Level )
  764. {
  765. HRESULT t_Result = S_OK ;
  766. if ( m_ThreadToken )
  767. {
  768. if ( a_Level )
  769. {
  770. SECURITY_IMPERSONATION_LEVEL t_ImpersonationLevel = SecurityAnonymous ;
  771. TOKEN_TYPE t_TokenType = TokenImpersonation ;
  772. t_Result = :: GetImpersonationLevel (
  773. m_ThreadToken ,
  774. t_ImpersonationLevel ,
  775. t_TokenType
  776. ) ;
  777. if ( SUCCEEDED ( t_Result ) )
  778. {
  779. switch ( t_ImpersonationLevel )
  780. {
  781. case SecurityAnonymous:
  782. {
  783. *a_Level = RPC_C_IMP_LEVEL_ANONYMOUS ;
  784. }
  785. break ;
  786. case SecurityIdentification:
  787. {
  788. *a_Level = RPC_C_IMP_LEVEL_IDENTIFY ;
  789. }
  790. break ;
  791. case SecurityImpersonation:
  792. {
  793. *a_Level = RPC_C_IMP_LEVEL_IMPERSONATE ;
  794. }
  795. break ;
  796. case SecurityDelegation:
  797. {
  798. *a_Level = RPC_C_IMP_LEVEL_DELEGATE ;
  799. }
  800. break ;
  801. default:
  802. {
  803. *a_Level = 0 ;
  804. }
  805. break ;
  806. }
  807. }
  808. }
  809. else
  810. {
  811. t_Result = WBEM_E_INVALID_PARAMETER ;
  812. }
  813. }
  814. else
  815. {
  816. t_Result = ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  817. }
  818. return t_Result ;
  819. }
  820. /******************************************************************************
  821. *
  822. * Name:
  823. *
  824. *
  825. * Description:
  826. *
  827. *
  828. *****************************************************************************/
  829. HRESULT CWbemThreadSecurityHandle :: GetAuthentication (
  830. DWORD *a_Level
  831. )
  832. {
  833. HRESULT t_Result = S_OK ;
  834. if ( a_Level )
  835. {
  836. *a_Level = GetAuthenticationLevel () ;
  837. }
  838. else
  839. {
  840. t_Result = WBEM_E_INVALID_PARAMETER ;
  841. }
  842. return t_Result ;
  843. }
  844. /******************************************************************************
  845. *
  846. * Name:
  847. *
  848. *
  849. * Description:
  850. *
  851. *
  852. *****************************************************************************/
  853. HRESULT CWbemThreadSecurityHandle :: CloneRpcContext (
  854. IServerSecurity *a_Security
  855. )
  856. {
  857. HRESULT t_Result = S_OK ;
  858. // If here, we are not impersonating and we want to gather info
  859. // about the client's call.
  860. // ============================================================
  861. RPC_AUTHZ_HANDLE t_Authorization = NULL ;
  862. // Ensures auto release of the mutex if we crash
  863. // CAutoSecurityMutex t_SecurityMutex ;
  864. DWORD t_ImpersonationLevel = 0 ;
  865. t_Result = a_Security->QueryBlanket (
  866. & m_AuthenticationService ,
  867. & m_AuthorizationService ,
  868. & m_ServerPrincipalName ,
  869. & m_AuthenticationLevel ,
  870. & t_ImpersonationLevel ,
  871. & t_Authorization ,
  872. NULL
  873. ) ;
  874. if ( FAILED ( t_Result ) )
  875. {
  876. // In some cases, we cant get the name, but the rest is ok. In particular
  877. // the temporary SMS accounts have that property. Or nt 4 after IPCONFIG /RELEASE
  878. t_Result = a_Security->QueryBlanket (
  879. & m_AuthenticationService ,
  880. & m_AuthorizationService ,
  881. & m_ServerPrincipalName ,
  882. & m_AuthenticationLevel ,
  883. & t_ImpersonationLevel ,
  884. NULL ,
  885. NULL
  886. ) ;
  887. t_Authorization = NULL ;
  888. }
  889. // We don't need this anymore.
  890. // t_SecurityMutex.Release () ;
  891. if ( SUCCEEDED ( t_Result ) )
  892. {
  893. if ( t_Authorization )
  894. {
  895. m_Identity = LPWSTR ( CoTaskMemAlloc ( ( wcslen ( LPWSTR ( t_Authorization ) ) + 1 ) * 2 ) ) ;
  896. if ( m_Identity )
  897. {
  898. StringCchCopyW ( m_Identity , wcslen ( LPWSTR ( t_Authorization ) ) + 1, LPWSTR ( t_Authorization ) ) ;
  899. }
  900. }
  901. // Impersonate the client long enough to clone the thread token.
  902. // =============================================================
  903. BOOL t_Impersonating = a_Security->IsImpersonating () ;
  904. if ( ! t_Impersonating )
  905. {
  906. t_Result = a_Security->ImpersonateClient () ;
  907. }
  908. if ( SUCCEEDED ( t_Result ) )
  909. {
  910. t_Result = CloneThreadContext () ;
  911. if ( ! t_Impersonating )
  912. {
  913. a_Security->RevertToSelf () ;
  914. }
  915. }
  916. }
  917. else
  918. {
  919. // THIS IS A WORKAROUND FOR COM BUG:
  920. // This failure is indicative of an anonymous-level client.
  921. // ========================================================
  922. m_ImpersonationLevel = 0 ;
  923. t_Result = S_OK ;
  924. }
  925. return t_Result ;
  926. }
  927. /******************************************************************************
  928. *
  929. * Name:
  930. *
  931. *
  932. * Description:
  933. *
  934. *
  935. *****************************************************************************/
  936. HRESULT CWbemThreadSecurityHandle :: CloneThreadContext ()
  937. {
  938. HRESULT t_Result = S_OK ;
  939. BOOL t_Status = OpenThreadToken (
  940. GetCurrentThread () ,
  941. MAXIMUM_ALLOWED ,
  942. TRUE ,
  943. & m_ThreadToken
  944. ) ;
  945. if ( t_Status )
  946. {
  947. // Find out token info.
  948. // =====================
  949. DWORD t_ImpersonationLevel = 0 ;
  950. DWORD t_Returned = 0 ;
  951. t_Status = GetTokenInformation (
  952. m_ThreadToken ,
  953. TokenImpersonationLevel ,
  954. & t_ImpersonationLevel ,
  955. sizeof ( DWORD ) ,
  956. & t_Returned
  957. ) ;
  958. if ( t_Status )
  959. {
  960. switch ( t_ImpersonationLevel )
  961. {
  962. case SecurityAnonymous:
  963. {
  964. m_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS ;
  965. }
  966. break ;
  967. case SecurityIdentification:
  968. {
  969. m_ImpersonationLevel = RPC_C_IMP_LEVEL_IDENTIFY ;
  970. }
  971. break ;
  972. case SecurityImpersonation:
  973. {
  974. m_ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE ;
  975. }
  976. break ;
  977. case SecurityDelegation:
  978. {
  979. m_ImpersonationLevel = RPC_C_IMP_LEVEL_DELEGATE ;
  980. }
  981. break ;
  982. default:
  983. {
  984. m_ImpersonationLevel = 0 ;
  985. }
  986. break ;
  987. }
  988. }
  989. else
  990. {
  991. if ( GetLastError () == ERROR_ACCESS_DENIED )
  992. {
  993. t_Result = WBEM_E_ACCESS_DENIED ;
  994. }
  995. else
  996. {
  997. t_Result = WBEM_E_NOT_FOUND ;
  998. }
  999. }
  1000. }
  1001. else
  1002. {
  1003. if ( GetLastError () == ERROR_ACCESS_DENIED )
  1004. {
  1005. t_Result = WBEM_E_ACCESS_DENIED ;
  1006. }
  1007. else
  1008. {
  1009. t_Result = WBEM_E_NOT_FOUND ;
  1010. }
  1011. }
  1012. return t_Result ;
  1013. }
  1014. /******************************************************************************
  1015. *
  1016. * Name:
  1017. *
  1018. *
  1019. * Description:
  1020. *
  1021. *
  1022. *****************************************************************************/
  1023. HRESULT CWbemThreadSecurityHandle :: CloneProcessContext ()
  1024. {
  1025. HRESULT t_Result = S_OK ;
  1026. m_AuthenticationService = RPC_C_AUTHN_WINNT ;
  1027. m_AuthorizationService = RPC_C_AUTHZ_NONE ;
  1028. m_AuthenticationLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY ;
  1029. m_ServerPrincipalName = NULL ;
  1030. m_Identity = NULL ;
  1031. HANDLE t_ProcessToken = NULL ;
  1032. BOOL t_Status = OpenProcessToken (
  1033. GetCurrentProcess () ,
  1034. TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE ,
  1035. & t_ProcessToken
  1036. ) ;
  1037. if ( t_Status )
  1038. {
  1039. t_Status = DuplicateTokenEx (
  1040. t_ProcessToken,
  1041. MAXIMUM_ALLOWED ,
  1042. NULL ,
  1043. ( SECURITY_IMPERSONATION_LEVEL ) SecurityImpersonation ,
  1044. TokenImpersonation ,
  1045. & m_ThreadToken
  1046. ) ;
  1047. if ( t_Status )
  1048. {
  1049. // This is the basic process thread.
  1050. // =================================
  1051. m_ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE ;
  1052. t_Result = S_OK ;
  1053. }
  1054. else
  1055. {
  1056. // Unknown error
  1057. // =============
  1058. m_ImpersonationLevel = 0 ;
  1059. t_Result = E_FAIL ;
  1060. }
  1061. CloseHandle ( t_ProcessToken ) ;
  1062. }
  1063. else
  1064. {
  1065. // Unknown error
  1066. // =============
  1067. m_ImpersonationLevel = 0 ;
  1068. t_Result = E_FAIL ;
  1069. }
  1070. return t_Result ;
  1071. }
  1072. /******************************************************************************
  1073. *
  1074. * Name:
  1075. *
  1076. *
  1077. * Description:
  1078. *
  1079. *
  1080. *****************************************************************************/
  1081. CWbemThreadSecurityHandle *CWbemThreadSecurityHandle :: New ()
  1082. {
  1083. return new CWbemThreadSecurityHandle ( NULL ) ;
  1084. }
  1085. /******************************************************************************
  1086. *
  1087. * Name:
  1088. *
  1089. *
  1090. * Description:
  1091. *
  1092. *
  1093. *****************************************************************************/
  1094. CWbemCallSecurity :: CWbemCallSecurity (
  1095. CLifeControl *a_Control
  1096. ) : m_ReferenceCount ( 0 ) ,
  1097. m_ImpersonationLevel ( 0 ) ,
  1098. m_ThreadSecurityHandle ( NULL ) ,
  1099. m_ThreadToken ( NULL ) ,
  1100. m_Control ( a_Control )
  1101. {
  1102. if ( m_Control )
  1103. {
  1104. m_Control->ObjectCreated ( ( IServerSecurity * ) this ) ;
  1105. }
  1106. }
  1107. /******************************************************************************
  1108. *
  1109. * Name:
  1110. *
  1111. *
  1112. * Description:
  1113. *
  1114. *
  1115. *****************************************************************************/
  1116. CWbemCallSecurity :: ~CWbemCallSecurity ()
  1117. {
  1118. if ( m_ThreadToken )
  1119. {
  1120. CloseHandle ( m_ThreadToken ) ;
  1121. }
  1122. if ( m_ThreadSecurityHandle )
  1123. {
  1124. m_ThreadSecurityHandle->Release () ;
  1125. }
  1126. if ( m_Control )
  1127. {
  1128. m_Control->ObjectDestroyed ( ( IServerSecurity * ) this ) ;
  1129. }
  1130. }
  1131. /******************************************************************************
  1132. *
  1133. * Name:
  1134. *
  1135. *
  1136. * Description:
  1137. *
  1138. *
  1139. *****************************************************************************/
  1140. CWbemCallSecurity &CWbemCallSecurity :: operator= ( const CWbemCallSecurity &a_Copy )
  1141. {
  1142. if ( m_ThreadSecurityHandle )
  1143. {
  1144. m_ThreadSecurityHandle->Release () ;
  1145. m_ThreadSecurityHandle = NULL ;
  1146. }
  1147. if ( a_Copy.m_Control )
  1148. {
  1149. m_Control = a_Copy.m_Control ;
  1150. if ( m_Control )
  1151. {
  1152. m_Control->ObjectCreated ( ( IServerSecurity * ) this ) ;
  1153. }
  1154. }
  1155. if ( a_Copy.m_ThreadSecurityHandle )
  1156. {
  1157. m_ThreadSecurityHandle = new CWbemThreadSecurityHandle ( * ( a_Copy.m_ThreadSecurityHandle ) ) ;
  1158. }
  1159. m_ImpersonationLevel = a_Copy.m_ImpersonationLevel ;
  1160. m_ReferenceCount = 1 ;
  1161. return *this ;
  1162. }
  1163. /******************************************************************************
  1164. *
  1165. * Name:
  1166. *
  1167. *
  1168. * Description:
  1169. *
  1170. *
  1171. *****************************************************************************/
  1172. ULONG CWbemCallSecurity :: AddRef ()
  1173. {
  1174. return InterlockedIncrement ( & m_ReferenceCount ) ;
  1175. }
  1176. /******************************************************************************
  1177. *
  1178. * Name:
  1179. *
  1180. *
  1181. * Description:
  1182. *
  1183. *
  1184. *****************************************************************************/
  1185. ULONG CWbemCallSecurity :: Release ()
  1186. {
  1187. LONG t_ReferenceCount = InterlockedDecrement( & m_ReferenceCount ) ;
  1188. if ( t_ReferenceCount == 0 )
  1189. {
  1190. delete this ;
  1191. }
  1192. return t_ReferenceCount ;
  1193. }
  1194. /******************************************************************************
  1195. *
  1196. * Name:
  1197. *
  1198. *
  1199. * Description:
  1200. *
  1201. *
  1202. *****************************************************************************/
  1203. HRESULT CWbemCallSecurity :: QueryInterface ( REFIID a_Riid , void **a_Void )
  1204. {
  1205. if ( a_Riid == IID_IUnknown )
  1206. {
  1207. *a_Void = ( void ** ) this ;
  1208. AddRef () ;
  1209. return S_OK ;
  1210. }
  1211. else if ( a_Riid == IID_IServerSecurity )
  1212. {
  1213. *a_Void = ( void ** ) ( IServerSecurity * ) this ;
  1214. AddRef () ;
  1215. return S_OK ;
  1216. }
  1217. else if ( a_Riid == IID_CWbemCallSecurity )
  1218. {
  1219. *a_Void = ( void ** ) ( CWbemCallSecurity * ) this ;
  1220. AddRef () ;
  1221. return S_OK ;
  1222. }
  1223. else if ( a_Riid == IID__IWmiCallSec )
  1224. {
  1225. *a_Void = ( void ** ) ( _IWmiCallSec *) this ;
  1226. AddRef () ;
  1227. return S_OK ;
  1228. }
  1229. else
  1230. {
  1231. return E_NOINTERFACE ;
  1232. }
  1233. }
  1234. /******************************************************************************
  1235. *
  1236. * Name:
  1237. *
  1238. *
  1239. * Description:
  1240. *
  1241. *
  1242. *****************************************************************************/
  1243. HRESULT CWbemCallSecurity :: QueryBlanket (
  1244. DWORD *a_AuthenticationService ,
  1245. DWORD *a_AuthorizationService ,
  1246. OLECHAR **a_ServerPrincipalName ,
  1247. DWORD *a_AuthenticationLevel ,
  1248. DWORD *a_ImpersonationLevel ,
  1249. void **a_Privileges ,
  1250. DWORD *a_Capabilities
  1251. )
  1252. {
  1253. if ( m_ThreadSecurityHandle )
  1254. {
  1255. if ( m_ThreadSecurityHandle->GetImpersonationLevel () == 0 )
  1256. {
  1257. return E_FAIL ;
  1258. }
  1259. if ( a_AuthenticationService )
  1260. {
  1261. *a_AuthenticationService = m_ThreadSecurityHandle->GetAuthenticationService () ;
  1262. }
  1263. if ( a_AuthorizationService )
  1264. {
  1265. *a_AuthorizationService = m_ThreadSecurityHandle->GetAuthorizationService () ;
  1266. }
  1267. if ( a_ImpersonationLevel )
  1268. {
  1269. *a_ImpersonationLevel = m_ThreadSecurityHandle->GetImpersonationLevel () ;
  1270. }
  1271. if ( a_AuthenticationLevel )
  1272. {
  1273. *a_AuthenticationLevel = m_ThreadSecurityHandle->GetAuthenticationLevel () ;
  1274. }
  1275. if ( a_ServerPrincipalName )
  1276. {
  1277. *a_ServerPrincipalName = 0 ;
  1278. if ( m_ThreadSecurityHandle->GetServerPrincipalName () )
  1279. {
  1280. *a_ServerPrincipalName = ( LPWSTR ) CoTaskMemAlloc ( ( wcslen ( m_ThreadSecurityHandle->GetServerPrincipalName () ) + 1 ) * 2 ) ;
  1281. if ( a_ServerPrincipalName )
  1282. {
  1283. StringCchCopyW ( *a_ServerPrincipalName , wcslen ( m_ThreadSecurityHandle->GetServerPrincipalName () ) + 1, m_ThreadSecurityHandle->GetServerPrincipalName () ) ;
  1284. }
  1285. else
  1286. {
  1287. return E_OUTOFMEMORY ;
  1288. }
  1289. }
  1290. }
  1291. if ( a_Privileges )
  1292. {
  1293. *a_Privileges = m_ThreadSecurityHandle->GetIdentity () ; // Documented to point to an internal!!
  1294. }
  1295. }
  1296. else
  1297. {
  1298. return ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  1299. }
  1300. return S_OK;
  1301. }
  1302. /******************************************************************************
  1303. *
  1304. * Name:
  1305. *
  1306. *
  1307. * Description:
  1308. *
  1309. *
  1310. *****************************************************************************/
  1311. HRESULT CWbemCallSecurity :: ImpersonateClient ()
  1312. {
  1313. if ( m_ImpersonationLevel != 0 )
  1314. {
  1315. return S_OK ;
  1316. }
  1317. else
  1318. {
  1319. if ( m_ThreadSecurityHandle )
  1320. {
  1321. if ( m_ThreadSecurityHandle->GetImpersonationLevel () == 0 )
  1322. {
  1323. return ( ERROR_CANT_OPEN_ANONYMOUS | 0x80070000 ) ;
  1324. }
  1325. BOOL t_Status = OpenThreadToken (
  1326. GetCurrentThread () ,
  1327. TOKEN_IMPERSONATE ,
  1328. TRUE ,
  1329. & m_ThreadToken
  1330. ) ;
  1331. if ( t_Status == FALSE )
  1332. {
  1333. DWORD t_LastError = GetLastError () ;
  1334. if ( ( t_LastError == ERROR_NO_IMPERSONATION_TOKEN || t_LastError == ERROR_NO_TOKEN ) )
  1335. {
  1336. }
  1337. else
  1338. {
  1339. return ( ERROR_ACCESS_DENIED | 0x80070000 ) ;
  1340. }
  1341. }
  1342. t_Status = SetThreadToken ( NULL , m_ThreadSecurityHandle->GetThreadToken () ) ;
  1343. if ( t_Status )
  1344. {
  1345. m_ImpersonationLevel = m_ThreadSecurityHandle->GetImpersonationLevel () ;
  1346. return S_OK ;
  1347. }
  1348. else
  1349. {
  1350. CloseHandle ( m_ThreadToken ) ;
  1351. m_ThreadToken = NULL ;
  1352. }
  1353. }
  1354. else
  1355. {
  1356. return ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  1357. }
  1358. }
  1359. return E_FAIL ;
  1360. }
  1361. /******************************************************************************
  1362. *
  1363. * Name:
  1364. *
  1365. *
  1366. * Description:
  1367. *
  1368. *
  1369. *****************************************************************************/
  1370. HRESULT CWbemCallSecurity :: RevertToSelf ()
  1371. {
  1372. if ( m_ImpersonationLevel == 0 )
  1373. {
  1374. return S_OK ;
  1375. }
  1376. else
  1377. {
  1378. if ( m_ThreadSecurityHandle )
  1379. {
  1380. // If here,we are impersonating and can definitely revert.
  1381. // =======================================================
  1382. BOOL t_Status = SetThreadToken ( NULL , m_ThreadToken ) ;
  1383. if ( t_Status == FALSE )
  1384. {
  1385. return ( GetLastError () | 0x80070000 ) ;
  1386. }
  1387. CloseHandle ( m_ThreadToken ) ;
  1388. m_ThreadToken = NULL ;
  1389. m_ImpersonationLevel = 0 ;
  1390. }
  1391. else
  1392. {
  1393. return ( ERROR_INVALID_HANDLE | 0x80070000 ) ;
  1394. }
  1395. }
  1396. return S_OK ;
  1397. }
  1398. /******************************************************************************
  1399. *
  1400. * Name:
  1401. *
  1402. *
  1403. * Description:
  1404. *
  1405. *
  1406. *****************************************************************************/
  1407. BOOL CWbemCallSecurity :: IsImpersonating ()
  1408. {
  1409. if ( m_ImpersonationLevel != 0 )
  1410. {
  1411. return TRUE ;
  1412. }
  1413. return FALSE ;
  1414. }
  1415. /******************************************************************************
  1416. *
  1417. * Name:
  1418. *
  1419. *
  1420. * Description:
  1421. *
  1422. *
  1423. *****************************************************************************/
  1424. HRESULT CWbemCallSecurity :: GetThreadSecurity (
  1425. WMI_THREAD_SECURITY_ORIGIN a_Origin ,
  1426. _IWmiThreadSecHandle **a_ThreadSecurity
  1427. )
  1428. {
  1429. HRESULT t_Result = S_OK ;
  1430. BOOL t_ValidOrigin = ( ( a_Origin & WMI_ORIGIN_THREAD ) || ( a_Origin & WMI_ORIGIN_EXISTING ) || ( a_Origin & WMI_ORIGIN_RPC ) ) ;
  1431. if ( a_ThreadSecurity && t_ValidOrigin )
  1432. {
  1433. if ( a_Origin & WMI_ORIGIN_THREAD )
  1434. {
  1435. *a_ThreadSecurity = new CWbemThreadSecurityHandle ( m_Control ) ;
  1436. if ( *a_ThreadSecurity )
  1437. {
  1438. ( *a_ThreadSecurity )->AddRef () ;
  1439. ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity )->SetOrigin ( WMI_ORIGIN_THREAD ) ;
  1440. t_Result = ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity)->CloneThreadContext () ;
  1441. if ( FAILED ( t_Result ) )
  1442. {
  1443. ( *a_ThreadSecurity )->Release () ;
  1444. *a_ThreadSecurity = NULL;
  1445. }
  1446. }
  1447. else
  1448. {
  1449. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1450. }
  1451. }
  1452. if ( t_Result == WBEM_E_NOT_FOUND )
  1453. {
  1454. if ( a_Origin & WMI_ORIGIN_RPC || a_Origin & WMI_ORIGIN_EXISTING )
  1455. {
  1456. // Figure out if the call context is ours or RPCs
  1457. // ==============================================
  1458. IServerSecurity *t_Security = NULL ;
  1459. t_Result = CoGetCallContext ( IID_IServerSecurity , ( void ** ) & t_Security ) ;
  1460. if ( SUCCEEDED ( t_Result ) )
  1461. {
  1462. CWbemCallSecurity *t_Internal = NULL ;
  1463. if ( SUCCEEDED ( t_Security->QueryInterface ( IID_CWbemCallSecurity , ( void ** ) & t_Internal ) ) )
  1464. {
  1465. // This is our own call context --- this must be an in-proc object
  1466. // calling us from our thread. Behave depending on the flags
  1467. // ===============================================================
  1468. if ( a_Origin & WMI_ORIGIN_EXISTING )
  1469. {
  1470. *a_ThreadSecurity = new CWbemThreadSecurityHandle ( *t_Internal->GetThreadSecurityHandle () ) ;
  1471. if ( *a_ThreadSecurity )
  1472. {
  1473. (*a_ThreadSecurity)->AddRef () ;
  1474. t_Result = S_OK ;
  1475. }
  1476. else
  1477. {
  1478. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1479. }
  1480. }
  1481. else
  1482. {
  1483. t_Result = WBEM_E_NOT_FOUND ;
  1484. }
  1485. t_Internal->Release () ;
  1486. }
  1487. else
  1488. {
  1489. t_Result = WBEM_E_NOT_FOUND ;
  1490. }
  1491. if ( t_Result == WBEM_E_NOT_FOUND )
  1492. {
  1493. if ( a_Origin & WMI_ORIGIN_RPC )
  1494. {
  1495. *a_ThreadSecurity = new CWbemThreadSecurityHandle ( m_Control ) ;
  1496. if ( *a_ThreadSecurity )
  1497. {
  1498. ( *a_ThreadSecurity )->AddRef () ;
  1499. t_Result = ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity)->CloneRpcContext (
  1500. t_Security
  1501. ) ;
  1502. if ( SUCCEEDED( t_Result ) )
  1503. {
  1504. ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity) ->SetOrigin ( WMI_ORIGIN_RPC ) ;
  1505. }
  1506. else
  1507. {
  1508. ( *a_ThreadSecurity )->Release ();
  1509. *a_ThreadSecurity = NULL;
  1510. }
  1511. }
  1512. else
  1513. {
  1514. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1515. }
  1516. }
  1517. }
  1518. t_Security->Release();
  1519. }
  1520. else
  1521. {
  1522. t_Result = WBEM_E_NOT_FOUND ;
  1523. }
  1524. if ( t_Result == WBEM_E_NOT_FOUND )
  1525. {
  1526. if ( a_Origin & WMI_ORIGIN_THREAD )
  1527. {
  1528. *a_ThreadSecurity = new CWbemThreadSecurityHandle ( m_Control ) ;
  1529. if ( *a_ThreadSecurity )
  1530. {
  1531. ( *a_ThreadSecurity )->AddRef () ;
  1532. ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity )->SetOrigin ( WMI_ORIGIN_THREAD ) ;
  1533. t_Result = ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity)->CloneProcessContext () ;
  1534. }
  1535. else
  1536. {
  1537. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1538. }
  1539. }
  1540. }
  1541. }
  1542. else
  1543. {
  1544. if ( a_Origin & WMI_ORIGIN_THREAD )
  1545. {
  1546. *a_ThreadSecurity = new CWbemThreadSecurityHandle ( m_Control ) ;
  1547. if ( *a_ThreadSecurity )
  1548. {
  1549. ( *a_ThreadSecurity )->AddRef () ;
  1550. ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity )->SetOrigin ( WMI_ORIGIN_THREAD ) ;
  1551. t_Result = ( ( CWbemThreadSecurityHandle * ) *a_ThreadSecurity)->CloneProcessContext () ;
  1552. }
  1553. else
  1554. {
  1555. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1556. }
  1557. }
  1558. }
  1559. }
  1560. }
  1561. else
  1562. {
  1563. t_Result = WBEM_E_INVALID_PARAMETER ;
  1564. }
  1565. return t_Result ;
  1566. }
  1567. /******************************************************************************
  1568. *
  1569. * Name:
  1570. *
  1571. *
  1572. * Description:
  1573. *
  1574. *
  1575. *****************************************************************************/
  1576. HRESULT CWbemCallSecurity :: SetThreadSecurity (
  1577. _IWmiThreadSecHandle *a_ThreadSecurity
  1578. )
  1579. {
  1580. HRESULT t_Result = S_OK ;
  1581. if ( m_ThreadSecurityHandle )
  1582. {
  1583. m_ThreadSecurityHandle->Release () ;
  1584. m_ThreadSecurityHandle = NULL ;
  1585. }
  1586. if ( a_ThreadSecurity )
  1587. {
  1588. CWbemThreadSecurityHandle *t_ThreadHandle = NULL ;
  1589. t_Result = a_ThreadSecurity->QueryInterface ( IID_CWbemThreadSecurityHandle , ( void ** ) & t_ThreadHandle ) ;
  1590. if ( SUCCEEDED ( t_Result ) )
  1591. {
  1592. m_ThreadSecurityHandle = t_ThreadHandle ;
  1593. IUnknown *t_Unknown = NULL ;
  1594. IUnknown *t_SwitchUnknown = NULL ;
  1595. t_Result = this->QueryInterface ( IID_IUnknown , ( void **) & t_SwitchUnknown ) ;
  1596. if ( SUCCEEDED ( t_Result ) )
  1597. {
  1598. t_Result = CoSwitchCallContext ( t_SwitchUnknown, & t_Unknown ) ;
  1599. t_SwitchUnknown->Release () ;
  1600. }
  1601. }
  1602. }
  1603. return t_Result ;
  1604. }
  1605. /******************************************************************************
  1606. *
  1607. * Name:
  1608. *
  1609. *
  1610. * Description:
  1611. *
  1612. *
  1613. *****************************************************************************/
  1614. HRESULT CWbemCallSecurity :: GetUser (
  1615. ULONG *a_Size ,
  1616. LPWSTR a_Buffer
  1617. )
  1618. {
  1619. HRESULT t_Result = S_OK ;
  1620. HANDLE t_Token = NULL ;
  1621. BOOL t_Status = OpenThreadToken (
  1622. GetCurrentThread() ,
  1623. TOKEN_QUERY,
  1624. TRUE ,
  1625. & t_Token
  1626. ) ;
  1627. DWORD t_LastError = GetLastError () ;
  1628. if ( ! t_Status && ( t_LastError == ERROR_NO_IMPERSONATION_TOKEN || t_LastError == ERROR_NO_TOKEN ) )
  1629. {
  1630. t_Status = OpenProcessToken (
  1631. GetCurrentProcess() ,
  1632. TOKEN_QUERY,
  1633. & t_Token
  1634. ) ;
  1635. if ( ! t_Status )
  1636. {
  1637. t_Result = WBEM_E_ACCESS_DENIED ;
  1638. }
  1639. }
  1640. else
  1641. {
  1642. if ( ! t_Status )
  1643. {
  1644. t_Result = WBEM_E_ACCESS_DENIED ;
  1645. }
  1646. }
  1647. if ( t_Status )
  1648. {
  1649. t_Result = :: GetUser ( t_Token , a_Size , a_Buffer ) ;
  1650. CloseHandle ( t_Token ) ;
  1651. }
  1652. return t_Result ;
  1653. }
  1654. /******************************************************************************
  1655. *
  1656. * Name:
  1657. *
  1658. *
  1659. * Description:
  1660. *
  1661. *
  1662. *****************************************************************************/
  1663. HRESULT CWbemCallSecurity :: GetUserSid (
  1664. ULONG *a_Size ,
  1665. PSID a_Sid
  1666. )
  1667. {
  1668. HRESULT t_Result = S_OK ;
  1669. HANDLE t_Token = NULL ;
  1670. BOOL t_Status = OpenThreadToken (
  1671. GetCurrentThread () ,
  1672. TOKEN_QUERY,
  1673. TRUE ,
  1674. & t_Token
  1675. ) ;
  1676. DWORD t_LastError = GetLastError () ;
  1677. if ( ! t_Status && ( t_LastError == ERROR_NO_IMPERSONATION_TOKEN || t_LastError == ERROR_NO_TOKEN ) )
  1678. {
  1679. t_Status = OpenProcessToken (
  1680. GetCurrentProcess () ,
  1681. TOKEN_QUERY,
  1682. & t_Token
  1683. ) ;
  1684. if ( ! t_Status )
  1685. {
  1686. t_Result = WBEM_E_ACCESS_DENIED ;
  1687. }
  1688. }
  1689. else
  1690. {
  1691. if ( ! t_Status )
  1692. {
  1693. t_Result = WBEM_E_ACCESS_DENIED ;
  1694. }
  1695. }
  1696. if ( t_Status )
  1697. {
  1698. t_Result = :: GetUserSid ( t_Token , a_Size , a_Sid ) ;
  1699. CloseHandle ( t_Token ) ;
  1700. }
  1701. return t_Result ;
  1702. }
  1703. /******************************************************************************
  1704. *
  1705. * Name:
  1706. *
  1707. *
  1708. * Description:
  1709. *
  1710. *
  1711. *****************************************************************************/
  1712. HRESULT CWbemCallSecurity :: GetAuthenticationLuid ( LPVOID a_Luid )
  1713. {
  1714. HRESULT t_Result = S_OK ;
  1715. HANDLE t_Token = NULL ;
  1716. BOOL t_Status = OpenThreadToken (
  1717. GetCurrentThread () ,
  1718. TOKEN_QUERY,
  1719. TRUE ,
  1720. & t_Token
  1721. ) ;
  1722. DWORD t_LastError = GetLastError () ;
  1723. if ( ! t_Status && ( t_LastError == ERROR_NO_IMPERSONATION_TOKEN || t_LastError == ERROR_NO_TOKEN ) )
  1724. {
  1725. t_Status = OpenProcessToken (
  1726. GetCurrentProcess () ,
  1727. TOKEN_QUERY,
  1728. & t_Token
  1729. ) ;
  1730. if ( ! t_Status )
  1731. {
  1732. t_Result = WBEM_E_ACCESS_DENIED ;
  1733. }
  1734. }
  1735. else
  1736. {
  1737. if ( ! t_Status )
  1738. {
  1739. t_Result = WBEM_E_ACCESS_DENIED ;
  1740. }
  1741. }
  1742. if ( t_Status )
  1743. {
  1744. t_Result = :: GetAuthenticationLuid ( t_Token , a_Luid ) ;
  1745. CloseHandle ( t_Token ) ;
  1746. }
  1747. return t_Result ;
  1748. }
  1749. /******************************************************************************
  1750. *
  1751. * Name:
  1752. *
  1753. *
  1754. * Description:
  1755. *
  1756. *
  1757. *****************************************************************************/
  1758. HRESULT CWbemCallSecurity :: GetImpersonation ( DWORD *a_Level )
  1759. {
  1760. HRESULT t_Result = S_OK ;
  1761. if ( a_Level )
  1762. {
  1763. HANDLE t_Token = NULL ;
  1764. BOOL t_Status = OpenThreadToken (
  1765. GetCurrentThread () ,
  1766. TOKEN_QUERY,
  1767. TRUE ,
  1768. & t_Token
  1769. ) ;
  1770. DWORD t_LastError = GetLastError () ;
  1771. if ( ! t_Status && ( t_LastError == ERROR_NO_IMPERSONATION_TOKEN || t_LastError == ERROR_NO_TOKEN ) )
  1772. {
  1773. *a_Level = 0 ;
  1774. }
  1775. else
  1776. {
  1777. if ( t_Status )
  1778. {
  1779. SECURITY_IMPERSONATION_LEVEL t_ImpersonationLevel = SecurityAnonymous ;
  1780. TOKEN_TYPE t_TokenType = TokenImpersonation ;
  1781. t_Result = :: GetImpersonationLevel (
  1782. t_Token ,
  1783. t_ImpersonationLevel ,
  1784. t_TokenType
  1785. ) ;
  1786. if ( SUCCEEDED ( t_Result ) )
  1787. {
  1788. switch ( t_ImpersonationLevel )
  1789. {
  1790. case SecurityAnonymous:
  1791. {
  1792. *a_Level = RPC_C_IMP_LEVEL_ANONYMOUS ;
  1793. }
  1794. break ;
  1795. case SecurityIdentification:
  1796. {
  1797. *a_Level = RPC_C_IMP_LEVEL_IDENTIFY ;
  1798. }
  1799. break ;
  1800. case SecurityImpersonation:
  1801. {
  1802. *a_Level = RPC_C_IMP_LEVEL_IMPERSONATE ;
  1803. }
  1804. break ;
  1805. case SecurityDelegation:
  1806. {
  1807. *a_Level = RPC_C_IMP_LEVEL_DELEGATE ;
  1808. }
  1809. break ;
  1810. default:
  1811. {
  1812. *a_Level = 0 ;
  1813. }
  1814. break ;
  1815. }
  1816. }
  1817. CloseHandle ( t_Token ) ;
  1818. }
  1819. else
  1820. {
  1821. t_Result = WBEM_E_ACCESS_DENIED ;
  1822. }
  1823. }
  1824. }
  1825. return t_Result ;
  1826. }
  1827. /******************************************************************************
  1828. *
  1829. * Name:
  1830. *
  1831. *
  1832. * Description:
  1833. *
  1834. *
  1835. *****************************************************************************/
  1836. HRESULT CWbemCallSecurity :: GetAuthentication (
  1837. DWORD *a_Level
  1838. )
  1839. {
  1840. HRESULT t_Result = S_OK ;
  1841. if ( a_Level )
  1842. {
  1843. if ( m_ThreadSecurityHandle )
  1844. {
  1845. *a_Level = m_ThreadSecurityHandle->GetAuthenticationLevel () ;
  1846. }
  1847. else
  1848. {
  1849. t_Result = WBEM_E_NOT_FOUND ;
  1850. }
  1851. }
  1852. else
  1853. {
  1854. t_Result = WBEM_E_INVALID_PARAMETER ;
  1855. }
  1856. return t_Result ;
  1857. }
  1858. /******************************************************************************
  1859. *
  1860. * Name:
  1861. *
  1862. *
  1863. * Description:
  1864. *
  1865. *
  1866. *****************************************************************************/
  1867. CWbemCallSecurity *CWbemCallSecurity :: New ()
  1868. {
  1869. return new CWbemCallSecurity ( NULL ) ;
  1870. }