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.

2230 lines
56 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation
  4. //
  5. // SECURITY.CPP
  6. //
  7. // alanbos 28-Jun-98 Created.
  8. //
  9. // Defines the implementation of CSWbemSecurity
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. // Used to protect security calls
  14. extern CRITICAL_SECTION g_csSecurity;
  15. bool CSWbemSecurity::s_bInitialized = false;
  16. bool CSWbemSecurity::s_bIsNT = false;
  17. DWORD CSWbemSecurity::s_dwNTMajorVersion = 0;
  18. HINSTANCE CSWbemSecurity::s_hAdvapi = NULL;
  19. bool CSWbemSecurity::s_bCanRevert = false;
  20. WbemImpersonationLevelEnum CSWbemSecurity::s_dwDefaultImpersonationLevel
  21. = wbemImpersonationLevelIdentify;
  22. // Declarations for function pointers that won't exist on Win9x
  23. BOOL (STDAPICALLTYPE *s_pfnDuplicateTokenEx) (
  24. HANDLE,
  25. DWORD,
  26. LPSECURITY_ATTRIBUTES,
  27. SECURITY_IMPERSONATION_LEVEL,
  28. TOKEN_TYPE,
  29. PHANDLE
  30. ) = NULL;
  31. //***************************************************************************
  32. //
  33. // SCODE CSWbemSecurity::Initialize
  34. //
  35. // DESCRIPTION:
  36. //
  37. // This static function is caused on DLL attachment to the process; it
  38. // sets up the function pointers for advanced API privilege functions.
  39. // On Win9x these functions are not supported which is why we need to
  40. // indirect through GetProcAddress.
  41. //
  42. //***************************************************************************
  43. void CSWbemSecurity::Initialize ()
  44. {
  45. EnterCriticalSection (&g_csSecurity);
  46. if (!s_bInitialized)
  47. {
  48. // Get OS info
  49. OSVERSIONINFO osVersionInfo;
  50. osVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  51. GetVersionEx (&osVersionInfo);
  52. s_bIsNT = (VER_PLATFORM_WIN32_NT == osVersionInfo.dwPlatformId);
  53. s_dwNTMajorVersion = osVersionInfo.dwMajorVersion;
  54. if (s_bIsNT)
  55. {
  56. HKEY hKey;
  57. // Security values are relevant for NT only - for Win9x leave as default
  58. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  59. WBEMS_RK_SCRIPTING, 0, KEY_QUERY_VALUE, &hKey))
  60. {
  61. DWORD dwDummy = 0;
  62. // Get revert flag value from registry - NT 4.0 or less only
  63. if (s_dwNTMajorVersion <= 4)
  64. {
  65. DWORD dwEnableForAsp = 0;
  66. dwDummy = sizeof (dwEnableForAsp);
  67. if (ERROR_SUCCESS == RegQueryValueEx (hKey, WBEMS_RV_ENABLEFORASP,
  68. NULL, NULL, (BYTE *) &dwEnableForAsp, &dwDummy))
  69. s_bCanRevert = (0 != dwEnableForAsp);
  70. }
  71. // Get default impersonation level from registry
  72. DWORD dwImpLevel = 0;
  73. dwDummy = sizeof (dwImpLevel);
  74. if (ERROR_SUCCESS == RegQueryValueEx (hKey, WBEMS_RV_DEFAULTIMPLEVEL,
  75. NULL, NULL, (BYTE *) &dwImpLevel, &dwDummy))
  76. s_dwDefaultImpersonationLevel = (WbemImpersonationLevelEnum) dwImpLevel;
  77. RegCloseKey (hKey);
  78. }
  79. // Set up security function pointers for NT
  80. if (!s_hAdvapi)
  81. {
  82. TCHAR dllName [] = _T("\\advapi32.dll");
  83. LPTSTR pszSysDir = new TCHAR[ MAX_PATH + _tcslen (dllName) + 1];
  84. if (pszSysDir)
  85. {
  86. pszSysDir[0] = NULL;
  87. UINT uSize = GetSystemDirectory(pszSysDir, MAX_PATH);
  88. if(uSize > MAX_PATH) {
  89. delete[] pszSysDir;
  90. pszSysDir = new TCHAR[ uSize + _tcslen (dllName) + 1];
  91. if (pszSysDir)
  92. {
  93. pszSysDir[0] = NULL;
  94. uSize = GetSystemDirectory(pszSysDir, uSize);
  95. }
  96. }
  97. if (pszSysDir)
  98. {
  99. _tcscat (pszSysDir, dllName);
  100. s_hAdvapi = LoadLibraryEx (pszSysDir, NULL, 0);
  101. if (s_hAdvapi)
  102. (FARPROC&) s_pfnDuplicateTokenEx = GetProcAddress(s_hAdvapi, "DuplicateTokenEx");
  103. delete [] pszSysDir;
  104. }
  105. }
  106. }
  107. }
  108. s_bInitialized = true;
  109. }
  110. LeaveCriticalSection (&g_csSecurity);
  111. }
  112. //***************************************************************************
  113. //
  114. // SCODE CSWbemSecurity::Uninitialize
  115. //
  116. // DESCRIPTION:
  117. //
  118. // This static function is caused on DLL detachment to the process; it
  119. // unloads the API loaded by Initialize (above) to obtain function pointers.
  120. //
  121. //***************************************************************************
  122. void CSWbemSecurity::Uninitialize ()
  123. {
  124. EnterCriticalSection (&g_csSecurity);
  125. if (s_hAdvapi)
  126. {
  127. s_pfnDuplicateTokenEx = NULL;
  128. FreeLibrary (s_hAdvapi);
  129. s_hAdvapi = NULL;
  130. s_bInitialized = false;
  131. }
  132. LeaveCriticalSection (&g_csSecurity);
  133. }
  134. //***************************************************************************
  135. //
  136. // SCODE CSWbemSecurity::LookupPrivilegeValue
  137. //
  138. // DESCRIPTION:
  139. //
  140. // This static function wraps the Win32 LookupPrivilegeValue function,
  141. // allowing us to do some OS-dependent stuff.
  142. //
  143. // PARAMETERS:
  144. //
  145. // lpName the privilege name
  146. // lpLuid holds the LUID on successful return
  147. //
  148. // RETURN VALUES:
  149. //
  150. // true On NT this means we found the privilege. On Win9x we
  151. // always return this.
  152. //
  153. // false On NT this means the privilege is not recognized. This
  154. // is never returned on Win9x.
  155. //
  156. //***************************************************************************
  157. BOOL CSWbemSecurity::LookupPrivilegeValue (
  158. LPCTSTR lpName,
  159. PLUID lpLuid
  160. )
  161. {
  162. // Allows any name to map to 0 LUID on Win9x - this aids script portability
  163. if (IsNT ())
  164. return ::LookupPrivilegeValue(NULL, lpName, lpLuid);
  165. else
  166. return true;
  167. }
  168. //***************************************************************************
  169. //
  170. // SCODE CSWbemSecurity::LookupPrivilegeDisplayName
  171. //
  172. // DESCRIPTION:
  173. //
  174. // This static function wraps the Win32 LookupPrivilegeDisplayName function,
  175. // allowing us to do some OS-dependent stuff.
  176. //
  177. // PARAMETERS:
  178. //
  179. // tName the privilege name
  180. // pDisplayName holds the display name on successful return
  181. //
  182. //***************************************************************************
  183. void CSWbemSecurity::LookupPrivilegeDisplayName (LPCTSTR lpName, BSTR *pDisplayName)
  184. {
  185. if (pDisplayName)
  186. {
  187. // Can't return display name on Win9x (no privilege support)
  188. if (IsNT ())
  189. {
  190. DWORD dwLangID;
  191. DWORD dwSize = 1;
  192. TCHAR dummy [1];
  193. // Get size of required buffer
  194. ::LookupPrivilegeDisplayName (NULL, lpName, dummy, &dwSize, &dwLangID);
  195. LPTSTR dname = new TCHAR[dwSize + 1];
  196. if (dname)
  197. {
  198. if (::LookupPrivilegeDisplayName (_T(""), lpName, dname, &dwSize, &dwLangID))
  199. {
  200. // Have a valid name - now copy it to a BSTR
  201. #ifdef _UNICODE
  202. *pDisplayName = SysAllocString (dname);
  203. #else
  204. size_t dnameLen = strlen (dname);
  205. OLECHAR *nameW = new OLECHAR [dnameLen + 1];
  206. if (nameW)
  207. {
  208. mbstowcs (nameW, dname, dnameLen);
  209. nameW [dnameLen] = NULL;
  210. *pDisplayName = SysAllocString (nameW);
  211. delete [] nameW;
  212. }
  213. #endif
  214. }
  215. delete [] dname;
  216. }
  217. }
  218. // If we failed, just set an empty string
  219. if (!(*pDisplayName))
  220. *pDisplayName = SysAllocString (L"");
  221. }
  222. }
  223. //***************************************************************************
  224. //
  225. // CSWbemSecurity::CSWbemSecurity
  226. //
  227. // CONSTRUCTOR
  228. // This form of the constructor is used for securing a new WBEM
  229. // remoted interface where no previous security has been applied.
  230. // It is only used to secure IWbemServices interfaces.
  231. // Note that the Locator may have security settings so these are
  232. // transferred if present.
  233. //
  234. //***************************************************************************
  235. CSWbemSecurity::CSWbemSecurity (
  236. IUnknown *pUnk,
  237. BSTR bsAuthority ,
  238. BSTR bsUser,
  239. BSTR bsPassword,
  240. CWbemLocatorSecurity *pLocatorSecurity) :
  241. m_pPrivilegeSet (NULL),
  242. m_pProxyCache (NULL),
  243. m_pCurProxy (NULL)
  244. {
  245. m_Dispatch.SetObj (this, IID_ISWbemSecurity,
  246. CLSID_SWbemSecurity, L"SWbemSecurity");
  247. m_cRef=1;
  248. m_pProxyCache = new CSWbemProxyCache (pUnk, bsAuthority,
  249. bsUser, bsPassword, pLocatorSecurity);
  250. if (m_pProxyCache)
  251. m_pCurProxy = m_pProxyCache->GetInitialProxy ();
  252. if (pLocatorSecurity)
  253. {
  254. // Clone the privilege set
  255. CSWbemPrivilegeSet *pPrivilegeSet = pLocatorSecurity->GetPrivilegeSet ();
  256. if (pPrivilegeSet)
  257. {
  258. m_pPrivilegeSet = new CSWbemPrivilegeSet (*pPrivilegeSet);
  259. pPrivilegeSet->Release ();
  260. }
  261. }
  262. else
  263. {
  264. // Create a new privilege set
  265. m_pPrivilegeSet = new CSWbemPrivilegeSet;
  266. }
  267. InterlockedIncrement(&g_cObj);
  268. }
  269. //***************************************************************************
  270. //
  271. // CSWbemSecurity::CSWbemSecurity
  272. //
  273. // CONSTRUCTOR
  274. // This form of the constructor is used for securing a new WBEM
  275. // remoted interface where no previous security has been applied,
  276. // and where the user credentials are expressed in the form of an
  277. // encrypted COAUTHIDENTITY plus principal and authority.
  278. // It is only used to secure IWbemServices interfaces.
  279. //
  280. //***************************************************************************
  281. CSWbemSecurity::CSWbemSecurity (
  282. IUnknown *pUnk,
  283. COAUTHIDENTITY *pCoAuthIdentity,
  284. BSTR bsPrincipal,
  285. BSTR bsAuthority) :
  286. m_pPrivilegeSet (NULL),
  287. m_pProxyCache (NULL),
  288. m_pCurProxy (NULL)
  289. {
  290. m_Dispatch.SetObj (this, IID_ISWbemSecurity,
  291. CLSID_SWbemSecurity, L"SWbemSecurity");
  292. m_cRef=1;
  293. m_pProxyCache = new CSWbemProxyCache (pUnk, pCoAuthIdentity,
  294. bsPrincipal, bsAuthority);
  295. if (m_pProxyCache)
  296. m_pCurProxy = m_pProxyCache->GetInitialProxy ();
  297. // Create a new privilege set
  298. m_pPrivilegeSet = new CSWbemPrivilegeSet;
  299. InterlockedIncrement(&g_cObj);
  300. }
  301. //***************************************************************************
  302. //
  303. // CSWbemSecurity::CSWbemSecurity
  304. //
  305. // CONSTRUCTOR
  306. // This form of the constructor is used for securing a new WBEM interface
  307. // non-remoted interface using the security attributes attached to another
  308. // (already secured) remoted interface; a non-remoted interface is secured
  309. // by virtue of securing a new proxy on an underlying remoted interface.
  310. // It is used to "secure" an ISWbemObjectEx interface using the security
  311. // settings of an IWbemServices interface.
  312. //
  313. //***************************************************************************
  314. CSWbemSecurity::CSWbemSecurity (
  315. CSWbemSecurity *pSecurity) :
  316. m_pPrivilegeSet (NULL),
  317. m_pProxyCache (NULL),
  318. m_pCurProxy (NULL)
  319. {
  320. m_Dispatch.SetObj (this, IID_ISWbemSecurity,
  321. CLSID_SWbemSecurity, L"SWbemSecurity");
  322. m_cRef=1;
  323. // Clone the privilege set
  324. if (pSecurity)
  325. {
  326. CSWbemPrivilegeSet *pPrivilegeSet = pSecurity->GetPrivilegeSet ();
  327. if (pPrivilegeSet)
  328. {
  329. m_pPrivilegeSet = new CSWbemPrivilegeSet (*pPrivilegeSet);
  330. pPrivilegeSet->Release ();
  331. }
  332. else
  333. {
  334. // Create a new one
  335. m_pPrivilegeSet = new CSWbemPrivilegeSet ();
  336. }
  337. m_pProxyCache = pSecurity->GetProxyCache ();
  338. m_pCurProxy = pSecurity->GetProxy ();
  339. }
  340. InterlockedIncrement(&g_cObj);
  341. }
  342. CSWbemSecurity::CSWbemSecurity (
  343. IUnknown *pUnk,
  344. ISWbemInternalSecurity *pISWbemInternalSecurity) :
  345. m_pPrivilegeSet (NULL),
  346. m_pProxyCache (NULL),
  347. m_pCurProxy (NULL)
  348. {
  349. m_Dispatch.SetObj (this, IID_ISWbemSecurity,
  350. CLSID_SWbemSecurity, L"SWbemSecurity");
  351. m_cRef=1;
  352. if (pISWbemInternalSecurity)
  353. {
  354. // Clone the privilege set
  355. ISWbemSecurity *pISWbemSecurity = NULL;
  356. if (SUCCEEDED(pISWbemInternalSecurity->QueryInterface (IID_ISWbemSecurity,
  357. (void**) &pISWbemSecurity)))
  358. {
  359. ISWbemPrivilegeSet *pISWbemPrivilegeSet = NULL;
  360. if (SUCCEEDED(pISWbemSecurity->get_Privileges (&pISWbemPrivilegeSet)))
  361. {
  362. // Build the privilege set
  363. m_pPrivilegeSet = new CSWbemPrivilegeSet (pISWbemPrivilegeSet);
  364. // Build the proxy cache
  365. BSTR bsAuthority = NULL;
  366. BSTR bsPrincipal = NULL;
  367. BSTR bsUser = NULL;
  368. BSTR bsPassword = NULL;
  369. BSTR bsDomain = NULL;
  370. pISWbemInternalSecurity->GetAuthority (&bsAuthority);
  371. pISWbemInternalSecurity->GetPrincipal (&bsPrincipal);
  372. pISWbemInternalSecurity->GetUPD (&bsUser, &bsPassword, &bsDomain);
  373. COAUTHIDENTITY *pCoAuthIdentity = NULL;
  374. // Decide if we need a COAUTHIDENTITY
  375. if ((bsUser && (0 < wcslen (bsUser))) ||
  376. (bsPassword && (0 < wcslen (bsPassword))) ||
  377. (bsDomain && (0 < wcslen (bsDomain))))
  378. WbemAllocAuthIdentity (bsUser, bsPassword, bsDomain, &pCoAuthIdentity);
  379. m_pProxyCache = new CSWbemProxyCache (pUnk, pCoAuthIdentity,
  380. bsPrincipal, bsAuthority);
  381. if (pCoAuthIdentity)
  382. WbemFreeAuthIdentity (pCoAuthIdentity);
  383. if (bsAuthority)
  384. SysFreeString (bsAuthority);
  385. if (bsPrincipal)
  386. SysFreeString (bsPrincipal);
  387. if (bsUser)
  388. SysFreeString (bsUser);
  389. if (bsPassword)
  390. SysFreeString (bsPassword);
  391. if (bsDomain)
  392. SysFreeString (bsDomain);
  393. if (m_pProxyCache)
  394. m_pCurProxy = m_pProxyCache->GetInitialProxy ();
  395. }
  396. pISWbemPrivilegeSet->Release ();
  397. }
  398. pISWbemSecurity->Release ();
  399. }
  400. InterlockedIncrement(&g_cObj);
  401. }
  402. //***************************************************************************
  403. //
  404. // CSWbemSecurity::CSWbemSecurity
  405. //
  406. // CONSTRUCTOR
  407. // This form of the constructor is used for securing a new WBEM remoted
  408. // interface interface using the security attributes attached to another
  409. // (already secured) remoted interface.
  410. // It is used to "secure" an ISWbemObjectSet interface using the security
  411. // settings of an IWbemServices interface.
  412. //
  413. //***************************************************************************
  414. CSWbemSecurity::CSWbemSecurity (
  415. IUnknown *pUnk,
  416. CSWbemSecurity *pSecurity) :
  417. m_pPrivilegeSet (NULL),
  418. m_pProxyCache (NULL),
  419. m_pCurProxy (NULL)
  420. {
  421. m_Dispatch.SetObj (this, IID_ISWbemSecurity,
  422. CLSID_SWbemSecurity, L"SWbemSecurity");
  423. m_cRef=1;
  424. InterlockedIncrement(&g_cObj);
  425. if (pSecurity)
  426. {
  427. // Clone the privilege set
  428. CSWbemPrivilegeSet *pPrivilegeSet = pSecurity->GetPrivilegeSet ();
  429. if (pPrivilegeSet)
  430. {
  431. m_pPrivilegeSet = new CSWbemPrivilegeSet (*pPrivilegeSet);
  432. pPrivilegeSet->Release ();
  433. }
  434. m_pProxyCache = new CSWbemProxyCache (pUnk, pSecurity);
  435. if (m_pProxyCache)
  436. m_pCurProxy = m_pProxyCache->GetInitialProxy ();
  437. }
  438. else
  439. {
  440. m_pPrivilegeSet = new CSWbemPrivilegeSet ();
  441. m_pProxyCache = new CSWbemProxyCache (pUnk, NULL);
  442. if (m_pProxyCache)
  443. m_pCurProxy = m_pProxyCache->GetInitialProxy ();
  444. }
  445. }
  446. //***************************************************************************
  447. //
  448. // CSWbemSecurity::~CSWbemSecurity
  449. //
  450. // DESTRUCTOR
  451. //
  452. //***************************************************************************
  453. CSWbemSecurity::~CSWbemSecurity (void)
  454. {
  455. InterlockedDecrement(&g_cObj);
  456. if (m_pCurProxy)
  457. m_pCurProxy->Release ();
  458. if (m_pProxyCache)
  459. m_pProxyCache->Release ();
  460. if (m_pPrivilegeSet)
  461. m_pPrivilegeSet->Release ();
  462. }
  463. //***************************************************************************
  464. // HRESULT CSWbemSecurity::QueryInterface
  465. // long CSWbemSecurity::AddRef
  466. // long CSWbemSecurity::Release
  467. //
  468. // DESCRIPTION:
  469. //
  470. // Standard Com IUNKNOWN functions.
  471. //
  472. //***************************************************************************
  473. STDMETHODIMP CSWbemSecurity::QueryInterface (
  474. IN REFIID riid,
  475. OUT LPVOID *ppv
  476. )
  477. {
  478. *ppv=NULL;
  479. if (IID_IUnknown==riid)
  480. *ppv = reinterpret_cast<IUnknown*>(this);
  481. else if (IID_ISWbemSecurity==riid)
  482. *ppv = (ISWbemSecurity *)this;
  483. else if (IID_IDispatch==riid)
  484. *ppv = (IDispatch *)this;
  485. else if (IID_ISupportErrorInfo==riid)
  486. *ppv = (ISupportErrorInfo *)this;
  487. else if (IID_ISWbemInternalSecurity==riid)
  488. *ppv = (ISWbemInternalSecurity *)this;
  489. else if (IID_IProvideClassInfo==riid)
  490. *ppv = (IProvideClassInfo *)this;
  491. if (NULL!=*ppv)
  492. {
  493. ((LPUNKNOWN)*ppv)->AddRef();
  494. return NOERROR;
  495. }
  496. return ResultFromScode(E_NOINTERFACE);
  497. }
  498. STDMETHODIMP_(ULONG) CSWbemSecurity::AddRef(void)
  499. {
  500. long l = InterlockedIncrement(&m_cRef);
  501. return l;
  502. }
  503. STDMETHODIMP_(ULONG) CSWbemSecurity::Release(void)
  504. {
  505. LONG cRef = InterlockedDecrement(&m_cRef);
  506. if (0 != cRef)
  507. {
  508. _ASSERT(cRef > 0);
  509. return cRef;
  510. }
  511. delete this;
  512. return 0;
  513. }
  514. //***************************************************************************
  515. // HRESULT CSWbemSecurity::InterfaceSupportsErrorInfo
  516. //
  517. // DESCRIPTION:
  518. //
  519. // Standard Com ISupportErrorInfo functions.
  520. //
  521. //***************************************************************************
  522. STDMETHODIMP CSWbemSecurity::InterfaceSupportsErrorInfo (IN REFIID riid)
  523. {
  524. return (IID_ISWbemSecurity == riid) ? S_OK : S_FALSE;
  525. }
  526. //***************************************************************************
  527. //
  528. // SCODE CSWbemSecurity::get_AuthenticationLevel
  529. //
  530. // DESCRIPTION:
  531. //
  532. // Retrieve the authentication level
  533. //
  534. // PARAMETERS:
  535. //
  536. // pAuthenticationLevel holds the value on return
  537. //
  538. // RETURN VALUES:
  539. //
  540. // WBEM_S_NO_ERROR success
  541. // WBEM_E_INVALID_PARAMETER bad input parameters
  542. // WBEM_E_FAILED otherwise
  543. //
  544. //***************************************************************************
  545. HRESULT CSWbemSecurity::get_AuthenticationLevel (
  546. WbemAuthenticationLevelEnum *pAuthenticationLevel
  547. )
  548. {
  549. HRESULT hr = WBEM_E_FAILED;
  550. ResetLastErrors ();
  551. if (NULL == pAuthenticationLevel)
  552. hr = WBEM_E_INVALID_PARAMETER;
  553. else if (m_pCurProxy)
  554. {
  555. DWORD dwAuthnLevel;
  556. DWORD dwImpLevel;
  557. if (S_OK == GetAuthImp (m_pCurProxy, &dwAuthnLevel, &dwImpLevel))
  558. {
  559. *pAuthenticationLevel = (WbemAuthenticationLevelEnum) dwAuthnLevel;
  560. hr = WBEM_S_NO_ERROR;
  561. }
  562. }
  563. if (FAILED(hr))
  564. m_Dispatch.RaiseException (hr);
  565. return hr;
  566. }
  567. //***************************************************************************
  568. //
  569. // SCODE CSWbemSecurity::put_AuthenticationLevel
  570. //
  571. // DESCRIPTION:
  572. //
  573. // Set the authentication level
  574. //
  575. // PARAMETERS:
  576. //
  577. // authenticationLevel the new value
  578. //
  579. // RETURN VALUES:
  580. //
  581. // WBEM_S_NO_ERROR success
  582. // WBEM_E_INVALID_PARAMETER bad input parameters
  583. // WBEM_E_FAILED otherwise
  584. //
  585. //***************************************************************************
  586. HRESULT CSWbemSecurity::put_AuthenticationLevel (
  587. WbemAuthenticationLevelEnum authenticationLevel
  588. )
  589. {
  590. HRESULT hr = WBEM_E_FAILED;
  591. ResetLastErrors ();
  592. if ((WBEMS_MIN_AUTHN_LEVEL > authenticationLevel) ||
  593. (WBEMS_MAX_AUTHN_LEVEL < authenticationLevel))
  594. hr = WBEM_E_INVALID_PARAMETER;
  595. else if (m_pCurProxy && m_pProxyCache)
  596. {
  597. DWORD dwAuthnLevel;
  598. DWORD dwImpLevel;
  599. if (S_OK == GetAuthImp (m_pCurProxy, &dwAuthnLevel, &dwImpLevel))
  600. {
  601. // Only refressh from cache if settings have changed
  602. if (authenticationLevel != (WbemAuthenticationLevelEnum) dwAuthnLevel)
  603. {
  604. m_pCurProxy->Release ();
  605. m_pCurProxy = NULL;
  606. m_pCurProxy = m_pProxyCache->GetProxy
  607. (authenticationLevel, (WbemImpersonationLevelEnum) dwImpLevel);
  608. }
  609. hr = WBEM_S_NO_ERROR;
  610. }
  611. }
  612. if (FAILED(hr))
  613. m_Dispatch.RaiseException (hr);
  614. return hr;
  615. }
  616. //***************************************************************************
  617. //
  618. // SCODE CSWbemSecurity::get_ImpersonationLevel
  619. //
  620. // DESCRIPTION:
  621. //
  622. // Retrieve the impersonation level
  623. //
  624. // PARAMETERS:
  625. //
  626. // pImpersonationLevel holds the value on return
  627. //
  628. // RETURN VALUES:
  629. //
  630. // WBEM_S_NO_ERROR success
  631. // WBEM_E_INVALID_PARAMETER bad input parameters
  632. // WBEM_E_FAILED otherwise
  633. //
  634. //***************************************************************************
  635. HRESULT CSWbemSecurity::get_ImpersonationLevel (
  636. WbemImpersonationLevelEnum *pImpersonationLevel
  637. )
  638. {
  639. HRESULT hr = WBEM_E_FAILED;
  640. ResetLastErrors ();
  641. if (NULL == pImpersonationLevel)
  642. hr = WBEM_E_INVALID_PARAMETER;
  643. else if (m_pCurProxy)
  644. {
  645. DWORD dwAuthnLevel;
  646. DWORD dwImpLevel;
  647. if (S_OK == GetAuthImp (m_pCurProxy, &dwAuthnLevel, &dwImpLevel))
  648. {
  649. *pImpersonationLevel = (WbemImpersonationLevelEnum) dwImpLevel;
  650. hr = WBEM_S_NO_ERROR;
  651. }
  652. }
  653. if (FAILED(hr))
  654. m_Dispatch.RaiseException (hr);
  655. return hr;
  656. }
  657. //***************************************************************************
  658. //
  659. // SCODE CSWbemSecurity::put_ImpersonationLevel
  660. //
  661. // DESCRIPTION:
  662. //
  663. // Set the impersonation level
  664. //
  665. // PARAMETERS:
  666. //
  667. // impersonationLevel the new value
  668. //
  669. // RETURN VALUES:
  670. //
  671. // WBEM_S_NO_ERROR success
  672. // WBEM_E_INVALID_PARAMETER bad input parameters
  673. // WBEM_E_FAILED otherwise
  674. //
  675. //***************************************************************************
  676. HRESULT CSWbemSecurity::put_ImpersonationLevel (
  677. WbemImpersonationLevelEnum impersonationLevel
  678. )
  679. {
  680. HRESULT hr = WBEM_E_FAILED;
  681. ResetLastErrors ();
  682. if ((WBEMS_MIN_IMP_LEVEL > impersonationLevel) || (WBEMS_MAX_IMP_LEVEL < impersonationLevel))
  683. hr = WBEM_E_INVALID_PARAMETER;
  684. else if (m_pCurProxy && m_pProxyCache)
  685. {
  686. DWORD dwAuthnLevel;
  687. DWORD dwImpLevel;
  688. if (S_OK == GetAuthImp (m_pCurProxy, &dwAuthnLevel, &dwImpLevel))
  689. {
  690. // Only refressh from cache if settings have changed
  691. if (impersonationLevel != (WbemImpersonationLevelEnum) dwImpLevel)
  692. {
  693. m_pCurProxy->Release ();
  694. m_pCurProxy = NULL;
  695. m_pCurProxy = m_pProxyCache->GetProxy
  696. ((WbemAuthenticationLevelEnum) dwAuthnLevel, impersonationLevel);
  697. }
  698. hr = WBEM_S_NO_ERROR;
  699. }
  700. }
  701. if (FAILED(hr))
  702. m_Dispatch.RaiseException (hr);
  703. return hr;
  704. }
  705. //***************************************************************************
  706. //
  707. // SCODE CSWbemSecurity::get_Privileges
  708. //
  709. // DESCRIPTION:
  710. //
  711. // Return the Privilege override set
  712. //
  713. // WBEM_S_NO_ERROR success
  714. // WBEM_E_INVALID_PARAMETER bad input parameters
  715. // WBEM_E_FAILED otherwise
  716. //
  717. //***************************************************************************
  718. HRESULT CSWbemSecurity::get_Privileges (
  719. ISWbemPrivilegeSet **ppPrivileges
  720. )
  721. {
  722. HRESULT hr = WBEM_E_FAILED;
  723. ResetLastErrors ();
  724. if (NULL == ppPrivileges)
  725. hr = WBEM_E_INVALID_PARAMETER;
  726. else // Bug ID 566345
  727. {
  728. *ppPrivileges = NULL;
  729. if (m_pPrivilegeSet)
  730. {
  731. if (SUCCEEDED (m_pPrivilegeSet->QueryInterface (IID_ISWbemPrivilegeSet,
  732. (PPVOID) ppPrivileges)))
  733. hr = WBEM_S_NO_ERROR;
  734. }
  735. }
  736. if (FAILED(hr))
  737. m_Dispatch.RaiseException (hr);
  738. return hr;
  739. }
  740. //***************************************************************************
  741. //
  742. // CSWbemSecurity::SecureInterface
  743. //
  744. // DESCRIPTION:
  745. //
  746. // Set the security on the specified interface using the security settings
  747. // on this interface.
  748. //
  749. // PARAMETERS:
  750. //
  751. // pUnk The interface to secure
  752. //
  753. // RETURN VALUES:
  754. // none
  755. //***************************************************************************
  756. void CSWbemSecurity::SecureInterface (IUnknown *pUnk)
  757. {
  758. if(pUnk)
  759. {
  760. if (m_pCurProxy)
  761. {
  762. DWORD dwAuthnLevel;
  763. DWORD dwImpLevel;
  764. if (S_OK == GetAuthImp (m_pCurProxy, &dwAuthnLevel, &dwImpLevel))
  765. if (m_pProxyCache)
  766. m_pProxyCache->SecureProxy (pUnk,
  767. (WbemAuthenticationLevelEnum) dwAuthnLevel,
  768. (WbemImpersonationLevelEnum) dwImpLevel);
  769. }
  770. }
  771. }
  772. //***************************************************************************
  773. //
  774. // CSWbemSecurity::SecureInterfaceRev
  775. //
  776. // DESCRIPTION:
  777. //
  778. // Set the security on this interface using the security settings
  779. // on the specified interface.
  780. //
  781. // PARAMETERS:
  782. //
  783. // pUnk The interface whose security settings we will
  784. // use to set this interface
  785. //
  786. // RETURN VALUES:
  787. // none
  788. //***************************************************************************
  789. void CSWbemSecurity::SecureInterfaceRev (IUnknown *pUnk)
  790. {
  791. if (pUnk)
  792. {
  793. DWORD dwAuthnLevel;
  794. DWORD dwImpLevel;
  795. if (S_OK == GetAuthImp (pUnk, &dwAuthnLevel, &dwImpLevel))
  796. {
  797. if (m_pCurProxy)
  798. {
  799. m_pCurProxy->Release ();
  800. m_pCurProxy = NULL;
  801. }
  802. if (m_pProxyCache)
  803. {
  804. m_pCurProxy = m_pProxyCache->GetProxy
  805. ((WbemAuthenticationLevelEnum) dwAuthnLevel,
  806. (WbemImpersonationLevelEnum) dwImpLevel);
  807. }
  808. }
  809. }
  810. }
  811. //***************************************************************************
  812. //
  813. // CSWbemSecurity::AdjustTokenPrivileges
  814. //
  815. // DESCRIPTION:
  816. //
  817. // Adjust the Privileges on the specified token without allowing a future
  818. // restore of the current settings..
  819. //
  820. // PARAMETERS:
  821. //
  822. // hHandle Handle of the token on which to adjust privileges
  823. // pPrivilegeSet Specified privilege adjustments
  824. //
  825. // RETURN VALUES:
  826. // none
  827. //***************************************************************************
  828. BOOL CSWbemSecurity::AdjustTokenPrivileges (
  829. HANDLE hHandle,
  830. CSWbemPrivilegeSet *pPrivilegeSet
  831. )
  832. {
  833. BOOL result = FALSE;
  834. DWORD lastErr = 0;
  835. if (pPrivilegeSet)
  836. {
  837. pPrivilegeSet->AddRef ();
  838. long lNumPrivileges = 0;
  839. pPrivilegeSet->get_Count (&lNumPrivileges);
  840. if (lNumPrivileges)
  841. {
  842. DWORD dwPrivilegeIndex = 0;
  843. /*
  844. * Set up the token privileges array. Note that some jiggery-pokery
  845. * is required here because the Privileges field is an [ANYSIZE_ARRAY]
  846. * type.
  847. */
  848. TOKEN_PRIVILEGES *pTokenPrivileges = (TOKEN_PRIVILEGES *)
  849. new BYTE [sizeof(TOKEN_PRIVILEGES) + (lNumPrivileges * sizeof (LUID_AND_ATTRIBUTES [1]))];
  850. if (pTokenPrivileges)
  851. {
  852. // Get the iterator
  853. PrivilegeMap::iterator next = pPrivilegeSet->m_PrivilegeMap.begin ();
  854. while (next != pPrivilegeSet->m_PrivilegeMap.end ())
  855. {
  856. CSWbemPrivilege *pPrivilege = (*next).second;
  857. pPrivilege->AddRef ();
  858. LUID luid;
  859. pPrivilege->GetLUID (&luid);
  860. VARIANT_BOOL vBool;
  861. pPrivilege->get_IsEnabled (&vBool);
  862. pTokenPrivileges->Privileges [dwPrivilegeIndex].Luid = luid;
  863. /*
  864. * Note that any setting other than SE_PRIVILEGE_ENABLED
  865. * is interpreted by AdjustTokenPrivileges as a DISABLE
  866. * request for that Privilege.
  867. */
  868. pTokenPrivileges->Privileges [dwPrivilegeIndex].Attributes
  869. = (VARIANT_TRUE == vBool) ?
  870. SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_ENABLED_BY_DEFAULT;
  871. dwPrivilegeIndex++;
  872. pPrivilege->Release ();
  873. next++;
  874. }
  875. // Now we should have recorded the number of privileges that were OK
  876. if (0 < dwPrivilegeIndex)
  877. {
  878. pTokenPrivileges->PrivilegeCount = dwPrivilegeIndex;
  879. result = ::AdjustTokenPrivileges (hHandle, FALSE, pTokenPrivileges, 0, NULL, NULL);
  880. lastErr = GetLastError ();
  881. }
  882. delete [] pTokenPrivileges;
  883. }
  884. }
  885. pPrivilegeSet->Release ();
  886. }
  887. return result;
  888. }
  889. template <typename T, typename FT, FT F> class OnDelete
  890. {
  891. private:
  892. T Val_;
  893. public:
  894. OnDelete(T Val):Val_(Val){};
  895. ~OnDelete(){ F(Val_); };
  896. };
  897. BOOL DuplicateTokenSameAcl(HANDLE hSrcToken,
  898. SECURITY_IMPERSONATION_LEVEL secImpLevel,
  899. HANDLE * pDupToken)
  900. {
  901. if (!s_pfnDuplicateTokenEx)
  902. return FALSE;
  903. DWORD dwSize = 0;
  904. BOOL bRet = GetKernelObjectSecurity(hSrcToken,
  905. DACL_SECURITY_INFORMATION, // |GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION
  906. NULL,
  907. 0,
  908. &dwSize);
  909. if(!bRet && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
  910. {
  911. void * pSecDescr = LocalAlloc(LPTR,dwSize);
  912. if (NULL == pSecDescr)
  913. return FALSE;
  914. OnDelete<void *,HLOCAL(*)(HLOCAL),LocalFree> rm(pSecDescr);
  915. bRet = GetKernelObjectSecurity(hSrcToken,
  916. DACL_SECURITY_INFORMATION, // |GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION
  917. pSecDescr,
  918. dwSize,
  919. &dwSize);
  920. if (FALSE == bRet)
  921. return bRet;
  922. SECURITY_ATTRIBUTES sa;
  923. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  924. sa.lpSecurityDescriptor = pSecDescr;
  925. sa.bInheritHandle = FALSE;
  926. return s_pfnDuplicateTokenEx(hSrcToken,
  927. TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES|TOKEN_IMPERSONATE,
  928. &sa,
  929. secImpLevel, TokenImpersonation,pDupToken);
  930. }
  931. return bRet;
  932. }
  933. //***************************************************************************
  934. //
  935. // SCODE CSWbemSecurity::SetSecurity
  936. //
  937. // DESCRIPTION:
  938. //
  939. // Set Privileges on the Thread Token.
  940. //
  941. //***************************************************************************
  942. BOOL CSWbemSecurity::SetSecurity (
  943. bool &needToResetSecurity,
  944. HANDLE &hThreadToken
  945. )
  946. {
  947. BOOL result = TRUE; // Default is success
  948. DWORD lastErr = 0;
  949. hThreadToken = NULL; // Default assume we'll modify process token
  950. needToResetSecurity = false; // Default assume we changed no privileges
  951. // Win9x has no security support
  952. if (IsNT ())
  953. {
  954. // Start by checking whether we are being impersonated. On an NT4
  955. // box (which has no cloaking, and therefore cannot allow us to
  956. // pass on this impersonation to Winmgmt) we should RevertToSelf
  957. // if we have been configured to allow this. If we haven't been
  958. // configured to allow this, bail out now.
  959. if (4 >= GetNTMajorVersion ())
  960. {
  961. if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY|TOKEN_IMPERSONATE, true, &hThreadToken))
  962. {
  963. // We are being impersonated
  964. if (s_bCanRevert)
  965. {
  966. if (result = RevertToSelf())
  967. needToResetSecurity = true;
  968. }
  969. else
  970. {
  971. // Error - cannot do this! Time to bail out
  972. CloseHandle (hThreadToken);
  973. hThreadToken = NULL;
  974. result = FALSE;
  975. }
  976. }
  977. }
  978. else
  979. {
  980. #ifdef WSCRPDEBUG
  981. HANDLE hToken = NULL;
  982. if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, false, &hToken))
  983. {
  984. PrintPrivileges (hToken);
  985. CloseHandle (hToken);
  986. }
  987. #endif
  988. }
  989. if (result)
  990. {
  991. // Now we check if we need to set privileges
  992. bool bIsUsingExplicitUserName = false;
  993. if (m_pProxyCache)
  994. bIsUsingExplicitUserName = m_pProxyCache->IsUsingExplicitUserName ();
  995. /*
  996. * Specifying a user only makes sense for remote operations, and we
  997. * don't need to mess with privilege for remote operations since
  998. * they are set up by server logon anyway.
  999. */
  1000. if (!bIsUsingExplicitUserName && m_pPrivilegeSet)
  1001. {
  1002. // Nothing to do unless some privilege overrides have been set
  1003. long lCount = 0;
  1004. m_pPrivilegeSet->get_Count (&lCount);
  1005. if (0 < lCount)
  1006. {
  1007. if (4 < GetNTMajorVersion ())
  1008. {
  1009. /*
  1010. * On NT5 we try to open the Thread token. If the client app
  1011. * is calling into us on an impersonated thread (as IIS may be,
  1012. * for example), this will succeed.
  1013. */
  1014. HANDLE hToken;
  1015. SECURITY_IMPERSONATION_LEVEL secImpLevel = SecurityImpersonation;
  1016. if (!(result = OpenThreadToken (GetCurrentThread (), TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE|TOKEN_READ, true, &hToken)))
  1017. {
  1018. // No thread token - go for the Process token instead
  1019. HANDLE hProcess = GetCurrentProcess ();
  1020. result = OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_READ, &hToken);
  1021. CloseHandle (hProcess);
  1022. if(result)
  1023. {
  1024. WbemImpersonationLevelEnum tmpSecImpLevel;
  1025. get_ImpersonationLevel(&tmpSecImpLevel);
  1026. secImpLevel = MapImpersonationLevel(tmpSecImpLevel);
  1027. }
  1028. }
  1029. else
  1030. {
  1031. // We are working with a thread token
  1032. hThreadToken = hToken;
  1033. // Try and get the impersonation level of this token
  1034. DWORD dwReturnLength = 0;
  1035. BOOL thisRes = GetTokenInformation (hToken, TokenImpersonationLevel, &secImpLevel,
  1036. sizeof (SECURITY_IMPERSONATION_LEVEL), &dwReturnLength);
  1037. }
  1038. if (result)
  1039. {
  1040. /*
  1041. * Getting here means we have a valid token, be it process or thread. We
  1042. * now attempt to duplicate it before Adjusting the Privileges.
  1043. */
  1044. #ifdef WSCRPDEBUG
  1045. PrintPrivileges (hToken);
  1046. #endif
  1047. HANDLE hDupToken;
  1048. EnterCriticalSection (&g_csSecurity);
  1049. result = DuplicateTokenSameAcl(hToken,
  1050. secImpLevel,
  1051. &hDupToken);
  1052. LeaveCriticalSection (&g_csSecurity);
  1053. if(result) result = CSWbemSecurity::AdjustTokenPrivileges (hDupToken, m_pPrivilegeSet);
  1054. if (result)
  1055. {
  1056. // Now use this token on the current thread
  1057. if (SetThreadToken(NULL, hDupToken))
  1058. {
  1059. needToResetSecurity = true;
  1060. #ifdef WSCRPDEBUG
  1061. CSWbemSecurity::PrintPrivileges (hDupToken);
  1062. #endif
  1063. // Reset the blanket for the benefit of RPC
  1064. DWORD dwAuthnLevel, dwImpLevel;
  1065. if (S_OK == GetAuthImp (m_pCurProxy, &dwAuthnLevel, &dwImpLevel))
  1066. {
  1067. // Force the cache to resecure the proxy
  1068. IUnknown *pNewProxy = m_pProxyCache->GetProxy
  1069. ((WbemAuthenticationLevelEnum) dwAuthnLevel,
  1070. (WbemImpersonationLevelEnum) dwImpLevel, true);
  1071. if (pNewProxy)
  1072. {
  1073. if (m_pCurProxy)
  1074. m_pCurProxy->Release ();
  1075. m_pCurProxy = pNewProxy;
  1076. }
  1077. }
  1078. }
  1079. else
  1080. {
  1081. result = FALSE;
  1082. }
  1083. CloseHandle (hDupToken);
  1084. }
  1085. else
  1086. {
  1087. lastErr = GetLastError ();
  1088. }
  1089. /*
  1090. * If we are not using a thread token, close the token now. Otherwise
  1091. * the handle will be closed in the balanced call to RestorePrivileges ().
  1092. */
  1093. if (!hThreadToken)
  1094. CloseHandle (hToken);
  1095. }
  1096. }
  1097. else
  1098. {
  1099. // For NT4 we adjust the privileges in the process token
  1100. HANDLE hProcessToken = NULL;
  1101. HANDLE hProcess = GetCurrentProcess ();
  1102. result = OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hProcessToken);
  1103. CloseHandle (hProcess);
  1104. // Adjust privilege on the process
  1105. if (result)
  1106. {
  1107. #ifdef WSCRPDEBUG
  1108. CSWbemSecurity::PrintPrivileges (hProcessToken);
  1109. #endif
  1110. result = CSWbemSecurity::AdjustTokenPrivileges (hProcessToken, m_pPrivilegeSet);
  1111. #ifdef WSCRPDEBUG
  1112. CSWbemSecurity::PrintPrivileges (hProcessToken);
  1113. #endif
  1114. CloseHandle (hProcessToken);
  1115. }
  1116. }
  1117. }
  1118. }
  1119. }
  1120. }
  1121. return result;
  1122. }
  1123. //***************************************************************************
  1124. //
  1125. // SCODE CSWbemSecurity::ResetSecurity
  1126. //
  1127. // DESCRIPTION:
  1128. //
  1129. // Restore Privileges on the Thread Token.
  1130. //
  1131. //***************************************************************************
  1132. void CSWbemSecurity::ResetSecurity (
  1133. HANDLE hThreadToken
  1134. )
  1135. {
  1136. // Win9x has no security palaver
  1137. if (IsNT ())
  1138. {
  1139. /*
  1140. * Set the supplied token (which may be NULL) into
  1141. * the current thread.
  1142. */
  1143. BOOL result = SetThreadToken (NULL, hThreadToken);
  1144. DWORD error = 0;
  1145. if (!result)
  1146. error = GetLastError ();
  1147. #ifdef WSCRPDEBUG
  1148. // Print out the current privileges to see what's changed
  1149. HANDLE hToken = NULL;
  1150. if (!OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, false, &hToken))
  1151. {
  1152. // No thread token - go for the Process token instead
  1153. HANDLE hProcess = GetCurrentProcess ();
  1154. OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
  1155. CloseHandle (hProcess);
  1156. }
  1157. if (hToken)
  1158. {
  1159. PrintPrivileges (hToken);
  1160. CloseHandle (hToken);
  1161. }
  1162. #endif
  1163. if (hThreadToken)
  1164. CloseHandle (hThreadToken);
  1165. }
  1166. }
  1167. bool CSWbemSecurity::IsImpersonating (bool useDefaultUser, bool useDefaultAuthority)
  1168. {
  1169. bool result = false;
  1170. if (useDefaultUser && useDefaultAuthority && CSWbemSecurity::IsNT () &&
  1171. (4 < CSWbemSecurity::GetNTMajorVersion ()))
  1172. {
  1173. // A suitable candidate - find out if we are running on an impersonated thread
  1174. HANDLE hThreadToken = NULL;
  1175. if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, true, &hThreadToken))
  1176. {
  1177. // Check we have an impersonation token
  1178. SECURITY_IMPERSONATION_LEVEL secImpLevel;
  1179. DWORD dwReturnLength = 0;
  1180. if (GetTokenInformation (hThreadToken, TokenImpersonationLevel, &secImpLevel,
  1181. sizeof (SECURITY_IMPERSONATION_LEVEL), &dwReturnLength))
  1182. result = ((SecurityImpersonation == secImpLevel) || (SecurityDelegation == secImpLevel));
  1183. CloseHandle (hThreadToken);
  1184. }
  1185. }
  1186. return result;
  1187. }
  1188. HRESULT CSWbemSecurity::GetAuthority (BSTR *bsAuthority)
  1189. {
  1190. HRESULT hr = WBEM_E_FAILED;
  1191. if (m_pProxyCache)
  1192. {
  1193. *bsAuthority = SysAllocString(m_pProxyCache->GetAuthority ());
  1194. hr = S_OK;
  1195. }
  1196. return hr;
  1197. }
  1198. HRESULT CSWbemSecurity::GetUPD (BSTR *bsUser, BSTR *bsPassword, BSTR *bsDomain)
  1199. {
  1200. HRESULT hr = WBEM_E_FAILED;
  1201. if (m_pProxyCache)
  1202. {
  1203. COAUTHIDENTITY *pCoAuthIdentity = m_pProxyCache->GetCoAuthIdentity ();
  1204. if (pCoAuthIdentity)
  1205. {
  1206. *bsUser = SysAllocString (pCoAuthIdentity->User);
  1207. *bsPassword = SysAllocString (pCoAuthIdentity->Password);
  1208. *bsDomain = SysAllocString (pCoAuthIdentity->Domain);
  1209. WbemFreeAuthIdentity (pCoAuthIdentity);
  1210. }
  1211. hr = S_OK;
  1212. }
  1213. return hr;
  1214. }
  1215. HRESULT CSWbemSecurity::GetPrincipal (BSTR *bsPrincipal)
  1216. {
  1217. HRESULT hr = WBEM_E_FAILED;
  1218. if (m_pProxyCache)
  1219. {
  1220. *bsPrincipal = SysAllocString(m_pProxyCache->GetPrincipal ());
  1221. hr = S_OK;
  1222. }
  1223. return hr;
  1224. }
  1225. // CWbemLocatorSecurity methods
  1226. //***************************************************************************
  1227. //
  1228. // CSWbemLocatorSecurity::CSWbemLocatorSecurity
  1229. //
  1230. // CONSTRUCTOR
  1231. //
  1232. //***************************************************************************
  1233. CWbemLocatorSecurity::CWbemLocatorSecurity (CSWbemPrivilegeSet *pPrivilegeSet) :
  1234. m_cRef (1),
  1235. m_impLevelSet (false),
  1236. m_authnLevelSet (false),
  1237. m_pPrivilegeSet (NULL)
  1238. {
  1239. m_Dispatch.SetObj (this, IID_ISWbemSecurity,
  1240. CLSID_SWbemSecurity, L"SWbemSecurity");
  1241. InterlockedIncrement(&g_cObj);
  1242. if (pPrivilegeSet)
  1243. m_pPrivilegeSet = new CSWbemPrivilegeSet (*pPrivilegeSet);
  1244. else
  1245. m_pPrivilegeSet = new CSWbemPrivilegeSet;
  1246. }
  1247. CWbemLocatorSecurity::CWbemLocatorSecurity (CWbemLocatorSecurity *pCWbemLocatorSecurity) :
  1248. m_cRef (1),
  1249. m_impLevelSet (false),
  1250. m_authnLevelSet (false),
  1251. m_pPrivilegeSet (NULL)
  1252. {
  1253. m_Dispatch.SetObj (this, IID_ISWbemSecurity,
  1254. CLSID_SWbemSecurity, L"SWbemSecurity");
  1255. InterlockedIncrement(&g_cObj);
  1256. if (pCWbemLocatorSecurity)
  1257. {
  1258. m_pPrivilegeSet = new CSWbemPrivilegeSet (pCWbemLocatorSecurity->m_pPrivilegeSet);
  1259. m_impLevelSet = pCWbemLocatorSecurity->m_impLevelSet;
  1260. m_authnLevelSet = pCWbemLocatorSecurity->m_authnLevelSet;
  1261. if (m_impLevelSet)
  1262. m_impLevel = pCWbemLocatorSecurity->m_impLevel;
  1263. if (m_authnLevelSet)
  1264. m_authnLevel = pCWbemLocatorSecurity->m_authnLevel;
  1265. }
  1266. else
  1267. {
  1268. m_pPrivilegeSet = new CSWbemPrivilegeSet;
  1269. m_impLevelSet = false;
  1270. m_authnLevelSet = false;
  1271. }
  1272. }
  1273. //***************************************************************************
  1274. //
  1275. // CWbemLocatorSecurity::CWbemLocatorSecurity
  1276. //
  1277. // DESTRUCTOR
  1278. //
  1279. //***************************************************************************
  1280. CWbemLocatorSecurity::~CWbemLocatorSecurity (void)
  1281. {
  1282. InterlockedDecrement(&g_cObj);
  1283. if (m_pPrivilegeSet)
  1284. m_pPrivilegeSet->Release ();
  1285. }
  1286. //***************************************************************************
  1287. // HRESULT CWbemLocatorSecurity::QueryInterface
  1288. // long CWbemLocatorSecurity::AddRef
  1289. // long CWbemLocatorSecurity::Release
  1290. //
  1291. // DESCRIPTION:
  1292. //
  1293. // Standard Com IUNKNOWN functions.
  1294. //
  1295. //***************************************************************************
  1296. STDMETHODIMP CWbemLocatorSecurity::QueryInterface (
  1297. IN REFIID riid,
  1298. OUT LPVOID *ppv
  1299. )
  1300. {
  1301. *ppv=NULL;
  1302. if (IID_IUnknown==riid)
  1303. *ppv = reinterpret_cast<IUnknown*>(this);
  1304. else if (IID_ISWbemSecurity==riid)
  1305. *ppv = (ISWbemSecurity *)this;
  1306. else if (IID_IDispatch==riid)
  1307. *ppv = (IDispatch *)this;
  1308. else if (IID_ISupportErrorInfo==riid)
  1309. *ppv = (ISupportErrorInfo *)this;
  1310. else if (IID_IProvideClassInfo==riid)
  1311. *ppv = (IProvideClassInfo *)this;
  1312. if (NULL!=*ppv)
  1313. {
  1314. ((LPUNKNOWN)*ppv)->AddRef();
  1315. return NOERROR;
  1316. }
  1317. return ResultFromScode(E_NOINTERFACE);
  1318. }
  1319. STDMETHODIMP_(ULONG) CWbemLocatorSecurity::AddRef(void)
  1320. {
  1321. long l = InterlockedIncrement(&m_cRef);
  1322. return l;
  1323. }
  1324. STDMETHODIMP_(ULONG) CWbemLocatorSecurity::Release(void)
  1325. {
  1326. LONG cRef = InterlockedDecrement(&m_cRef);
  1327. if (0 != cRef)
  1328. {
  1329. _ASSERT(cRef > 0);
  1330. return cRef;
  1331. }
  1332. delete this;
  1333. return 0;
  1334. }
  1335. //***************************************************************************
  1336. // HRESULT CSWbemLocatorSecurity::InterfaceSupportsErrorInfo
  1337. //
  1338. // DESCRIPTION:
  1339. //
  1340. // Standard Com ISupportErrorInfo functions.
  1341. //
  1342. //***************************************************************************
  1343. STDMETHODIMP CWbemLocatorSecurity::InterfaceSupportsErrorInfo (IN REFIID riid)
  1344. {
  1345. return (IID_ISWbemSecurity == riid) ? S_OK : S_FALSE;
  1346. }
  1347. //***************************************************************************
  1348. //
  1349. // SCODE CWbemLocatorSecurity::get_AuthenticationLevel
  1350. //
  1351. // DESCRIPTION:
  1352. //
  1353. // Retrieve the authentication level
  1354. //
  1355. // PARAMETERS:
  1356. //
  1357. // pAuthenticationLevel holds the value on return
  1358. //
  1359. // RETURN VALUES:
  1360. //
  1361. // WBEM_S_NO_ERROR success
  1362. // WBEM_E_INVALID_PARAMETER bad input parameters
  1363. // WBEM_E_FAILED otherwise
  1364. //
  1365. //***************************************************************************
  1366. HRESULT CWbemLocatorSecurity::get_AuthenticationLevel (
  1367. WbemAuthenticationLevelEnum *pAuthenticationLevel
  1368. )
  1369. {
  1370. HRESULT hr = WBEM_E_FAILED;
  1371. ResetLastErrors ();
  1372. if (NULL == pAuthenticationLevel)
  1373. hr = WBEM_E_INVALID_PARAMETER;
  1374. else if (m_authnLevelSet)
  1375. {
  1376. *pAuthenticationLevel = m_authnLevel;
  1377. hr = WBEM_S_NO_ERROR;
  1378. }
  1379. if (FAILED(hr))
  1380. m_Dispatch.RaiseException (hr);
  1381. return hr;
  1382. }
  1383. //***************************************************************************
  1384. //
  1385. // SCODE CWbemLocatorSecurity::put_AuthenticationLevel
  1386. //
  1387. // DESCRIPTION:
  1388. //
  1389. // Set the authentication level
  1390. //
  1391. // PARAMETERS:
  1392. //
  1393. // authenticationLevel the new value
  1394. //
  1395. // RETURN VALUES:
  1396. //
  1397. // WBEM_S_NO_ERROR success
  1398. // WBEM_E_INVALID_PARAMETER bad input parameters
  1399. // WBEM_E_FAILED otherwise
  1400. //
  1401. //***************************************************************************
  1402. HRESULT CWbemLocatorSecurity::put_AuthenticationLevel (
  1403. WbemAuthenticationLevelEnum authenticationLevel
  1404. )
  1405. {
  1406. HRESULT hr = WBEM_E_FAILED;
  1407. ResetLastErrors ();
  1408. if ((WBEMS_MIN_AUTHN_LEVEL > authenticationLevel) ||
  1409. (WBEMS_MAX_AUTHN_LEVEL < authenticationLevel))
  1410. hr = WBEM_E_INVALID_PARAMETER;
  1411. else
  1412. {
  1413. m_authnLevel = authenticationLevel;
  1414. m_authnLevelSet = true;
  1415. hr = WBEM_S_NO_ERROR;
  1416. }
  1417. if (FAILED(hr))
  1418. m_Dispatch.RaiseException (hr);
  1419. return hr;
  1420. }
  1421. //***************************************************************************
  1422. //
  1423. // SCODE CWbemLocatorSecurity::get_ImpersonationLevel
  1424. //
  1425. // DESCRIPTION:
  1426. //
  1427. // Retrieve the impersonation level
  1428. //
  1429. // PARAMETERS:
  1430. //
  1431. // pImpersonationLevel holds the value on return
  1432. //
  1433. // RETURN VALUES:
  1434. //
  1435. // WBEM_S_NO_ERROR success
  1436. // WBEM_E_INVALID_PARAMETER bad input parameters
  1437. // WBEM_E_FAILED otherwise
  1438. //
  1439. //***************************************************************************
  1440. HRESULT CWbemLocatorSecurity::get_ImpersonationLevel (
  1441. WbemImpersonationLevelEnum *pImpersonationLevel
  1442. )
  1443. {
  1444. HRESULT hr = WBEM_E_FAILED;
  1445. ResetLastErrors ();
  1446. if (NULL == pImpersonationLevel)
  1447. hr = WBEM_E_INVALID_PARAMETER;
  1448. else if (m_impLevelSet)
  1449. {
  1450. *pImpersonationLevel = m_impLevel;
  1451. hr = WBEM_S_NO_ERROR;
  1452. }
  1453. if (FAILED(hr))
  1454. m_Dispatch.RaiseException (hr);
  1455. return hr;
  1456. }
  1457. //***************************************************************************
  1458. //
  1459. // SCODE CWbemLocatorSecurity::put_ImpersonationLevel
  1460. //
  1461. // DESCRIPTION:
  1462. //
  1463. // Set the impersonation level
  1464. //
  1465. // PARAMETERS:
  1466. //
  1467. // impersonationLevel the new value
  1468. //
  1469. // RETURN VALUES:
  1470. //
  1471. // WBEM_S_NO_ERROR success
  1472. // WBEM_E_INVALID_PARAMETER bad input parameters
  1473. // WBEM_E_FAILED otherwise
  1474. //
  1475. //***************************************************************************
  1476. HRESULT CWbemLocatorSecurity::put_ImpersonationLevel (
  1477. WbemImpersonationLevelEnum impersonationLevel
  1478. )
  1479. {
  1480. HRESULT hr = WBEM_E_FAILED;
  1481. ResetLastErrors ();
  1482. if ((WBEMS_MIN_IMP_LEVEL > impersonationLevel) || (WBEMS_MAX_IMP_LEVEL < impersonationLevel))
  1483. hr = WBEM_E_INVALID_PARAMETER;
  1484. else
  1485. {
  1486. m_impLevel = impersonationLevel;
  1487. m_impLevelSet = true;
  1488. hr = WBEM_S_NO_ERROR;
  1489. }
  1490. if (FAILED(hr))
  1491. m_Dispatch.RaiseException (hr);
  1492. return hr;
  1493. }
  1494. //***************************************************************************
  1495. //
  1496. // SCODE CWbemLocatorSecurity::get_Privileges
  1497. //
  1498. // DESCRIPTION:
  1499. //
  1500. // Return the Privilege override set
  1501. //
  1502. // WBEM_S_NO_ERROR success
  1503. // WBEM_E_INVALID_PARAMETER bad input parameters
  1504. // WBEM_E_FAILED otherwise
  1505. //
  1506. //***************************************************************************
  1507. HRESULT CWbemLocatorSecurity::get_Privileges (
  1508. ISWbemPrivilegeSet **ppPrivileges
  1509. )
  1510. {
  1511. HRESULT hr = WBEM_E_FAILED;
  1512. ResetLastErrors ();
  1513. if (NULL == ppPrivileges)
  1514. hr = WBEM_E_INVALID_PARAMETER;
  1515. else // Bug ID 566345
  1516. {
  1517. *ppPrivileges = NULL;
  1518. if (m_pPrivilegeSet)
  1519. {
  1520. if (SUCCEEDED (m_pPrivilegeSet->QueryInterface (IID_ISWbemPrivilegeSet,
  1521. (PPVOID) ppPrivileges)))
  1522. hr = WBEM_S_NO_ERROR;
  1523. }
  1524. }
  1525. if (FAILED(hr))
  1526. m_Dispatch.RaiseException (hr);
  1527. return hr;
  1528. }
  1529. //***************************************************************************
  1530. //
  1531. // SCODE CWbemLocatorSecurity::SetSecurity
  1532. //
  1533. // DESCRIPTION:
  1534. //
  1535. // Set Privileges on the Process Token.
  1536. //
  1537. //***************************************************************************
  1538. BOOL CWbemLocatorSecurity::SetSecurity (
  1539. BSTR bsUser,
  1540. bool &needToResetSecurity,
  1541. HANDLE &hThreadToken
  1542. )
  1543. {
  1544. BOOL result = TRUE;
  1545. needToResetSecurity = false;
  1546. hThreadToken = NULL;
  1547. /*
  1548. * NT5 supports the concept of dynamic cloaking, which means
  1549. * we can set privileges temporarily on a thread (impersonation)
  1550. * token basis immediately before a call to a remoted proxy.
  1551. *
  1552. * Setting prior to locator.connectserver therefore makes no
  1553. * sense for NT5.
  1554. *
  1555. * Oh and Win9x has no security support
  1556. */
  1557. if (CSWbemSecurity::IsNT () && (4 >= CSWbemSecurity::GetNTMajorVersion ()))
  1558. {
  1559. /*
  1560. * Start by checking whether we are being impersonated. On an NT4
  1561. * box (which has no cloaking, and therefore cannot allow us to
  1562. * pass on this impersonation to Winmgmt) we should RevertToSelf
  1563. * if we have been configured to allow this. If we haven't been
  1564. * configured to allow this, bail out now.
  1565. */
  1566. if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY|TOKEN_IMPERSONATE, false, &hThreadToken))
  1567. {
  1568. // We are being impersonated
  1569. if (CSWbemSecurity::CanRevertToSelf ())
  1570. {
  1571. if (result = RevertToSelf())
  1572. needToResetSecurity = true;
  1573. }
  1574. else
  1575. {
  1576. // Error - cannot do this! Time to bail out
  1577. CloseHandle (hThreadToken);
  1578. hThreadToken = NULL;
  1579. result = FALSE;
  1580. }
  1581. }
  1582. if (result && m_pPrivilegeSet)
  1583. {
  1584. /*
  1585. * Specifying a user only makes sense for remote operations, and we
  1586. * don't need to mess with privilege for remote operations since
  1587. * they are set up by server logon anyway.
  1588. */
  1589. if (!bsUser || (0 == wcslen(bsUser)))
  1590. {
  1591. // Nothing to do unless some privilege overrides have been set
  1592. long lCount = 0;
  1593. m_pPrivilegeSet->get_Count (&lCount);
  1594. if (0 < lCount)
  1595. {
  1596. /*
  1597. * For NT4 privilege settings on impersonation tokens are ignored
  1598. * by DCOM/RPC. Hence we have to set this on the process token.
  1599. *
  1600. * On NT4 we must set the configured privileges on the Process
  1601. * Token before the first call to RPC (i.e. IWbemLocator::ConnectServer)
  1602. * if we need to guarantee privilege settings will be communicated to
  1603. * the server.
  1604. *
  1605. * This is because (a) NT4 does not support cloaking to allow the
  1606. * impersonation (i.e. thread) token privilege setting to propagate
  1607. * on a per-DCOM call basis, (b) changes to Process-token level
  1608. * privileges _may_ be ignored after the first remote DCOM call due
  1609. * to RPC caching behavior.
  1610. *
  1611. * Note that this is a non-reversible operation, and is highly discouraged
  1612. * on apps (such as IE and IIS) which host multiple "tasks" since it adjusts
  1613. * the Privilege set for all of the other threads in the process.
  1614. */
  1615. HANDLE hProcess = GetCurrentProcess ();
  1616. HANDLE hProcessToken = NULL;
  1617. result = OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hProcessToken);
  1618. CloseHandle (hProcess);
  1619. if (result)
  1620. {
  1621. #ifdef WSCRPDEBUG
  1622. CSWbemSecurity::PrintPrivileges (hProcessToken);
  1623. #endif
  1624. result = CSWbemSecurity::AdjustTokenPrivileges (hProcessToken, m_pPrivilegeSet);
  1625. #ifdef WSCRPDEBUG
  1626. CSWbemSecurity::PrintPrivileges (hProcessToken);
  1627. #endif
  1628. CloseHandle (hProcessToken);
  1629. }
  1630. }
  1631. }
  1632. }
  1633. }
  1634. return result;
  1635. }
  1636. //***************************************************************************
  1637. //
  1638. // SCODE CWbemLocatorSecurity::ResetSecurity
  1639. //
  1640. // DESCRIPTION:
  1641. //
  1642. // Restore Privileges on the Thread Token.
  1643. //
  1644. //***************************************************************************
  1645. void CWbemLocatorSecurity::ResetSecurity (
  1646. HANDLE hThreadToken
  1647. )
  1648. {
  1649. // Win9x has no concept of impersonation
  1650. // On NT5 we never set privileges through this class anyway
  1651. if (CSWbemSecurity::IsNT () && (4 >= CSWbemSecurity::GetNTMajorVersion ())
  1652. && hThreadToken)
  1653. {
  1654. /*
  1655. * Set the supplied token back into
  1656. * the current thread.
  1657. */
  1658. BOOL result = SetThreadToken (NULL, hThreadToken);
  1659. #ifdef WSCRPDEBUG
  1660. // Print out the current privileges to see what's changed
  1661. HANDLE hToken = NULL;
  1662. if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, false, &hToken))
  1663. {
  1664. // No thread token - go for the Process token instead
  1665. HANDLE hProcess = GetCurrentProcess ();
  1666. OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
  1667. CloseHandle (hProcess);
  1668. }
  1669. if (hToken)
  1670. {
  1671. CSWbemSecurity::PrintPrivileges (hToken);
  1672. CloseHandle (hToken);
  1673. }
  1674. #endif
  1675. CloseHandle (hThreadToken);
  1676. }
  1677. }
  1678. //***************************************************************************
  1679. //
  1680. // SCODE CSWbemSecurity::MapImpersonationLevel
  1681. //
  1682. // DESCRIPTION:
  1683. //
  1684. // Function to map enum value of WbemImpersonationLevelEnum to SECURITY_IMPERSONATION_LEVEL
  1685. //
  1686. //***************************************************************************
  1687. SECURITY_IMPERSONATION_LEVEL CSWbemSecurity::MapImpersonationLevel(WbemImpersonationLevelEnum ImpersonationLevel)
  1688. {
  1689. SECURITY_IMPERSONATION_LEVEL ret = SecurityAnonymous;
  1690. switch (ImpersonationLevel)
  1691. {
  1692. case wbemImpersonationLevelAnonymous:
  1693. ret = SecurityAnonymous;
  1694. break;
  1695. case wbemImpersonationLevelIdentify:
  1696. ret = SecurityIdentification;
  1697. break;
  1698. case wbemImpersonationLevelImpersonate:
  1699. ret = SecurityImpersonation;
  1700. break;
  1701. case wbemImpersonationLevelDelegate:
  1702. ret = SecurityDelegation;
  1703. break;
  1704. default:
  1705. break;
  1706. }
  1707. return ret;
  1708. }
  1709. #ifdef WSCRPDEBUG
  1710. //***************************************************************************
  1711. //
  1712. // SCODE CSWbemSecurity::PrintPrivileges
  1713. //
  1714. // DESCRIPTION:
  1715. //
  1716. // Debug logging for privileges and other token info
  1717. //
  1718. //***************************************************************************
  1719. void CSWbemSecurity::PrintPrivileges (HANDLE hToken)
  1720. {
  1721. DWORD dwSize = sizeof (TOKEN_PRIVILEGES);
  1722. TOKEN_PRIVILEGES *tp = (TOKEN_PRIVILEGES *) new BYTE [dwSize];
  1723. if (!tp)
  1724. {
  1725. return;
  1726. }
  1727. DWORD dwRequiredSize = 0;
  1728. DWORD dwLastError = 0;
  1729. FILE *fDebug = fopen ("C:/temp/wmidsec.txt", "a+");
  1730. fprintf (fDebug, "\n\n***********************************************\n\n");
  1731. bool status = false;
  1732. // Step 0 - get impersonation level
  1733. SECURITY_IMPERSONATION_LEVEL secImpLevel;
  1734. if (GetTokenInformation (hToken, TokenImpersonationLevel, &secImpLevel,
  1735. sizeof (SECURITY_IMPERSONATION_LEVEL), &dwRequiredSize))
  1736. {
  1737. switch (secImpLevel)
  1738. {
  1739. case SecurityAnonymous:
  1740. fprintf (fDebug, "IMPERSONATION LEVEL: Anonymous\n");
  1741. break;
  1742. case SecurityIdentification:
  1743. fprintf (fDebug, "IMPERSONATION LEVEL: Identification\n");
  1744. break;
  1745. case SecurityImpersonation:
  1746. fprintf (fDebug, "IMPERSONATION LEVEL: Impersonation\n");
  1747. break;
  1748. case SecurityDelegation:
  1749. fprintf (fDebug, "IMPERSONATION LEVEL: Delegation\n");
  1750. break;
  1751. default:
  1752. fprintf (fDebug, "IMPERSONATION LEVEL: Unknown!\n");
  1753. break;
  1754. }
  1755. fflush (fDebug);
  1756. }
  1757. DWORD dwUSize = sizeof (TOKEN_USER);
  1758. TOKEN_USER *tu = (TOKEN_USER *) new BYTE [dwUSize];
  1759. if (!tu)
  1760. {
  1761. delete [] tp;
  1762. fclose (fDebug);
  1763. return;
  1764. }
  1765. // Step 1 - get user info
  1766. if (0 == GetTokenInformation (hToken, TokenUser,
  1767. (LPVOID) tu, dwUSize, &dwRequiredSize))
  1768. {
  1769. delete [] tu;
  1770. dwUSize = dwRequiredSize;
  1771. dwRequiredSize = 0;
  1772. tu = (TOKEN_USER *) new BYTE [dwUSize];
  1773. if (!tu)
  1774. {
  1775. delete [] tp;
  1776. fclose (fDebug);
  1777. return;
  1778. }
  1779. if (!GetTokenInformation (hToken, TokenUser, (LPVOID) tu, dwUSize,
  1780. &dwRequiredSize))
  1781. dwLastError = GetLastError ();
  1782. else
  1783. status = true;
  1784. }
  1785. if (status)
  1786. {
  1787. // Dig out the user info
  1788. dwRequiredSize = BUFSIZ;
  1789. char *userName = new char [dwRequiredSize];
  1790. char *domainName = new char [dwRequiredSize];
  1791. if (!userName || !domainName)
  1792. {
  1793. delete [] tp;
  1794. delete [] tu;
  1795. delete [] userName;
  1796. delete [] domainName;
  1797. return;
  1798. }
  1799. SID_NAME_USE eUse;
  1800. LookupAccountSid (NULL, (tu->User).Sid, userName, &dwRequiredSize,
  1801. domainName, &dwRequiredSize, &eUse);
  1802. fprintf (fDebug, "USER: [%s\\%s]\n", domainName, userName);
  1803. fflush (fDebug);
  1804. delete [] userName;
  1805. delete [] domainName;
  1806. }
  1807. else
  1808. {
  1809. fprintf (fDebug, " FAILED : %d\n", dwLastError);
  1810. fflush (fDebug);
  1811. }
  1812. delete [] tu;
  1813. status = false;
  1814. dwRequiredSize = 0;
  1815. // Step 2 - get privilege info
  1816. if (0 == GetTokenInformation (hToken, TokenPrivileges,
  1817. (LPVOID) tp, dwSize, &dwRequiredSize))
  1818. {
  1819. delete [] tp;
  1820. dwSize = dwRequiredSize;
  1821. dwRequiredSize = 0;
  1822. tp = (TOKEN_PRIVILEGES *) new BYTE [dwSize];
  1823. if (!tp)
  1824. {
  1825. fclose (fDebug);
  1826. return;
  1827. }
  1828. if (!GetTokenInformation (hToken, TokenPrivileges,
  1829. (LPVOID) tp, dwSize, &dwRequiredSize))
  1830. {
  1831. dwLastError = GetLastError ();
  1832. }
  1833. else
  1834. status = true;
  1835. }
  1836. else
  1837. status = true;
  1838. if (status)
  1839. {
  1840. fprintf (fDebug, "PRIVILEGES: [%d]\n", tp->PrivilegeCount);
  1841. fflush (fDebug);
  1842. for (DWORD i = 0; i < tp->PrivilegeCount; i++)
  1843. {
  1844. DWORD dwNameSize = 256;
  1845. LPTSTR name = new TCHAR [dwNameSize + 1];
  1846. if (!name)
  1847. {
  1848. delete [] tp;
  1849. fclose (fDebug);
  1850. return;
  1851. }
  1852. DWORD dwRequiredSize = dwNameSize;
  1853. if (LookupPrivilegeName (NULL, &(tp->Privileges [i].Luid), name, &dwRequiredSize))
  1854. {
  1855. BOOL enabDefault = (tp->Privileges [i].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT);
  1856. BOOL enabled = (tp->Privileges [i].Attributes & SE_PRIVILEGE_ENABLED);
  1857. BOOL usedForAccess (tp->Privileges [i].Attributes & SE_PRIVILEGE_USED_FOR_ACCESS);
  1858. fprintf (fDebug, " %s: enabledByDefault=%d enabled=%d usedForAccess=%d\n",
  1859. name, enabDefault, enabled, usedForAccess);
  1860. fflush (fDebug);
  1861. }
  1862. else
  1863. {
  1864. dwLastError = GetLastError ();
  1865. delete [] name;
  1866. dwNameSize = dwRequiredSize;
  1867. name = new TCHAR [dwRequiredSize];
  1868. if (!name)
  1869. {
  1870. delete [] tp;
  1871. fclose (fDebug);
  1872. return;
  1873. }
  1874. if (LookupPrivilegeName (NULL, &(tp->Privileges [i].Luid), name, &dwRequiredSize))
  1875. {
  1876. BOOL enabDefault = (tp->Privileges [i].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT);
  1877. BOOL enabled = (tp->Privileges [i].Attributes & SE_PRIVILEGE_ENABLED);
  1878. BOOL usedForAccess (tp->Privileges [i].Attributes & SE_PRIVILEGE_USED_FOR_ACCESS);
  1879. fprintf (fDebug, " %s: enabledByDefault=%d enabled=%d usedForAccess=%d\n",
  1880. name, enabDefault, enabled, usedForAccess);
  1881. fflush (fDebug);
  1882. }
  1883. else
  1884. dwLastError = GetLastError ();
  1885. }
  1886. delete [] name;
  1887. }
  1888. }
  1889. else
  1890. {
  1891. fprintf (fDebug, " FAILED : %d\n", dwLastError);
  1892. fflush (fDebug);
  1893. }
  1894. delete [] tp;
  1895. fclose (fDebug);
  1896. }
  1897. #endif