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.

1720 lines
51 KiB

  1. //*************************************************************
  2. //
  3. // Microsoft Confidential. Copyright (c) Microsoft Corporation 1999. All rights reserved
  4. //
  5. // File: diagprov.cpp
  6. //
  7. // Description: Rsop diagnostic mode provider
  8. //
  9. // History: 8-20-99 leonardm Created
  10. //
  11. //*************************************************************
  12. #include "uenv.h"
  13. #include "diagprov.h"
  14. #include "rsopinc.h"
  15. #include "Indicate.h"
  16. #include "rsopdbg.h"
  17. #include "rsopsec.h"
  18. #include <strsafe.h>
  19. HRESULT EnumerateUserNameSpace( IWbemLocator *pWbemLocator, HANDLE hToken, SAFEARRAY **psaUserSids );
  20. HRESULT UpdateGPCoreStatus(IWbemLocator *pWbemLocator,
  21. LPWSTR szSid, LPWSTR szNameSpace);
  22. //*************************************************************
  23. // TranslateNameXForest
  24. DWORD DsNameErrorMap[] = { ERROR_SUCCESS,
  25. ERROR_NO_SUCH_USER,
  26. ERROR_NO_SUCH_USER,
  27. ERROR_NONE_MAPPED,
  28. ERROR_NONE_MAPPED,
  29. ERROR_SOME_NOT_MAPPED,
  30. ERROR_SOME_NOT_MAPPED
  31. };
  32. #define MapDsNameError( x ) ((x < sizeof( DsNameErrorMap ) / sizeof( DWORD ) ) ? \
  33. DsNameErrorMap[ x ] : ERROR_GEN_FAILURE )
  34. extern "C" BOOLEAN TranslateNameXForest (
  35. LPTSTR szDomain, // Domain where the name should be resolved
  36. LPCTSTR lpAccountName, // object name
  37. DS_NAME_FORMAT AccountNameFormat, // name format
  38. DS_NAME_FORMAT DesiredNameFormat, // new name format
  39. LPTSTR *lpTranslatedName // returned name buffer
  40. );
  41. //*************************************************************
  42. //
  43. // GetMachAccountName()
  44. //
  45. // Purpose: Gets Machine account name
  46. //
  47. // Return: Machine Account
  48. //
  49. //*************************************************************
  50. LPTSTR GetMachAccountName()
  51. {
  52. return MyGetComputerName(NameSamCompatible);
  53. }
  54. BOOLEAN
  55. TranslateNameXForest (
  56. LPTSTR szDomain, // Domain where the name should be resolved
  57. LPCTSTR lpAccountName, // object name
  58. DS_NAME_FORMAT AccountNameFormat, // name format
  59. DS_NAME_FORMAT DesiredNameFormat, // new name format
  60. LPTSTR *lpTranslatedName // returned name buffer
  61. )
  62. {
  63. BOOL bRetry = FALSE;
  64. DWORD dwErr;
  65. PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
  66. HANDLE hDS = NULL;
  67. XLastError xe;
  68. PDS_NAME_RESULT pResult = NULL;
  69. BOOLEAN bRet = FALSE;
  70. XPtrLF<WCHAR> xszTransName;
  71. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"MyTranslateName: Resolving name <%s> at Domain <%s>", lpAccountName, szDomain ? szDomain : L"");
  72. //
  73. // get a DC and bind to it. Make sure to force rediscover a DC if the bind fails
  74. //
  75. for (;;) {
  76. dwErr = DsGetDcName( NULL,
  77. szDomain ? szDomain : L"",
  78. NULL,
  79. NULL,
  80. DS_DIRECTORY_SERVICE_REQUIRED |
  81. DS_RETURN_DNS_NAME |
  82. (bRetry ? DS_FORCE_REDISCOVERY : 0) |
  83. 0,
  84. &pDCInfo );
  85. if (dwErr == NO_ERROR) {
  86. dwErr = DsBind( pDCInfo->DomainControllerName,
  87. NULL,
  88. &hDS );
  89. if (dwErr == NO_ERROR) {
  90. break;
  91. }
  92. else {
  93. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MyTranslateName: Failed to bind to DC <%s> with error %d",
  94. pDCInfo->DomainControllerName, dwErr );
  95. NetApiBufferFree(pDCInfo);
  96. pDCInfo = NULL;
  97. }
  98. }
  99. else {
  100. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MyTranslateName: Failed to get DC for domain <%s> with error %d",
  101. szDomain ? szDomain : L"", dwErr );
  102. }
  103. //
  104. // Failed to bind to a DC. bail
  105. //
  106. if (bRetry) {
  107. xe = dwErr;
  108. goto Exit;
  109. }
  110. bRetry = TRUE;
  111. }
  112. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"MyTranslateName: DC selected is <%s>", pDCInfo->DomainControllerName);
  113. //
  114. // Now crack names with the DC that is bound
  115. //
  116. dwErr = DsCrackNames( hDS,
  117. DS_NAME_NO_FLAGS,
  118. AccountNameFormat,
  119. DesiredNameFormat,
  120. 1,
  121. &lpAccountName,
  122. &pResult);
  123. if (dwErr != DS_NAME_NO_ERROR) {
  124. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MyTranslateName: Failed to crack names with error %d", dwErr );
  125. xe = dwErr;
  126. goto Exit;
  127. }
  128. if ( pResult->cItems == 0 ) {
  129. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MyTranslateName: Failed to return enough result items" );
  130. xe = dwErr = ERROR_INVALID_DATA;
  131. goto Exit;
  132. }
  133. if ( pResult->rItems[0].status == DS_NAME_NO_ERROR ) {
  134. //
  135. // In case of no error, return the resolved name
  136. //
  137. DWORD dwTransNameLength = 1 + lstrlen(pResult->rItems[0].pName);
  138. xszTransName = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR) * ( dwTransNameLength ));
  139. if (!xszTransName) {
  140. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MyTranslateName: Failed to allocate memory for domain" );
  141. xe = dwErr = GetLastError();
  142. goto Exit;
  143. }
  144. HRESULT hr = StringCchCopy(xszTransName, dwTransNameLength, pResult->rItems[0].pName);
  145. if(FAILED(hr)) {
  146. xe = dwErr = HRESULT_CODE(hr);
  147. goto Exit;
  148. }
  149. *lpTranslatedName = xszTransName.Acquire();
  150. }
  151. else {
  152. //
  153. // remap the error code to win32 error
  154. //
  155. xe = dwErr = MapDsNameError(pResult->rItems[0].status);
  156. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MyTranslateName: DsCrackNames failed with error %d", pResult->rItems[0].status );
  157. goto Exit;
  158. }
  159. bRet = TRUE;
  160. Exit:
  161. if ( pDCInfo ) {
  162. NetApiBufferFree(pDCInfo);
  163. }
  164. if (hDS) {
  165. DsUnBind( &hDS );
  166. }
  167. if (pResult) {
  168. DsFreeNameResult(pResult);
  169. }
  170. return bRet;
  171. }
  172. //*************************************************************
  173. //
  174. // GetSOMFromSID()
  175. //
  176. // Purpose: Finds out the FQDN of a given user/computer given the SID
  177. // It reads from the cache that we have already maintained
  178. //
  179. // Parameters: szSID - User Sid or NULL for machine account
  180. //
  181. // Return: SOM, NULL otherwise. GetLastError() for details
  182. // This just returns the DN of the user
  183. //
  184. //*************************************************************
  185. LPWSTR GetSOMFromSID(LPWSTR szSID)
  186. {
  187. BOOL bMachine = FALSE;
  188. HRESULT hr = S_OK;
  189. XLastError xe;
  190. XPtrLF<WCHAR> xszName;
  191. XPtrLF<WCHAR> xszFinalName;
  192. DWORD dwError, dwType, dwSize;
  193. XKey xhKeyState;
  194. XPtrLF<WCHAR> xszKeyState;
  195. XPtrLF<WCHAR> xszMachAccount;
  196. XPtrLF<WCHAR> xszDomain;
  197. DWORD dwKeyStateLength = lstrlen(GP_STATE_KEY) + lstrlen(szSID ? szSID : L"Machine") + 1;
  198. xszKeyState = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR) * ( dwKeyStateLength ));
  199. if (!xszKeyState) {
  200. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Failed to allocate memory. Error - %d", GetLastError() );
  201. xe = GetLastError();
  202. return NULL;
  203. }
  204. if ( !szSID )
  205. {
  206. bMachine = TRUE;
  207. hr = StringCchPrintf( xszKeyState, dwKeyStateLength, GP_STATE_KEY, L"Machine" );
  208. }
  209. else
  210. {
  211. hr = StringCchPrintf( xszKeyState, dwKeyStateLength, GP_STATE_KEY, szSID );
  212. }
  213. if (FAILED(hr)) {
  214. xe = HRESULT_CODE(hr);
  215. return NULL;
  216. }
  217. dwSize = 0;
  218. dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  219. xszKeyState,
  220. 0,
  221. KEY_READ,
  222. &xhKeyState );
  223. if ( dwError != ERROR_SUCCESS )
  224. {
  225. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Failed to open state key for %s. Error - %d", (LPWSTR)xszKeyState, dwError );
  226. xe = dwError;
  227. return NULL;
  228. }
  229. dwError = RegQueryValueEx(xhKeyState,
  230. DN,
  231. 0,
  232. &dwType,
  233. NULL,
  234. &dwSize );
  235. if ( dwError != ERROR_SUCCESS )
  236. {
  237. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Failed to get the size of DN value. Error - %d", dwError );
  238. xe = dwError;
  239. return NULL;
  240. }
  241. xszName = (LPWSTR)LocalAlloc(LPTR, dwSize+2);
  242. if ( !xszName ) {
  243. xe = GetLastError();
  244. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Failed to get the size of DN value. Error - %d", GetLastError() );
  245. return NULL;
  246. }
  247. dwError = RegQueryValueEx(xhKeyState,
  248. DN,
  249. 0,
  250. &dwType,
  251. (LPBYTE)(LPWSTR)xszName,
  252. &dwSize );
  253. if ( dwError != ERROR_SUCCESS )
  254. {
  255. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Failed to get the size of DN value. Error - %d", dwError );
  256. xe = dwError;
  257. return NULL;
  258. }
  259. if (xszName[0] == L'\0') {
  260. xe = ERROR_NON_DOMAIN_SID;
  261. return NULL;
  262. }
  263. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"GetSOMFromSID: Som for SID <%s> in registry is %s.", szSID ? szSID : L"Machine", (LPWSTR)xszName );
  264. //
  265. // Confirming that the SOMs haven't changed since the last time the user was logged on
  266. // get the domain and requery for the som
  267. //
  268. dwError = GetDomain(xszName, &xszDomain);
  269. if (dwError != ERROR_SUCCESS) {
  270. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Cannot get the domain from the som path. Error - %d", dwError );
  271. xe = dwError;
  272. return NULL;
  273. }
  274. if (bMachine) {
  275. xszMachAccount = GetMachAccountName();
  276. if (!xszMachAccount) {
  277. xe = GetLastError();
  278. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Couldn't get the machine account. Error - %d", GetLastError() );
  279. return NULL;
  280. }
  281. if (!TranslateNameXForest( xszDomain, xszMachAccount, DS_NT4_ACCOUNT_NAME, DS_FQDN_1779_NAME, &xszFinalName)) {
  282. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Translate name failed for machine account. Error - %d", GetLastError() );
  283. }
  284. else {
  285. xszName = xszFinalName.Acquire();
  286. }
  287. }
  288. else {
  289. if (!TranslateNameXForest( xszDomain, szSID, DS_SID_OR_SID_HISTORY_NAME, DS_FQDN_1779_NAME, &xszFinalName)) {
  290. dbg.Msg( DEBUG_MESSAGE_WARNING, L"GetSOMFromSID: Translate name failed for user account. Error - %d", GetLastError() );
  291. }
  292. else {
  293. xszName = xszFinalName.Acquire();
  294. }
  295. }
  296. return xszName.Acquire();
  297. }
  298. //*************************************************************
  299. //
  300. // CheckRsopDiagPolicyInteractive()
  301. //
  302. // Purpose: Can this user get the rsop data even if the user is logged
  303. // on interactively
  304. //
  305. // Parameters:
  306. //
  307. // Return: CheckRsopDiagPolicyInteractive
  308. //
  309. //*************************************************************
  310. BOOL CheckRsopDiagPolicyInteractive()
  311. {
  312. HKEY hKeyUser = NULL;
  313. HKEY hKey;
  314. DWORD dwSize = 0, dwType = 0;
  315. BOOL bDeny = FALSE;
  316. HRESULT hr = CoImpersonateClient();
  317. if ( FAILED(hr) )
  318. {
  319. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CheckRsopDiagPolicyInteractive::CoImpersonateClient failed with 0x%x"), hr );
  320. }
  321. else if (!RegOpenCurrentUser(KEY_READ, &hKeyUser) == ERROR_SUCCESS)
  322. {
  323. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CheckRsopDiagPolicyInteractive:: couldn't access registry of interactive user."));
  324. hKeyUser = NULL;
  325. }
  326. CoRevertToSelf();
  327. //
  328. // First, check for a user preference
  329. //
  330. if (hKeyUser) {
  331. if (RegOpenKeyEx (hKeyUser, WINLOGON_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  332. dwSize = sizeof(bDeny);
  333. RegQueryValueEx (hKey, DENY_RSOP_FROM_INTERACTIVE_USER, NULL, &dwType,
  334. (LPBYTE) &bDeny, &dwSize);
  335. RegCloseKey (hKey);
  336. }
  337. }
  338. //
  339. // Check for a machine preference
  340. //
  341. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, WINLOGON_KEY, 0,
  342. KEY_READ, &hKey) == ERROR_SUCCESS) {
  343. dwSize = sizeof(bDeny);
  344. RegQueryValueEx (hKey, DENY_RSOP_FROM_INTERACTIVE_USER, NULL, &dwType,
  345. (LPBYTE) &bDeny, &dwSize);
  346. RegCloseKey (hKey);
  347. }
  348. //
  349. // Check for a user policy
  350. //
  351. if (hKeyUser) {
  352. if (RegOpenKeyEx (hKeyUser, SYSTEM_POLICIES_KEY, 0,
  353. KEY_READ, &hKey) == ERROR_SUCCESS) {
  354. dwSize = sizeof(bDeny);
  355. RegQueryValueEx (hKey, DENY_RSOP_FROM_INTERACTIVE_USER, NULL, &dwType,
  356. (LPBYTE) &bDeny, &dwSize);
  357. RegCloseKey (hKey);
  358. }
  359. }
  360. //
  361. // Check for a machine policy
  362. //
  363. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, SYSTEM_POLICIES_KEY, 0,
  364. KEY_READ, &hKey) == ERROR_SUCCESS) {
  365. dwSize = sizeof(bDeny);
  366. RegQueryValueEx (hKey, DENY_RSOP_FROM_INTERACTIVE_USER, NULL, &dwType,
  367. (LPBYTE) &bDeny, &dwSize);
  368. RegCloseKey (hKey);
  369. }
  370. if (hKeyUser) {
  371. RegCloseKey(hKeyUser);
  372. }
  373. return (!bDeny);
  374. }
  375. //*************************************************************
  376. //
  377. // Functions: Constructor, Destructor, QueryInterface, AddRef, Release
  378. //
  379. //*************************************************************
  380. CSnapProv::CSnapProv()
  381. : m_cRef(1),
  382. m_bInitialized(false),
  383. m_pNamespace(NULL)
  384. {
  385. InterlockedIncrement(&g_cObj);
  386. m_xbstrUserSid = L"userSid";
  387. if ( !m_xbstrUserSid )
  388. return;
  389. m_xbstrUserSids = L"userSids";
  390. if ( !m_xbstrUserSids )
  391. return;
  392. m_xbstrNameSpace = L"nameSpace";
  393. if ( !m_xbstrNameSpace )
  394. return;
  395. m_xbstrResult = L"hResult";
  396. if ( !m_xbstrResult )
  397. return;
  398. m_xbstrFlags = L"flags";
  399. if ( !m_xbstrFlags )
  400. return;
  401. m_xbstrExtendedInfo = L"ExtendedInfo";
  402. if ( !m_xbstrExtendedInfo )
  403. return;
  404. m_xbstrClass = L"RsopLoggingModeProvider";
  405. if ( !m_xbstrClass )
  406. return;
  407. m_bInitialized = TRUE;
  408. }
  409. CSnapProv::~CSnapProv()
  410. {
  411. if(m_pNamespace != NULL)
  412. {
  413. m_pNamespace->Release();
  414. }
  415. InterlockedDecrement(&g_cObj);
  416. }
  417. STDMETHODIMP CSnapProv::QueryInterface (REFIID riid, LPVOID* ppv)
  418. {
  419. if(riid == IID_IUnknown || riid == IID_IWbemServices)
  420. {
  421. *ppv = static_cast<IWbemServices*>(this);
  422. }
  423. else if(riid == IID_IWbemProviderInit)
  424. {
  425. *ppv = static_cast<IWbemProviderInit*>(this);
  426. }
  427. else
  428. {
  429. *ppv=NULL;
  430. return E_NOINTERFACE;
  431. }
  432. AddRef();
  433. return S_OK;
  434. }
  435. STDMETHODIMP_(ULONG) CSnapProv::AddRef()
  436. {
  437. return InterlockedIncrement( &m_cRef );
  438. }
  439. STDMETHODIMP_(ULONG) CSnapProv::Release()
  440. {
  441. if (!InterlockedDecrement(&m_cRef))
  442. {
  443. delete this;
  444. return 0;
  445. }
  446. return m_cRef;
  447. }
  448. //*************************************************************
  449. //
  450. // Initialize()
  451. //
  452. // Purpose: WbemProvider's initialize method
  453. //
  454. // Parameters: See IWbemProivderInit::Initialize
  455. //
  456. // Return: hresult
  457. //
  458. //*************************************************************
  459. STDMETHODIMP CSnapProv::Initialize( LPWSTR pszUser,
  460. LONG lFlags,
  461. LPWSTR pszNamespace,
  462. LPWSTR pszLocale,
  463. IWbemServices __RPC_FAR *pNamespace,
  464. IWbemContext __RPC_FAR *pCtx,
  465. IWbemProviderInitSink __RPC_FAR *pInitSink)
  466. {
  467. HRESULT hr;
  468. if ( !m_bInitialized ) {
  469. hr = pInitSink->SetStatus(E_FAIL, 0);
  470. return hr;
  471. }
  472. //
  473. // No need to authenticate user. The ACLs on Rsop namespace will
  474. // deny access to users that cannot snapshot diagnostic mode data.
  475. //
  476. m_pNamespace = pNamespace;
  477. m_pNamespace->AddRef();
  478. hr = pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  479. return hr;
  480. }
  481. #if _MSC_FULL_VER <= 13008827 && defined(_M_IX86)
  482. #pragma optimize("", off)
  483. #endif
  484. //*************************************************************
  485. //
  486. // ExecMethodAsync()
  487. //
  488. // Purpose: Execute method
  489. //
  490. // Parameters: See IWbemServices::ExecMethodAsync
  491. //
  492. // Return: hresult
  493. //
  494. //*************************************************************
  495. STDMETHODIMP CSnapProv::ExecMethodAsync( const BSTR bstrObject,
  496. const BSTR bstrMethod,
  497. long lFlags,
  498. IWbemContext __RPC_FAR *pCtx,
  499. IWbemClassObject __RPC_FAR *pInParams,
  500. IWbemObjectSink __RPC_FAR *pResponseHandler)
  501. {
  502. HRESULT hr;
  503. CFailRetStatus retStatus( pResponseHandler );
  504. IUnknown *pOldSecContext;
  505. //
  506. // Make sure the provider is properly initialized
  507. //
  508. //
  509. // Allow for debugging level to be dynamically changed during queries
  510. //
  511. dbgRsop.Initialize( L"Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon",
  512. L"RsopDebugLevel",
  513. L"userenv.log",
  514. L"userenv.bak",
  515. FALSE );
  516. InitDebugSupport(0);
  517. if ( !m_bInitialized )
  518. {
  519. hr = E_OUTOFMEMORY;
  520. retStatus.SetError( hr );
  521. return hr;
  522. }
  523. //
  524. // Initialize the return status object to fail status
  525. //
  526. IWbemLocator *pWbemLocator = NULL;
  527. hr = CoCreateInstance( CLSID_WbemAuthenticatedLocator,
  528. NULL,
  529. CLSCTX_INPROC_SERVER,
  530. IID_IWbemLocator,
  531. (LPVOID *) &pWbemLocator );
  532. if ( FAILED(hr) )
  533. {
  534. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecMethodAsync: CoCreateInstance returned 0x%x"), hr );
  535. retStatus.SetError( hr );
  536. return hr;
  537. }
  538. XInterface<IWbemLocator> xLocator( pWbemLocator );
  539. IWbemClassObject* pProvClass = NULL;
  540. IWbemClassObject* pOutClass = NULL;
  541. IWbemClassObject* pOutParams = NULL;
  542. hr = m_pNamespace->GetObject( m_xbstrClass, 0, pCtx, &pProvClass, NULL);
  543. if ( FAILED(hr) )
  544. {
  545. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::GetObject failed with 0x%x."), hr );
  546. retStatus.SetError( hr );
  547. return hr;
  548. }
  549. XInterface<IWbemClassObject> xProvClass( pProvClass );
  550. hr = pProvClass->GetMethod( bstrMethod, 0, NULL, &pOutClass);
  551. if ( FAILED(hr) )
  552. {
  553. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::GetMethod failed with 0x%x."), hr );
  554. retStatus.SetError( hr );
  555. return hr;
  556. }
  557. XInterface<IWbemClassObject> xOutClass( pOutClass );
  558. hr = pOutClass->SpawnInstance(0, &pOutParams);
  559. if ( FAILED(hr) )
  560. {
  561. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::SpawnInstance failed with 0x%x."), hr );
  562. retStatus.SetError( hr );
  563. return hr;
  564. }
  565. //
  566. // Get the tokens and Sids upfront
  567. //
  568. XPtrLF <WCHAR> xszSidString;
  569. XPtrLF <SID> xSid;
  570. XHandle xUserToken;
  571. hr = CoImpersonateClient();
  572. if ( FAILED(hr) )
  573. {
  574. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoImpersonateClient failed with 0x%x"), hr );
  575. retStatus.SetError( hr );
  576. return hr;
  577. }
  578. if (OpenThreadToken (GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &xUserToken)) {
  579. LPWSTR szSid = GetSidString(xUserToken);
  580. if (!szSid) {
  581. hr = HRESULT_FROM_WIN32(GetLastError());
  582. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::GetSidString failed with %d"), GetLastError() );
  583. CoRevertToSelf();
  584. retStatus.SetError( hr );
  585. return hr;
  586. }
  587. else {
  588. DWORD szSidStrLength = lstrlen(szSid) + 1;
  589. xszSidString = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR) * ( szSidStrLength ));
  590. if (!xszSidString) {
  591. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::LocalAlloc failed with %d"), GetLastError() );
  592. hr = HRESULT_FROM_WIN32(GetLastError());
  593. DeleteSidString(szSid);
  594. CoRevertToSelf();
  595. retStatus.SetError( hr );
  596. return hr;
  597. }
  598. hr = StringCchCopy(xszSidString, szSidStrLength, szSid);
  599. if(FAILED(hr)){
  600. DeleteSidString(szSid);
  601. CoRevertToSelf();
  602. retStatus.SetError( hr );
  603. return hr;
  604. }
  605. DeleteSidString(szSid);
  606. }
  607. xSid = (SID *)GetUserSid(xUserToken);
  608. if (!xSid) {
  609. hr = HRESULT_FROM_WIN32(GetLastError());
  610. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::GetUserSid failed with %d"), GetLastError() );
  611. CoRevertToSelf();
  612. retStatus.SetError( hr );
  613. return hr;
  614. }
  615. } else {
  616. hr = HRESULT_FROM_WIN32(GetLastError());
  617. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Openthreadtoken failed with 0x%x"), hr );
  618. CoRevertToSelf();
  619. retStatus.SetError( hr );
  620. return hr;
  621. }
  622. CoRevertToSelf();
  623. XInterface<IWbemClassObject> xOutParams( pOutParams );
  624. if ( _wcsicmp( (WCHAR *) bstrMethod, L"RsopDeleteSession" ) == 0 ) {
  625. //
  626. // rsopdeletesession
  627. //
  628. VARIANT vNameSpace;
  629. hr = pInParams->Get( m_xbstrNameSpace, 0, &vNameSpace, NULL, NULL);
  630. if ( FAILED(hr) )
  631. {
  632. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Get machine name failed with 0x%x."), hr );
  633. retStatus.SetError( hr );
  634. return hr;
  635. }
  636. XVariant xvNameSpace( &vNameSpace );
  637. if (vNameSpace.vt != VT_NULL ) {
  638. //
  639. // We want to run as LS
  640. //
  641. hr = CoSwitchCallContext(NULL, &pOldSecContext);
  642. if (FAILED(hr)) {
  643. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr );
  644. retStatus.SetError( hr );
  645. return hr;
  646. }
  647. hr = ProviderDeleteRsopNameSpace( pWbemLocator,
  648. vNameSpace.bstrVal,
  649. xUserToken,
  650. xszSidString,
  651. SETUP_NS_SM);
  652. IUnknown *pNewObject;
  653. HRESULT hr2 = CoSwitchCallContext(pOldSecContext, &pNewObject);
  654. if (FAILED(hr2)) {
  655. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr2 );
  656. }
  657. }
  658. else {
  659. hr = E_INVALIDARG;
  660. }
  661. VARIANT var;
  662. var.vt = VT_I4;
  663. var.lVal = hr;
  664. hr = pOutParams->Put( m_xbstrResult, 0, &var, 0);
  665. if ( FAILED(hr) )
  666. {
  667. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Put result failed with 0x%x"), hr );
  668. retStatus.SetError( hr );
  669. return hr;
  670. }
  671. hr = pResponseHandler->Indicate(1, &pOutParams);
  672. if ( FAILED(hr) )
  673. {
  674. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod:: Indicate failed with 0x%x"), hr );
  675. retStatus.SetError( hr );
  676. return hr;
  677. }
  678. return hr;
  679. }
  680. else if ( _wcsicmp( (WCHAR *) bstrMethod, L"RsopEnumerateUsers" ) == 0 )
  681. {
  682. //
  683. // RsopenumerateUsers
  684. //
  685. SAFEARRAY *pArray;
  686. hr = EnumerateUserNameSpace( pWbemLocator, xUserToken, &pArray );
  687. XSafeArray xsaUserSids(pArray);
  688. if ( FAILED(hr) )
  689. {
  690. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::EnumerateUserNameSpace failed") );
  691. }
  692. VARIANT var;
  693. var.vt = VT_I4;
  694. var.lVal = hr;
  695. hr = pOutParams->Put( m_xbstrResult, 0, &var, 0);
  696. if ( FAILED(hr) )
  697. {
  698. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Put result failed with 0x%x"), hr );
  699. retStatus.SetError( hr );
  700. return hr;
  701. }
  702. var.vt = VT_ARRAY | VT_BSTR;
  703. var.parray = xsaUserSids;
  704. hr = pOutParams->Put( m_xbstrUserSids, 0, &var, 0 );
  705. if ( FAILED(hr) )
  706. {
  707. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Put sids failed with 0x%x"), hr );
  708. retStatus.SetError( hr );
  709. return hr;
  710. }
  711. hr = pResponseHandler->Indicate(1, &pOutParams);
  712. if ( FAILED(hr) )
  713. {
  714. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod:: Indicate failed with 0x%x"), hr );
  715. retStatus.SetError( hr );
  716. return hr;
  717. }
  718. return hr;
  719. }
  720. //
  721. // progress indicator.
  722. // 25% done when we enter the first critical section.
  723. // 50% done when we enter the second critical section.
  724. // 100% complete when we copy the namespace.
  725. //
  726. CProgressIndicator Indicator( pResponseHandler,
  727. (lFlags & WBEM_FLAG_SEND_STATUS) != 0 );
  728. //
  729. // 5% done. Hack for UI.
  730. //
  731. hr = Indicator.IncrementBy( 5 );
  732. VARIANT vUserSid;
  733. hr = pInParams->Get( m_xbstrUserSid, 0, &vUserSid, NULL, NULL);
  734. if ( FAILED(hr) )
  735. {
  736. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Get RemoteComputer failed with 0x%x."), hr );
  737. retStatus.SetError( hr );
  738. return hr;
  739. }
  740. XVariant xvUserSid ( &vUserSid );
  741. VARIANT vFlags;
  742. VariantInit( &vFlags );
  743. hr = pInParams->Get( m_xbstrFlags, 0, &vFlags, NULL, NULL);
  744. if ( FAILED(hr) )
  745. {
  746. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Get dwFlags failed with 0x%x."), hr );
  747. retStatus.SetError( hr );
  748. return hr;
  749. }
  750. DWORD dwFlags = vFlags.vt == VT_EMPTY || vFlags.vt == VT_NULL ? 0 : vFlags.ulVal;
  751. //
  752. // Flags specific to Diagnostic mode provider
  753. //
  754. if ((dwFlags & FLAG_NO_USER) && (dwFlags & FLAG_NO_COMPUTER)) {
  755. hr = WBEM_E_INVALID_PARAMETER;
  756. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod:: Both user and computer are null."));
  757. retStatus.SetError( hr );
  758. return hr;
  759. }
  760. //
  761. // We can dump out all the input parameters here later on.
  762. //
  763. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::---------------RsopCreateSession::Input Parameters--------------------"));
  764. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::UserSid = <%s>"), vUserSid.vt == VT_NULL ? L"NULL" : vUserSid.bstrVal);
  765. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::flags = <%d>"), dwFlags);
  766. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::---------------RsopCreateSession::Input Parameters--------------------"));
  767. //
  768. // Code for RsopCreateSession method
  769. //
  770. XPtrLF<TCHAR> xszMachSOM;
  771. XPtrLF<TCHAR> xszUserSOM;
  772. BOOL bDelegated = FALSE;
  773. BOOL bCheckAccess = TRUE;
  774. DWORD dwExtendedInfo = 0;
  775. //
  776. // Get the machine SOM
  777. //
  778. if ( !(dwFlags & FLAG_NO_COMPUTER) ) {
  779. dwExtendedInfo |= RSOP_COMPUTER_ACCESS_DENIED;
  780. xszMachSOM = GetSOMFromSID(NULL);
  781. if (xszMachSOM) {
  782. dwExtendedInfo &= ~RSOP_COMPUTER_ACCESS_DENIED;
  783. }
  784. else {
  785. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::No machine SOM. error %d"), GetLastError() );
  786. }
  787. }
  788. //
  789. // Get the User SOM
  790. //
  791. if ( !(dwFlags & FLAG_NO_USER) ) {
  792. dwExtendedInfo |= RSOP_USER_ACCESS_DENIED;
  793. xszUserSOM = GetSOMFromSID(vUserSid.vt == VT_NULL ? xszSidString : vUserSid.bstrVal);
  794. if (xszUserSOM) {
  795. dwExtendedInfo &= ~RSOP_USER_ACCESS_DENIED;
  796. }
  797. else {
  798. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::No User SOM. error %d"), GetLastError() );
  799. }
  800. }
  801. // at this point we already know whether to treat the user as delegated or not...
  802. if (!xszMachSOM && !xszUserSOM)
  803. {
  804. bCheckAccess = FALSE;
  805. }
  806. //
  807. // Check access now
  808. //
  809. if (bCheckAccess) {
  810. hr = AuthenticateUser(xUserToken, xszMachSOM, xszUserSOM, TRUE, &dwExtendedInfo);
  811. if (FAILED(hr)) {
  812. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::User is not a delegated admin. Error 0x%x"), hr );
  813. hr = S_OK;
  814. }
  815. else {
  816. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::User is a delegated admin. Error 0x%x"), hr );
  817. }
  818. }
  819. if ((!(dwExtendedInfo & RSOP_USER_ACCESS_DENIED)) &&
  820. (!(dwExtendedInfo & RSOP_COMPUTER_ACCESS_DENIED)))
  821. {
  822. bDelegated = TRUE;
  823. }
  824. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecMethodAsync::Getting policy critical sections"));
  825. XCriticalPolicySection criticalPolicySectionMACHINE( EnterCriticalPolicySectionEx(TRUE, 40000, ECP_FAIL_ON_WAIT_TIMEOUT) );
  826. if ( !criticalPolicySectionMACHINE )
  827. {
  828. hr = HRESULT_FROM_WIN32( GetLastError() );
  829. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecMethodAsync::EnterCriticalPolicySection failed with 0x%x"), hr );
  830. retStatus.SetError( hr );
  831. return hr;
  832. }
  833. //
  834. // 25% done when we enter the first critical section.
  835. //
  836. hr = Indicator.IncrementBy( 20 );
  837. if ( FAILED( hr ) )
  838. {
  839. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecMethodAsync::IncrementBy() failed with 0x%x"), hr );
  840. }
  841. XCriticalPolicySection criticalPolicySectionUSER( EnterCriticalPolicySectionEx(FALSE, 40000, ECP_FAIL_ON_WAIT_TIMEOUT) );
  842. if ( !criticalPolicySectionUSER )
  843. {
  844. hr = HRESULT_FROM_WIN32( GetLastError() );
  845. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecMethodAsync::EnterCriticalPolicySection failed with 0x%x"), hr );
  846. retStatus.SetError( hr );
  847. return hr;
  848. }
  849. //
  850. // 50% done when we enter the second critical section.
  851. //
  852. hr = Indicator.IncrementBy( 25 );
  853. if ( FAILED( hr ) )
  854. {
  855. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecMethodAsync::IncrementBy() failed with 0x%x"), hr );
  856. }
  857. LPWSTR wszNameSpace = 0;
  858. //
  859. // Impersonate if not delegated
  860. //
  861. if (!bDelegated) {
  862. hr = CoImpersonateClient();
  863. if ( FAILED(hr) )
  864. {
  865. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoImpersonateClient failed with 0x%x"), hr );
  866. retStatus.SetError( hr );
  867. return hr;
  868. }
  869. }
  870. else {
  871. //
  872. // We want to run as LS
  873. //
  874. hr = CoSwitchCallContext(NULL, &pOldSecContext);
  875. if (FAILED(hr)) {
  876. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr );
  877. retStatus.SetError( hr );
  878. return hr;
  879. }
  880. }
  881. XPtrLF<WCHAR> xwszNameSpace;
  882. DWORD dwNewNameSpaceFlags = SETUP_NS_SM;
  883. dwNewNameSpaceFlags |= (dwFlags & FLAG_NO_USER) ? SETUP_NS_SM_NO_USER : 0;
  884. dwNewNameSpaceFlags |= (dwFlags & FLAG_NO_COMPUTER) ? SETUP_NS_SM_NO_COMPUTER : 0;
  885. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::UserSid = <%s>"), vUserSid.vt == VT_NULL ? L"NULL" : vUserSid.bstrVal);
  886. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::User who is running the tool = <%s>"), (LPWSTR)xszSidString);
  887. hr = SetupNewNameSpace( &xwszNameSpace,
  888. 0, // namespace on this machine
  889. (vUserSid.vt == VT_NULL) ? ((LPWSTR)xszSidString) : vUserSid.bstrVal,
  890. xSid,
  891. pWbemLocator,
  892. dwNewNameSpaceFlags,
  893. &dwExtendedInfo);
  894. if (!bDelegated) {
  895. CoRevertToSelf();
  896. }
  897. else {
  898. //
  899. // restore call context
  900. //
  901. IUnknown *pNewObject;
  902. HRESULT hr2 = CoSwitchCallContext(pOldSecContext, &pNewObject);
  903. if (FAILED(hr2)) {
  904. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr2 );
  905. }
  906. }
  907. if ( FAILED(hr) && !bDelegated)
  908. {
  909. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::SetupNewNameSpace failed with 0x%x"), hr );
  910. if (IsUserAnInteractiveUser(xUserToken) && CheckRsopDiagPolicyInteractive()) {
  911. // if the user had permissions on the computer or if the user didn't ask for computer
  912. // continue
  913. // clear out the user access denied right in any case.
  914. dwExtendedInfo &= ~RSOP_USER_ACCESS_DENIED;
  915. if ( (!(dwExtendedInfo & RSOP_COMPUTER_ACCESS_DENIED)) ||
  916. (dwFlags & FLAG_NO_COMPUTER) ) {
  917. // if the user asked for their own rsop data
  918. if ( (vUserSid.vt == VT_NULL) || (_wcsicmp(vUserSid.bstrVal, xszSidString) == 0 )) {
  919. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::SetupNewNameSpace failed. retrying in interactive mode"), hr );
  920. //
  921. // We want to run as LS
  922. //
  923. hr = CoSwitchCallContext(NULL, &pOldSecContext);
  924. if (FAILED(hr)) {
  925. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr );
  926. retStatus.SetError( hr );
  927. return hr;
  928. }
  929. //
  930. // if the namespace is null, get the name of the interactive namespace
  931. //
  932. XPtrLF<WCHAR> xszInteractiveNS;
  933. hr = GetInteractiveNameSpace(xszSidString, &xszInteractiveNS);
  934. if (FAILED(hr)) {
  935. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr );
  936. retStatus.SetError( hr );
  937. return hr;
  938. }
  939. BOOL bContinue=TRUE;
  940. if (dwFlags & FLAG_FORCE_CREATENAMESPACE) {
  941. hr = DeleteRsopNameSpace( xszInteractiveNS, pWbemLocator );
  942. // ignore error
  943. }
  944. else {
  945. XInterface<IWbemServices> xWbemServices;
  946. hr = pWbemLocator->ConnectServer( xszInteractiveNS,
  947. NULL,
  948. NULL,
  949. 0L,
  950. 0L,
  951. NULL,
  952. NULL,
  953. &xWbemServices );
  954. if (SUCCEEDED(hr)) {
  955. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod:: Namespace already exists. Failing call"));
  956. hr = WBEM_E_ALREADY_EXISTS;
  957. dwExtendedInfo = RSOP_TEMPNAMESPACE_EXISTS;
  958. bContinue = FALSE;
  959. }
  960. }
  961. if (bContinue) {
  962. dwNewNameSpaceFlags |= SETUP_NS_SM_INTERACTIVE;
  963. hr = SetupNewNameSpace( &xwszNameSpace,
  964. 0, // namespace on this machine
  965. xszSidString,
  966. xSid,
  967. pWbemLocator,
  968. dwNewNameSpaceFlags,
  969. &dwExtendedInfo);
  970. }
  971. //
  972. // restore call context
  973. //
  974. IUnknown *pNewObject;
  975. HRESULT hr2 = CoSwitchCallContext(pOldSecContext, &pNewObject);
  976. if (FAILED(hr2)) {
  977. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr2 );
  978. }
  979. }
  980. }
  981. }
  982. }
  983. if (FAILED(hr)) {
  984. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::SetupNewNameSpace failed with 0x%x"), hr );
  985. }
  986. else
  987. {
  988. HRESULT hr2;
  989. VARIANT var;
  990. //
  991. // if we managed to get a snapshot, then ignore the extended access denied info
  992. //
  993. dwExtendedInfo = 0;
  994. //
  995. // We want to run as LS
  996. //
  997. hr = CoSwitchCallContext(NULL, &pOldSecContext);
  998. if (FAILED(hr)) {
  999. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr );
  1000. retStatus.SetError( hr );
  1001. return hr;
  1002. }
  1003. if ( !(dwFlags & FLAG_NO_COMPUTER) ) {
  1004. hr = UpdateGPCoreStatus(pWbemLocator, NULL, xwszNameSpace);
  1005. }
  1006. if ( (SUCCEEDED(hr)) && (!(dwFlags & FLAG_NO_USER)) ) {
  1007. hr = UpdateGPCoreStatus(pWbemLocator,
  1008. vUserSid.vt == VT_NULL ? xszSidString : vUserSid.bstrVal,
  1009. xwszNameSpace);
  1010. }
  1011. //
  1012. // restore call context
  1013. //
  1014. IUnknown *pNewObject;
  1015. hr2 = CoSwitchCallContext(pOldSecContext, &pNewObject);
  1016. if (FAILED(hr2)) {
  1017. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr2 );
  1018. }
  1019. //
  1020. // Return the error code if the status cannot be updated..
  1021. //
  1022. if (FAILED(hr)) {
  1023. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::UpdateGPCoreStatus failed with 0x%x"), hr );
  1024. retStatus.SetError( hr );
  1025. return hr;
  1026. }
  1027. XBStr xbstrNS( xwszNameSpace );
  1028. if ( !xbstrNS )
  1029. {
  1030. hr2 = HRESULT_FROM_WIN32( E_OUTOFMEMORY );
  1031. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Memory allocate failed") );
  1032. retStatus.SetError( hr2 );
  1033. return hr2;
  1034. }
  1035. var.vt = VT_BSTR;
  1036. var.bstrVal = xbstrNS;
  1037. hr2 = pOutParams->Put( m_xbstrNameSpace, 0, &var, 0);
  1038. if ( FAILED(hr2) )
  1039. {
  1040. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Put namespace failed with 0x%x"), hr );
  1041. retStatus.SetError( hr2 );
  1042. return hr2;
  1043. }
  1044. }
  1045. VARIANT var;
  1046. var.vt = VT_I4;
  1047. var.lVal = hr;
  1048. hr = pOutParams->Put( m_xbstrResult, 0, &var, 0);
  1049. if ( FAILED(hr) )
  1050. {
  1051. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Put result failed with 0x%x"), hr );
  1052. retStatus.SetError( hr );
  1053. return hr;
  1054. }
  1055. var.lVal = dwExtendedInfo;
  1056. hr = pOutParams->Put( m_xbstrExtendedInfo, 0, &var, 0);
  1057. if ( FAILED(hr) )
  1058. {
  1059. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::Put result failed with 0x%x"), hr );
  1060. retStatus.SetError( hr );
  1061. return hr;
  1062. }
  1063. //
  1064. // 100% complete when we copy the namespace.
  1065. //
  1066. hr = Indicator.SetComplete();
  1067. if ( FAILED( hr ) )
  1068. {
  1069. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecMethodAsync::IncrementBy() failed with 0x%x"), hr );
  1070. }
  1071. hr = pResponseHandler->Indicate(1, &pOutParams);
  1072. if ( FAILED(hr) )
  1073. {
  1074. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod:: Indicate failed with 0x%x"), hr );
  1075. retStatus.SetError( hr );
  1076. return hr;
  1077. }
  1078. return hr;
  1079. }
  1080. #if _MSC_FULL_VER <= 13008827 && defined(_M_IX86)
  1081. #pragma optimize("", on)
  1082. #endif
  1083. //*************************************************************
  1084. //
  1085. // EnumerateUserNameSpace()
  1086. //
  1087. // Purpose: EnumerateUserNameSpace
  1088. //
  1089. // Parameters:
  1090. // pWbemLocator - Pointer to a locator
  1091. // [out] psaUserSids - Pointer to User Sids
  1092. //
  1093. // Return: hresult
  1094. //
  1095. //*************************************************************
  1096. typedef struct _UserSidList {
  1097. LPWSTR szUserSid;
  1098. struct _UserSidList *pNext;
  1099. } USERSIDLIST, *PUSERSIDLIST;
  1100. HRESULT EnumerateUserNameSpace( IWbemLocator *pWbemLocator, HANDLE hToken, SAFEARRAY **psaUserSids )
  1101. {
  1102. USERSIDLIST SidList = {0,0};
  1103. DWORD dwNum = 0;
  1104. PUSERSIDLIST pElem = NULL;
  1105. HRESULT hr = S_OK;
  1106. DWORD dwExtendedInfo;
  1107. IUnknown *pOldSecContext;
  1108. //
  1109. // Connect to namespace ROOT\RSOP\User
  1110. //
  1111. *psaUserSids = NULL;
  1112. XInterface<IWbemServices>xpWbemServices = NULL;
  1113. XBStr xbstrNamespace = RSOP_NS_DIAG_USERROOT;
  1114. if(!xbstrNamespace)
  1115. {
  1116. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: Failed to allocate memory.")));
  1117. return E_OUTOFMEMORY;
  1118. }
  1119. hr = pWbemLocator->ConnectServer(xbstrNamespace,
  1120. NULL,
  1121. NULL,
  1122. 0L,
  1123. 0L,
  1124. NULL,
  1125. NULL,
  1126. &xpWbemServices);
  1127. if(FAILED(hr))
  1128. {
  1129. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: ConnectServer failed. hr=0x%x" ), hr ));
  1130. return hr;
  1131. }
  1132. //
  1133. // Enumerate all instances of __namespace at the root\rsop\user level.
  1134. //
  1135. XInterface<IEnumWbemClassObject> xpEnum;
  1136. XBStr xbstrClass = L"__namespace";
  1137. if(!xbstrClass)
  1138. {
  1139. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: Failed to allocate memory.")));
  1140. return E_OUTOFMEMORY;
  1141. }
  1142. hr = xpWbemServices->CreateInstanceEnum( xbstrClass,
  1143. WBEM_FLAG_SHALLOW | WBEM_FLAG_FORWARD_ONLY,
  1144. NULL,
  1145. &xpEnum);
  1146. if(FAILED(hr))
  1147. {
  1148. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: CreateInstanceEnum failed. hr=0x%x" ), hr ));
  1149. return hr;
  1150. }
  1151. XBStr xbstrProperty = L"Name";
  1152. if(!xbstrProperty)
  1153. {
  1154. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: Failed to allocate memory")));
  1155. return E_FAIL;
  1156. }
  1157. XInterface<IWbemClassObject>xpInstance = NULL;
  1158. ULONG ulReturned = 1;
  1159. while(1)
  1160. {
  1161. hr = xpEnum->Next( WBEM_NO_WAIT, 1, &xpInstance, &ulReturned);
  1162. if (hr != WBEM_S_NO_ERROR || !ulReturned)
  1163. {
  1164. break;
  1165. }
  1166. VARIANT var;
  1167. VariantInit(&var);
  1168. hr = xpInstance->Get(xbstrProperty, 0L, &var, NULL, NULL);
  1169. xpInstance = NULL;
  1170. if(FAILED(hr))
  1171. {
  1172. DebugMsg((DM_VERBOSE, TEXT("EnumerateUserNameSpace: Get failed. hr=0x%x" ), hr ));
  1173. goto Exit; // continue
  1174. }
  1175. //
  1176. // Check to see whether user is delegated admin for the user account
  1177. //
  1178. XPtrLF<WCHAR> xszUserSid = (LPWSTR)LocalAlloc(LPTR, (1+lstrlen(var.bstrVal))*sizeof(WCHAR));
  1179. if (!xszUserSid) {
  1180. hr = HRESULT_FROM_WIN32(GetLastError());
  1181. DebugMsg((DM_VERBOSE, TEXT("EnumerateUserNameSpace: AllocMem failed. hr=0x%x" ), hr ));
  1182. goto Exit;
  1183. }
  1184. ConvertWMINameToSid(var.bstrVal, xszUserSid);
  1185. //
  1186. // See whether it is a valid Sid
  1187. //
  1188. PSID pSid = NULL;
  1189. if (AllocateAndInitSidFromString(xszUserSid, &pSid) != STATUS_SUCCESS ) {
  1190. DebugMsg((DM_VERBOSE, TEXT("EnumerateUserNameSpace: AllocateAndInitSidFromString - %s is not a valid Sid" ), xszUserSid));
  1191. continue;
  1192. }
  1193. if (!IsValidSid(pSid)) {
  1194. DebugMsg((DM_VERBOSE, TEXT("EnumerateUserNameSpace: %s is not a valid Sid" ), xszUserSid));
  1195. LocalFree(pSid);
  1196. continue;
  1197. }
  1198. LocalFree(pSid);
  1199. //
  1200. // First try to connect to the NameSpace
  1201. //
  1202. hr = CoImpersonateClient();
  1203. if ( FAILED(hr) )
  1204. {
  1205. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoImpersonateClient failed with 0x%x"), hr );
  1206. goto Exit;
  1207. }
  1208. XInterface<IWbemServices> xpChildNamespace = NULL;
  1209. hr = xpWbemServices->OpenNamespace( var.bstrVal,
  1210. 0,
  1211. NULL,
  1212. &xpChildNamespace,
  1213. NULL);
  1214. CoRevertToSelf();
  1215. if(FAILED(hr))
  1216. {
  1217. IUnknown *pNewObject;
  1218. HRESULT hr2=S_OK;
  1219. BOOL bDelegated = TRUE;
  1220. DebugMsg((DM_VERBOSE, TEXT("EnumerateUserNameSpace: OpenNamespace returned 0x%x"), hr));
  1221. //
  1222. // Check whether user has access as LS
  1223. //
  1224. //
  1225. // We want to run as LS
  1226. //
  1227. hr = CoSwitchCallContext(NULL, &pOldSecContext);
  1228. if (FAILED(hr)) {
  1229. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr );
  1230. goto Exit;
  1231. }
  1232. XPtrLF<TCHAR> xszUserSOM;
  1233. if (bDelegated) {
  1234. xszUserSOM = GetSOMFromSID(xszUserSid);
  1235. if (!xszUserSOM) {
  1236. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::No User SOM. Probably local account. error %d"), GetLastError() );
  1237. bDelegated = FALSE;
  1238. }
  1239. }
  1240. //
  1241. // Check access now
  1242. //
  1243. if (bDelegated) {
  1244. hr = AuthenticateUser(hToken, NULL, xszUserSOM, TRUE, &dwExtendedInfo);
  1245. if (FAILED(hr)) {
  1246. dbg.Msg( DEBUG_MESSAGE_VERBOSE, TEXT("ExecAsyncMethod::User is not a delegated admin. Error 0x%x"), hr );
  1247. bDelegated = FALSE;
  1248. }
  1249. }
  1250. //
  1251. // restore call context
  1252. //
  1253. hr2 = CoSwitchCallContext(pOldSecContext, &pNewObject);
  1254. if (FAILED(hr2)) {
  1255. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("ExecAsyncMethod::CoSwitchCallContext failed with 0x%x"), hr2 );
  1256. }
  1257. if (!bDelegated) {
  1258. continue;
  1259. }
  1260. }
  1261. //
  1262. // For every instance of __namespace under ROOT\RSOP\user
  1263. // convert it to Sid and return
  1264. //
  1265. pElem = (PUSERSIDLIST)LocalAlloc(LPTR, sizeof(USERSIDLIST));
  1266. if (!pElem) {
  1267. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: Couldn't allocate memory Error = GetLastError()" ), GetLastError()));
  1268. goto Exit;
  1269. }
  1270. pElem->szUserSid = xszUserSid.Acquire();
  1271. //
  1272. // Attach to the beginning of the list
  1273. //
  1274. pElem->pNext = SidList.pNext;
  1275. SidList.pNext = pElem;
  1276. dwNum++;
  1277. VariantClear( &var );
  1278. }
  1279. if(hr != (HRESULT) WBEM_S_FALSE || ulReturned)
  1280. {
  1281. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: Get failed. hr=0x%x" ), hr ));
  1282. hr = E_FAIL;
  1283. goto Exit;
  1284. }
  1285. //
  1286. // Now make the safe array from the list that we got
  1287. //
  1288. SAFEARRAYBOUND arrayBound[1];
  1289. arrayBound[0].lLbound = 0;
  1290. arrayBound[0].cElements = dwNum;
  1291. *psaUserSids = SafeArrayCreate( VT_BSTR, 1, arrayBound );
  1292. if ( *psaUserSids == NULL ) {
  1293. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: Failed to allocate memory. Error = %d" ), GetLastError() ));
  1294. hr = E_FAIL;
  1295. goto Exit;
  1296. }
  1297. //
  1298. // traverse the list
  1299. //
  1300. DWORD i;
  1301. for (i=0, pElem = SidList.pNext; (i < dwNum); i++, pElem = pElem->pNext) {
  1302. XBStr xbstrUserSid(pElem->szUserSid);
  1303. hr = SafeArrayPutElement( *psaUserSids, (LONG *)&i, xbstrUserSid);
  1304. if(FAILED(hr)) {
  1305. DebugMsg((DM_WARNING, TEXT("EnumerateUserNameSpace: SafeArrayPutElement failed. Error = 0x%x" ), hr ));
  1306. goto Exit; // free up the SidList
  1307. }
  1308. }
  1309. hr = S_OK;
  1310. Exit:
  1311. // free
  1312. for (i=0, pElem = SidList.pNext; (i < dwNum); i++ ) {
  1313. if (pElem->szUserSid)
  1314. LocalFree(pElem->szUserSid);
  1315. PUSERSIDLIST pTemp = pElem;
  1316. pElem = pElem->pNext;
  1317. LocalFree(pTemp);
  1318. }
  1319. return hr;
  1320. }