Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1634 lines
47 KiB

  1. /*++
  2. // Copyright (c) 1995-2001 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. COMINIT.CPP
  5. Abstract:
  6. WMI COM Helper functions
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include <wbemidl.h>
  11. #define _COMINIT_CPP_
  12. #include "cominit.h"
  13. #include <tchar.h>
  14. BOOL WINAPI DoesContainCredentials( COAUTHIDENTITY* pAuthIdentity )
  15. {
  16. try
  17. {
  18. if ( NULL != pAuthIdentity && COLE_DEFAULT_AUTHINFO != pAuthIdentity)
  19. {
  20. return ( pAuthIdentity->UserLength != 0 || pAuthIdentity->PasswordLength != 0 );
  21. }
  22. return FALSE;
  23. }
  24. catch(...)
  25. {
  26. return FALSE;
  27. }
  28. }
  29. HRESULT WINAPI WbemSetProxyBlanket(
  30. IUnknown *pInterface,
  31. DWORD dwAuthnSvc,
  32. DWORD dwAuthzSvc,
  33. OLECHAR *pServerPrincName,
  34. DWORD dwAuthLevel,
  35. DWORD dwImpLevel,
  36. RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
  37. DWORD dwCapabilities,
  38. bool fIgnoreUnk )
  39. {
  40. IUnknown * pUnk = NULL;
  41. IClientSecurity * pCliSec = NULL;
  42. HRESULT sc = pInterface->QueryInterface(IID_IUnknown, (void **) &pUnk);
  43. if(sc != S_OK)
  44. return sc;
  45. sc = pInterface->QueryInterface(IID_IClientSecurity, (void **) &pCliSec);
  46. if(sc != S_OK)
  47. {
  48. pUnk->Release();
  49. return sc;
  50. }
  51. /*
  52. * Can't set pAuthInfo if cloaking requested, as cloaking implies
  53. * that the current proxy identity in the impersonated thread (rather
  54. * than the credentials supplied explicitly by the RPC_AUTH_IDENTITY_HANDLE)
  55. * is to be used.
  56. * See MSDN info on CoSetProxyBlanket for more details.
  57. */
  58. if (dwCapabilities & (EOAC_STATIC_CLOAKING | EOAC_DYNAMIC_CLOAKING))
  59. pAuthInfo = NULL;
  60. sc = pCliSec->SetBlanket(pInterface, dwAuthnSvc, dwAuthzSvc, pServerPrincName,
  61. dwAuthLevel, dwImpLevel, pAuthInfo, dwCapabilities);
  62. pCliSec->Release();
  63. pCliSec = NULL;
  64. // If we are not explicitly told to ignore the IUnknown, then we should
  65. // check the auth identity structure. This performs a heuristic which
  66. // assumes a COAUTHIDENTITY structure. If the structure is not one, we're
  67. // wrapped with a try/catch in case we AV (this should be benign since
  68. // we're not writing to memory).
  69. if ( !fIgnoreUnk && DoesContainCredentials( (COAUTHIDENTITY*) pAuthInfo ) )
  70. {
  71. sc = pUnk->QueryInterface(IID_IClientSecurity, (void **) &pCliSec);
  72. if(sc == S_OK)
  73. {
  74. sc = pCliSec->SetBlanket(pUnk, dwAuthnSvc, dwAuthzSvc, pServerPrincName,
  75. dwAuthLevel, dwImpLevel, pAuthInfo, dwCapabilities);
  76. pCliSec->Release();
  77. }
  78. else if (sc == 0x80004002)
  79. sc = S_OK;
  80. }
  81. pUnk->Release();
  82. return sc;
  83. }
  84. // Helper class we can keep a static instance of and ensure that when a module unloads,
  85. // the dll handle is freed.
  86. class CLibHandle
  87. {
  88. public:
  89. CLibHandle() : m_hInstance( NULL ) {};
  90. ~CLibHandle();
  91. HINSTANCE GetHandle( void ) { return m_hInstance; }
  92. void SetHandle( HINSTANCE hInst ) { m_hInstance = hInst; }
  93. private:
  94. HINSTANCE m_hInstance;
  95. };
  96. CLibHandle::~CLibHandle()
  97. {
  98. if ( NULL == m_hInstance )
  99. return;
  100. OSVERSIONINFO os;
  101. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  102. if(!GetVersionEx(&os))
  103. return; // should never happen
  104. // if not nt, then we can crash by freeing the library, so only do it if nt!
  105. if(os.dwPlatformId == VER_PLATFORM_WIN32_NT)
  106. FreeLibrary( m_hInstance );
  107. return;
  108. }
  109. // The OLE32 library has been loaded to access the functions above
  110. // for DCOM calls.
  111. // ===============================================================
  112. // Static object that will destruct and free the handle to
  113. // g_hOle32 when the module exits memory.
  114. static CLibHandle g_LibHandleOle32;
  115. // DCOM check has been performed = TRUE.
  116. // =====================================
  117. static BOOL g_bInitialized = FALSE;
  118. BOOL WINAPI InitComInit()
  119. {
  120. UINT uSize;
  121. BOOL bRetCode = FALSE;
  122. HANDLE hMut;
  123. if(g_bInitialized) {
  124. return TRUE;
  125. }
  126. do {
  127. hMut = CreateMutex(NULL, TRUE, _T("COMINIT_INITIALING"));
  128. if(hMut == INVALID_HANDLE_VALUE) {
  129. Sleep(50);
  130. }
  131. } while(hMut == INVALID_HANDLE_VALUE);
  132. if(g_bInitialized) {
  133. CloseHandle(hMut);
  134. return TRUE;
  135. }
  136. LPTSTR pszSysDir = new _TCHAR[ MAX_PATH+10 ];
  137. if(pszSysDir == NULL)
  138. {
  139. CloseHandle(hMut);
  140. return FALSE;
  141. }
  142. uSize = GetSystemDirectory(pszSysDir, MAX_PATH);
  143. if(uSize > MAX_PATH) {
  144. delete[] pszSysDir;
  145. pszSysDir = new _TCHAR[ uSize +10 ];
  146. if(pszSysDir == NULL)
  147. {
  148. CloseHandle(hMut);
  149. return FALSE;
  150. }
  151. uSize = GetSystemDirectory(pszSysDir, uSize);
  152. }
  153. lstrcat(pszSysDir, _T("\\ole32.dll"));
  154. HINSTANCE hOle32 = LoadLibraryEx(pszSysDir, NULL, 0);
  155. delete pszSysDir;
  156. if(hOle32 != NULL)
  157. {
  158. bRetCode = TRUE;
  159. (FARPROC&)g_pfnCoInitializeEx = GetProcAddress(hOle32, "CoInitializeEx");
  160. if(!g_pfnCoInitializeEx) {
  161. FreeLibrary(hOle32);
  162. hOle32 = NULL;
  163. bRetCode = FALSE;
  164. }
  165. // This handle will now automagically be freed when the Dll
  166. // is unloaded from memory.
  167. g_LibHandleOle32.SetHandle( hOle32 );
  168. (FARPROC&)g_pfnCoCreateInstanceEx =
  169. GetProcAddress(g_LibHandleOle32.GetHandle(), "CoCreateInstanceEx");
  170. (FARPROC&)g_pfnCoGetCallContext =
  171. GetProcAddress(g_LibHandleOle32.GetHandle(), "CoGetCallContext");
  172. (FARPROC&)g_pfnCoSwitchCallContext =
  173. GetProcAddress(g_LibHandleOle32.GetHandle(), "CoSwitchCallContext");
  174. }
  175. g_bInitialized = TRUE;
  176. CloseHandle(hMut);
  177. return bRetCode;
  178. }
  179. BOOL WINAPI IsDcomEnabled()
  180. {
  181. InitComInit();
  182. if(g_LibHandleOle32.GetHandle()) {
  183. // DCOM has been detected.
  184. // =======================
  185. return TRUE;
  186. } else {
  187. // DCOM was not detected.
  188. // ======================
  189. return FALSE;
  190. }
  191. }
  192. HRESULT WINAPI InitializeCom()
  193. {
  194. if(IsDcomEnabled()) {
  195. return g_pfnCoInitializeEx(0, COINIT_MULTITHREADED);
  196. }
  197. return CoInitialize(0);
  198. }
  199. HRESULT WINAPI InitializeSecurity(
  200. PSECURITY_DESCRIPTOR pSecDesc,
  201. LONG cAuthSvc,
  202. SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
  203. void *pReserved1,
  204. DWORD dwAuthnLevel,
  205. DWORD dwImpLevel,
  206. void *pReserved2,
  207. DWORD dwCapabilities,
  208. void *pReserved3)
  209. {
  210. // Get CoInitializeSecurity from ole32.dll
  211. // =======================================
  212. if(g_LibHandleOle32.GetHandle() == NULL)
  213. {
  214. return E_FAIL;
  215. }
  216. typedef HRESULT (STDAPICALLTYPE *PFN_COINITIALIZESECURITY)(
  217. PSECURITY_DESCRIPTOR, DWORD,
  218. SOLE_AUTHENTICATION_SERVICE*, void*, DWORD, DWORD,
  219. RPC_AUTH_IDENTITY_HANDLE, DWORD, void*);
  220. PFN_COINITIALIZESECURITY pfnCoInitializeSecurity =
  221. (PFN_COINITIALIZESECURITY)
  222. GetProcAddress(g_LibHandleOle32.GetHandle(), "CoInitializeSecurity");
  223. if(pfnCoInitializeSecurity == NULL)
  224. {
  225. return S_FALSE;
  226. }
  227. // Initialize security
  228. // ===================
  229. return pfnCoInitializeSecurity(pSecDesc,
  230. cAuthSvc,
  231. asAuthSvc,
  232. pReserved1,
  233. dwAuthnLevel,
  234. dwImpLevel,
  235. pReserved2,
  236. dwCapabilities,
  237. pReserved3);
  238. }
  239. DWORD WINAPI WbemWaitForMultipleObjects(DWORD nCount, HANDLE* ahHandles, DWORD dwMilli)
  240. {
  241. MSG msg;
  242. DWORD dwRet;
  243. while(1)
  244. {
  245. dwRet = MsgWaitForMultipleObjects(nCount, ahHandles, FALSE, dwMilli,
  246. QS_SENDMESSAGE);
  247. if(dwRet == (WAIT_OBJECT_0 + nCount))
  248. {
  249. while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  250. DispatchMessage(&msg);
  251. }
  252. continue;
  253. }
  254. else
  255. {
  256. break;
  257. }
  258. }
  259. return dwRet;
  260. }
  261. DWORD WINAPI WbemWaitForSingleObject(HANDLE hHandle, DWORD dwMilli)
  262. {
  263. return WbemWaitForMultipleObjects(1, &hHandle, dwMilli);
  264. }
  265. BOOL WINAPI WbemTryEnterCriticalSection(CRITICAL_SECTION* pcs)
  266. {
  267. // TBD properly!!
  268. if(pcs->LockCount >= 0)
  269. return FALSE;
  270. else
  271. {
  272. EnterCriticalSection(pcs);
  273. return TRUE;
  274. }
  275. }
  276. HRESULT WINAPI WbemCoCreateInstance(REFCLSID rclsid, IUnknown* pUnkOuter,
  277. DWORD dwClsContext, REFIID riid, void** ppv)
  278. {
  279. if(!IsDcomEnabled())
  280. {
  281. dwClsContext &= ~CLSCTX_REMOTE_SERVER;
  282. }
  283. return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
  284. }
  285. HRESULT WINAPI WbemCoGetClassObject(REFCLSID rclsid, DWORD dwClsContext,
  286. COSERVERINFO* pServerInfo, REFIID riid, void** ppv)
  287. {
  288. if(!IsDcomEnabled())
  289. {
  290. dwClsContext &= ~CLSCTX_REMOTE_SERVER;
  291. }
  292. return CoGetClassObject(rclsid, dwClsContext, pServerInfo, riid, ppv);
  293. }
  294. HRESULT WINAPI WbemCoGetCallContext(REFIID riid, void** ppv)
  295. {
  296. if(!IsDcomEnabled())
  297. {
  298. *ppv = NULL;
  299. return E_NOTIMPL;
  300. }
  301. else
  302. {
  303. return (*g_pfnCoGetCallContext)(riid, ppv);
  304. }
  305. }
  306. HRESULT WINAPI WbemCoSwitchCallContext( IUnknown *pNewObject, IUnknown **ppOldObject )
  307. {
  308. if(!IsDcomEnabled())
  309. {
  310. return E_NOTIMPL;
  311. }
  312. else
  313. {
  314. return (*g_pfnCoSwitchCallContext)(pNewObject, ppOldObject);
  315. }
  316. }
  317. //***************************************************************************
  318. //
  319. // SCODE DetermineLoginType
  320. //
  321. // DESCRIPTION:
  322. //
  323. // Examines the Authority and User argument and determines the authentication
  324. // type and possibly extracts the domain name from the user arugment in the
  325. // NTLM case. For NTLM, the domain can be at the end of the authentication
  326. // string, or in the front of the user name, ex; "redmond\a-davj"
  327. //
  328. // PARAMETERS:
  329. //
  330. // ConnType Returned with the connection type, ie wbem, ntlm
  331. // AuthArg Output, contains the domain name
  332. // UserArg Output, user name
  333. // Authority Input
  334. // User Input
  335. //
  336. // RETURN VALUE:
  337. //
  338. // S_OK all is well
  339. // else error listed in WBEMSVC.H
  340. //
  341. //***************************************************************************
  342. SCODE WINAPI DetermineLoginType(BSTR & AuthArg, BSTR & UserArg,BSTR & Authority,BSTR & User)
  343. {
  344. // Determine the connection type by examining the Authority string
  345. if(!(Authority == NULL || wcslen(Authority) == 0 || !_wcsnicmp(Authority, L"NTLMDOMAIN:",11)))
  346. return WBEM_E_INVALID_PARAMETER;
  347. // The ntlm case is more complex. There are four cases
  348. // 1) Authority = NTLMDOMAIN:name" and User = "User"
  349. // 2) Authority = NULL and User = "User"
  350. // 3) Authority = "NTLMDOMAIN:" User = "domain\user"
  351. // 4) Authority = NULL and User = "domain\user"
  352. // first step is to determine if there is a backslash in the user name somewhere between the
  353. // second and second to last character
  354. WCHAR * pSlashInUser = NULL;
  355. if(User)
  356. {
  357. WCHAR * pEnd = User + wcslen(User) - 1;
  358. for(pSlashInUser = User; pSlashInUser <= pEnd; pSlashInUser++)
  359. if(*pSlashInUser == L'\\') // dont think forward slash is allowed!
  360. break;
  361. if(pSlashInUser > pEnd)
  362. pSlashInUser = NULL;
  363. }
  364. if(Authority && wcslen(Authority) > 11)
  365. {
  366. if(pSlashInUser)
  367. return WBEM_E_INVALID_PARAMETER;
  368. AuthArg = SysAllocString(Authority + 11);
  369. if(User) UserArg = SysAllocString(User);
  370. return S_OK;
  371. }
  372. else if(pSlashInUser)
  373. {
  374. DWORD_PTR iDomLen = pSlashInUser-User;
  375. WCHAR cTemp[MAX_PATH];
  376. wcsncpy(cTemp, User, iDomLen);
  377. cTemp[iDomLen] = 0;
  378. AuthArg = SysAllocString(cTemp);
  379. if(wcslen(pSlashInUser+1))
  380. UserArg = SysAllocString(pSlashInUser+1);
  381. }
  382. else
  383. if(User) UserArg = SysAllocString(User);
  384. return S_OK;
  385. }
  386. //***************************************************************************
  387. //
  388. // SCODE DetermineLoginTypeEx
  389. //
  390. // DESCRIPTION:
  391. //
  392. // Extended version that supports Kerberos. To do so, the authority string
  393. // must start with Kerberos: and the other parts be compatible with the normal
  394. // login. Ie, user should be domain\user.
  395. //
  396. // PARAMETERS:
  397. //
  398. // AuthArg Output, contains the domain name
  399. // UserArg Output, user name
  400. // PrincipalArg Output, user name
  401. // Authority Input
  402. // User Input
  403. //
  404. // RETURN VALUE:
  405. //
  406. // S_OK all is well
  407. // else error listed in WBEMSVC.H
  408. //
  409. //***************************************************************************
  410. SCODE WINAPI DetermineLoginTypeEx(BSTR & AuthArg, BSTR & UserArg,BSTR & PrincipalArg,
  411. BSTR & Authority,BSTR & User)
  412. {
  413. // Normal case, just let existing code handle it
  414. if(Authority == NULL || _wcsnicmp(Authority, L"KERBEROS:",9))
  415. return DetermineLoginType(AuthArg, UserArg, Authority, User);
  416. if(!IsKerberosAvailable())
  417. return WBEM_E_INVALID_PARAMETER;
  418. PrincipalArg = SysAllocString(&Authority[9]);
  419. BSTR tempArg = NULL;
  420. return DetermineLoginType(AuthArg, UserArg, tempArg, User);
  421. }
  422. //***************************************************************************
  423. //
  424. // bool bIsNT
  425. //
  426. // DESCRIPTION:
  427. //
  428. // Returns true if running windows NT.
  429. //
  430. // RETURN VALUE:
  431. //
  432. // see description.
  433. //
  434. //***************************************************************************
  435. bool WINAPI bIsNT(void)
  436. {
  437. OSVERSIONINFO os;
  438. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  439. if(!GetVersionEx(&os))
  440. return FALSE; // should never happen
  441. return os.dwPlatformId == VER_PLATFORM_WIN32_NT;
  442. }
  443. //***************************************************************************
  444. //
  445. // bool IsKeberosAvailable
  446. //
  447. // DESCRIPTION:
  448. //
  449. // Returns true if Kerberos is available.
  450. //
  451. // RETURN VALUE:
  452. //
  453. // see description.
  454. //
  455. //***************************************************************************
  456. BOOL WINAPI IsKerberosAvailable(void)
  457. {
  458. OSVERSIONINFO os;
  459. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  460. if(!GetVersionEx(&os))
  461. return FALSE; // should never happen
  462. // IMPORTANT!! This will need to be chanted if Kerberos is ever ported to 98
  463. return ( os.dwPlatformId == VER_PLATFORM_WIN32_NT ) && ( os.dwMajorVersion >= 5 ) ;
  464. }
  465. //***************************************************************************
  466. //
  467. // bool IsAuthenticated
  468. //
  469. // DESCRIPTION:
  470. //
  471. // This routine is used by clients in check if an interface pointer is using
  472. // authentication.
  473. //
  474. // PARAMETERS:
  475. //
  476. // pFrom the interface to be tested.
  477. //
  478. // RETURN VALUE:
  479. //
  480. // S_OK all is well
  481. // else error listed in WBEMSVC.H
  482. //
  483. //***************************************************************************
  484. bool WINAPI IsAuthenticated(IUnknown * pFrom)
  485. {
  486. bool bAuthenticate = true;
  487. if(pFrom == NULL)
  488. return true;
  489. IClientSecurity * pFromSec = NULL;
  490. SCODE sc = pFrom->QueryInterface(IID_IClientSecurity, (void **) &pFromSec);
  491. if(sc == S_OK)
  492. {
  493. DWORD dwAuthnSvc, dwAuthzSvc, dwAuthnLevel, dwImpLevel, dwCapabilities;
  494. sc = pFromSec->QueryBlanket(pFrom, &dwAuthnSvc, &dwAuthzSvc,
  495. NULL,
  496. &dwAuthnLevel, &dwImpLevel,
  497. NULL, &dwCapabilities);
  498. if (sc == 0x800706d2 || (sc == S_OK && dwAuthnLevel == RPC_C_AUTHN_LEVEL_NONE))
  499. bAuthenticate = false;
  500. pFromSec->Release();
  501. }
  502. return bAuthenticate;
  503. }
  504. //***************************************************************************
  505. //
  506. // SCODE GetAuthImp
  507. //
  508. // DESCRIPTION:
  509. //
  510. // Gets the authentication and impersonation levels for a current interface.
  511. //
  512. // PARAMETERS:
  513. //
  514. // pFrom the interface to be tested.
  515. // pdwAuthLevel
  516. //
  517. // RETURN VALUE:
  518. //
  519. // S_OK all is well
  520. // else error listed in WBEMSVC.H
  521. //
  522. //***************************************************************************
  523. SCODE WINAPI GetAuthImp(IUnknown * pFrom, DWORD * pdwAuthLevel, DWORD * pdwImpLevel)
  524. {
  525. if(pFrom == NULL || pdwAuthLevel == NULL || pdwImpLevel == NULL)
  526. return WBEM_E_INVALID_PARAMETER;
  527. IClientSecurity * pFromSec = NULL;
  528. SCODE sc = pFrom->QueryInterface(IID_IClientSecurity, (void **) &pFromSec);
  529. if(sc == S_OK)
  530. {
  531. DWORD dwAuthnSvc, dwAuthzSvc, dwCapabilities;
  532. sc = pFromSec->QueryBlanket(pFrom, &dwAuthnSvc, &dwAuthzSvc,
  533. NULL,
  534. pdwAuthLevel, pdwImpLevel,
  535. NULL, &dwCapabilities);
  536. // Special case of going to a win9x share level box
  537. if (sc == 0x800706d2)
  538. {
  539. *pdwAuthLevel = RPC_C_AUTHN_LEVEL_NONE;
  540. *pdwImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
  541. sc = S_OK;
  542. }
  543. pFromSec->Release();
  544. }
  545. return sc;
  546. }
  547. //***************************************************************************
  548. //
  549. // SCODE SetInterfaceSecurity
  550. //
  551. // DESCRIPTION:
  552. //
  553. // This routine is used by clients in order to set the identity to be used by a connection.
  554. //
  555. // PARAMETERS:
  556. //
  557. // pInterface Interface to be set
  558. // pDomain Input, domain
  559. // pUser Input, user name
  560. // pPassword Input, password.
  561. // pFrom Input, if not NULL, then the authentication level of this interface
  562. // is used
  563. // bAuthArg If pFrom is NULL, then this is the authentication level
  564. // RETURN VALUE:
  565. //
  566. // S_OK all is well
  567. // else error listed in WBEMSVC.H
  568. //
  569. //***************************************************************************
  570. HRESULT WINAPI SetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority, LPWSTR pUser,
  571. LPWSTR pPassword, IUnknown * pFrom, bool bAuthArg)
  572. {
  573. SCODE sc;
  574. if(!IsDcomEnabled()) // For the anon pipes clients, dont even bother
  575. return S_OK;
  576. if(pInterface == NULL)
  577. return WBEM_E_INVALID_PARAMETER;
  578. // Check the source pointer to determine if we are running in a non authenticated mode which
  579. // would be the case when connected to a Win9X box which is using share level security
  580. bool bAuthenticate = true;
  581. if(pFrom)
  582. bAuthenticate = IsAuthenticated(pFrom);
  583. else
  584. bAuthenticate = bAuthArg;
  585. // If we are doing trivial case, just pass in a null authenication structure which is used
  586. // if the current logged in user's credentials are OK.
  587. if((pAuthority == NULL || wcslen(pAuthority) < 1) &&
  588. (pUser == NULL || wcslen(pUser) < 1) &&
  589. (pPassword == NULL || wcslen(pPassword) < 1))
  590. return SetInterfaceSecurity(pInterface, NULL, bAuthenticate);
  591. // If user, or Authority was passed in, the we need to create an authority argument for the login
  592. COAUTHIDENTITY authident;
  593. BSTR AuthArg = NULL, UserArg = NULL;
  594. sc = DetermineLoginType(AuthArg, UserArg, pAuthority, pUser);
  595. if(sc != S_OK)
  596. return sc;
  597. memset((void *)&authident,0,sizeof(COAUTHIDENTITY));
  598. if(bIsNT())
  599. {
  600. if(UserArg)
  601. {
  602. authident.UserLength = wcslen(UserArg);
  603. authident.User = (LPWSTR)UserArg;
  604. }
  605. if(AuthArg)
  606. {
  607. authident.DomainLength = wcslen(AuthArg);
  608. authident.Domain = (LPWSTR)AuthArg;
  609. }
  610. if(pPassword)
  611. {
  612. authident.PasswordLength = wcslen(pPassword);
  613. authident.Password = (LPWSTR)pPassword;
  614. }
  615. authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  616. sc = SetInterfaceSecurity(pInterface, &authident, bAuthenticate);
  617. }
  618. else
  619. {
  620. char szUser[MAX_PATH], szAuthority[MAX_PATH], szPassword[MAX_PATH];
  621. // Fill in the indentity structure
  622. if(UserArg)
  623. {
  624. wcstombs(szUser, UserArg, MAX_PATH);
  625. authident.UserLength = strlen(szUser);
  626. authident.User = (LPWSTR)szUser;
  627. }
  628. if(AuthArg)
  629. {
  630. wcstombs(szAuthority, AuthArg, MAX_PATH);
  631. authident.DomainLength = strlen(szAuthority);
  632. authident.Domain = (LPWSTR)szAuthority;
  633. }
  634. if(pPassword)
  635. {
  636. wcstombs(szPassword, pPassword, MAX_PATH);
  637. authident.PasswordLength = strlen(szPassword);
  638. authident.Password = (LPWSTR)szPassword;
  639. }
  640. authident.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  641. sc = SetInterfaceSecurity(pInterface, &authident, bAuthenticate);
  642. }
  643. if(UserArg)
  644. SysFreeString(UserArg);
  645. if(AuthArg)
  646. SysFreeString(AuthArg);
  647. return sc;
  648. }
  649. //***************************************************************************
  650. //
  651. // SCODE SetInterfaceSecurity
  652. //
  653. // DESCRIPTION:
  654. //
  655. // This routine is used by clients in order to set the identity to be used by a connection.
  656. //
  657. // PARAMETERS:
  658. //
  659. // pInterface Interface to be set
  660. // pDomain Input, domain
  661. // pUser Input, user name
  662. // pPassword Input, password.
  663. // pFrom Input, if not NULL, then the authentication level of this interface
  664. // is used
  665. // bAuthArg If pFrom is NULL, then this is the authentication level
  666. // RETURN VALUE:
  667. //
  668. // S_OK all is well
  669. // else error listed in WBEMSVC.H
  670. //
  671. //***************************************************************************
  672. HRESULT WINAPI SetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority, LPWSTR pUser,
  673. LPWSTR pPassword, DWORD dwAuthLevel, DWORD dwImpLevel, DWORD dwCapabilities)
  674. {
  675. SCODE sc;
  676. if(!IsDcomEnabled()) // For the anon pipes clients, dont even bother
  677. return S_OK;
  678. if(pInterface == NULL)
  679. return WBEM_E_INVALID_PARAMETER;
  680. // If we are doing trivial case, just pass in a null authenication structure which is used
  681. // if the current logged in user's credentials are OK.
  682. if((pAuthority == NULL || wcslen(pAuthority) < 1) &&
  683. (pUser == NULL || wcslen(pUser) < 1) &&
  684. (pPassword == NULL || wcslen(pPassword) < 1))
  685. {
  686. sc = WbemSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
  687. dwAuthLevel, dwImpLevel,
  688. NULL,
  689. dwCapabilities);
  690. return sc;
  691. }
  692. // If user, or Authority was passed in, the we need to create an authority argument for the login
  693. COAUTHIDENTITY authident;
  694. BSTR AuthArg = NULL, UserArg = NULL, PrincipalArg = NULL;
  695. sc = DetermineLoginTypeEx(AuthArg, UserArg, PrincipalArg, pAuthority, pUser);
  696. if(sc != S_OK)
  697. return sc;
  698. memset((void *)&authident,0,sizeof(COAUTHIDENTITY));
  699. if(bIsNT())
  700. {
  701. if(UserArg)
  702. {
  703. authident.UserLength = wcslen(UserArg);
  704. authident.User = (LPWSTR)UserArg;
  705. }
  706. if(AuthArg)
  707. {
  708. authident.DomainLength = wcslen(AuthArg);
  709. authident.Domain = (LPWSTR)AuthArg;
  710. }
  711. if(pPassword)
  712. {
  713. authident.PasswordLength = wcslen(pPassword);
  714. authident.Password = (LPWSTR)pPassword;
  715. }
  716. authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  717. }
  718. else
  719. {
  720. char szUser[MAX_PATH], szAuthority[MAX_PATH], szPassword[MAX_PATH];
  721. // Fill in the indentity structure
  722. if(UserArg)
  723. {
  724. wcstombs(szUser, UserArg, MAX_PATH);
  725. authident.UserLength = strlen(szUser);
  726. authident.User = (LPWSTR)szUser;
  727. }
  728. if(AuthArg)
  729. {
  730. wcstombs(szAuthority, AuthArg, MAX_PATH);
  731. authident.DomainLength = strlen(szAuthority);
  732. authident.Domain = (LPWSTR)szAuthority;
  733. }
  734. if(pPassword)
  735. {
  736. wcstombs(szPassword, pPassword, MAX_PATH);
  737. authident.PasswordLength = strlen(szPassword);
  738. authident.Password = (LPWSTR)szPassword;
  739. }
  740. authident.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  741. }
  742. sc = WbemSetProxyBlanket(pInterface,
  743. (PrincipalArg) ? 16 : RPC_C_AUTHN_WINNT,
  744. RPC_C_AUTHZ_NONE,
  745. PrincipalArg,
  746. dwAuthLevel, dwImpLevel,
  747. (dwAuthLevel >= RPC_C_AUTHN_LEVEL_CONNECT) ? &authident : NULL,
  748. dwCapabilities);
  749. if(UserArg)
  750. SysFreeString(UserArg);
  751. if(AuthArg)
  752. SysFreeString(AuthArg);
  753. if(PrincipalArg)
  754. SysFreeString(PrincipalArg);
  755. return sc;
  756. }
  757. //***************************************************************************
  758. //
  759. // SCODE SetInterfaceSecurity
  760. //
  761. // DESCRIPTION:
  762. //
  763. // This routine is used by clients in order to set the identity to be used by a connection.
  764. //
  765. // PARAMETERS:
  766. //
  767. // pInterface Interface to be set
  768. // pauthident Structure with the identity info already set.
  769. //
  770. // RETURN VALUE:
  771. //
  772. // S_OK all is well
  773. //
  774. //***************************************************************************
  775. HRESULT WINAPI SetInterfaceSecurity(IUnknown * pInterface, COAUTHIDENTITY * pauthident, bool bAuthenticate)
  776. {
  777. if(pInterface == NULL)
  778. return WBEM_E_INVALID_PARAMETER;
  779. SCODE sc;
  780. sc = WbemSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
  781. (bAuthenticate) ? RPC_C_AUTHN_LEVEL_DEFAULT : RPC_C_AUTHN_LEVEL_NONE,
  782. RPC_C_IMP_LEVEL_IDENTIFY,
  783. (bAuthenticate) ? pauthident : NULL,
  784. EOAC_NONE);
  785. return sc;
  786. }
  787. void GetCurrentValue(IUnknown * pFrom,DWORD & dwAuthenticationArg, DWORD & dwAuthorizationArg)
  788. {
  789. if(pFrom == NULL)
  790. return;
  791. IClientSecurity * pFromSec = NULL;
  792. SCODE sc = pFrom->QueryInterface(IID_IClientSecurity, (void **) &pFromSec);
  793. if(sc == S_OK)
  794. {
  795. DWORD dwAuthnSvc, dwAuthzSvc;
  796. sc = pFromSec->QueryBlanket(pFrom, &dwAuthnSvc, &dwAuthzSvc,
  797. NULL,
  798. NULL, NULL,
  799. NULL, NULL);
  800. if (sc == S_OK)
  801. {
  802. dwAuthenticationArg = dwAuthnSvc;
  803. dwAuthorizationArg = dwAuthzSvc;
  804. }
  805. pFromSec->Release();
  806. }
  807. }
  808. //***************************************************************************
  809. //
  810. // SCODE SetInterfaceSecurityEx
  811. //
  812. // DESCRIPTION:
  813. //
  814. // This routine is used by clients in order to set the identity to be used by a connection.
  815. //
  816. // PARAMETERS:
  817. //
  818. // pInterface Interface to be set
  819. // pAuthority Input, authority
  820. // pUser Input, user name
  821. // pPassword Input, password.
  822. // dwAuthLevel Input, Authorization Level
  823. // dwImpLevel Input, Impersonation Level
  824. // dwCapabilities Input, Capability settings
  825. // ppAuthIdent Output, Allocated AuthIdentity if applicable, caller must free
  826. // manually (can use the FreeAuthInfo function).
  827. // pPrincipal Output, Principal calculated from supplied data Caller must
  828. // free using SysFreeString.
  829. // GetInfoFirst if true, the authentication and authorization are retrived via
  830. // QueryBlanket.
  831. //
  832. // RETURN VALUE:
  833. //
  834. // S_OK all is well
  835. // else error listed in WBEMSVC.H
  836. //
  837. //***************************************************************************
  838. HRESULT WINAPI SetInterfaceSecurityEx(IUnknown * pInterface, LPWSTR pAuthority, LPWSTR pUser, LPWSTR pPassword,
  839. DWORD dwAuthLevel, DWORD dwImpLevel, DWORD dwCapabilities,
  840. COAUTHIDENTITY** ppAuthIdent, BSTR* pPrincipal, bool GetInfoFirst)
  841. {
  842. SCODE sc;
  843. DWORD dwAuthenticationArg = RPC_C_AUTHN_WINNT;
  844. DWORD dwAuthorizationArg = RPC_C_AUTHZ_NONE;
  845. if(!IsDcomEnabled()) // For the anon pipes clients, dont even bother
  846. return S_OK;
  847. if( pInterface == NULL || NULL == ppAuthIdent || NULL == pPrincipal )
  848. return WBEM_E_INVALID_PARAMETER;
  849. if(GetInfoFirst)
  850. GetCurrentValue(pInterface, dwAuthenticationArg, dwAuthorizationArg);
  851. // If we are doing trivial case, just pass in a null authenication structure which is used
  852. // if the current logged in user's credentials are OK.
  853. if((pAuthority == NULL || wcslen(pAuthority) < 1) &&
  854. (pUser == NULL || wcslen(pUser) < 1) &&
  855. (pPassword == NULL || wcslen(pPassword) < 1))
  856. {
  857. sc = WbemSetProxyBlanket(pInterface, dwAuthenticationArg, dwAuthorizationArg, NULL,
  858. dwAuthLevel, dwImpLevel,
  859. NULL,
  860. dwCapabilities);
  861. return sc;
  862. }
  863. // If user, or Authority was passed in, the we need to create an authority argument for the login
  864. BSTR AuthArg = NULL, UserArg = NULL, PrincipalArg = NULL;
  865. sc = DetermineLoginTypeEx(AuthArg, UserArg, PrincipalArg, pAuthority, pUser);
  866. if(sc != S_OK)
  867. {
  868. return sc;
  869. }
  870. // Handle an allocation failure
  871. COAUTHIDENTITY* pAuthIdent = NULL;
  872. // We will only need this structure if we are not cloaking and we want at least
  873. // connect level authorization
  874. if ( !( dwCapabilities & (EOAC_STATIC_CLOAKING | EOAC_DYNAMIC_CLOAKING) )
  875. && (dwAuthLevel >= RPC_C_AUTHN_LEVEL_CONNECT) )
  876. {
  877. sc = WbemAllocAuthIdentity( UserArg, pPassword, AuthArg, &pAuthIdent );
  878. }
  879. if ( SUCCEEDED( sc ) )
  880. {
  881. sc = WbemSetProxyBlanket(pInterface,
  882. (PrincipalArg) ? 16 : dwAuthenticationArg,
  883. dwAuthorizationArg,
  884. PrincipalArg,
  885. dwAuthLevel, dwImpLevel,
  886. pAuthIdent,
  887. dwCapabilities);
  888. // We will store relevant values as necessary
  889. if ( SUCCEEDED( sc ) )
  890. {
  891. *ppAuthIdent = pAuthIdent;
  892. *pPrincipal = PrincipalArg;
  893. }
  894. else
  895. {
  896. WbemFreeAuthIdentity( pAuthIdent );
  897. }
  898. }
  899. if(UserArg)
  900. SysFreeString(UserArg);
  901. if(AuthArg)
  902. SysFreeString(AuthArg);
  903. // Only free if we failed
  904. if(PrincipalArg && FAILED( sc ))
  905. {
  906. SysFreeString(PrincipalArg);
  907. }
  908. return sc;
  909. }
  910. //***************************************************************************
  911. //
  912. // SCODE SetInterfaceSecurityEx
  913. //
  914. // DESCRIPTION:
  915. //
  916. // This routine is used by clients in order to set the identity to be used by a connection.
  917. //
  918. // PARAMETERS:
  919. //
  920. // pInterface Interface to be set
  921. // pAuthIdent Input, Preset COAUTHIDENTITY structure pointer.
  922. // pPrincipal Input, Preset principal argument
  923. // dwAuthLevel Input, Authorization Level
  924. // dwImpLevel Input, Impersonation Level
  925. // dwCapabilities Input, Capability settings
  926. // GetInfoFirst if true, the authentication and authorization are retrived via
  927. // QueryBlanket.
  928. // RETURN VALUE:
  929. //
  930. // S_OK all is well
  931. // else error listed in WBEMSVC.H
  932. //
  933. //***************************************************************************
  934. HRESULT WINAPI SetInterfaceSecurityEx(IUnknown * pInterface, COAUTHIDENTITY* pAuthIdent, BSTR pPrincipal,
  935. DWORD dwAuthLevel, DWORD dwImpLevel,
  936. DWORD dwCapabilities, bool GetInfoFirst)
  937. {
  938. DWORD dwAuthenticationArg = RPC_C_AUTHN_WINNT;
  939. DWORD dwAuthorizationArg = RPC_C_AUTHZ_NONE;
  940. if(!IsDcomEnabled()) // For the anon pipes clients, dont even bother
  941. return S_OK;
  942. if(pInterface == NULL)
  943. return WBEM_E_INVALID_PARAMETER;
  944. if(GetInfoFirst)
  945. GetCurrentValue(pInterface, dwAuthenticationArg, dwAuthorizationArg);
  946. // The complicated values should have already been precalced.
  947. // Note : For auth level, we have to check for the 'RPC_C_AUTHN_LEVEL_DEFAULT' (=0) value as well,
  948. // as after negotiation with the server it might result in something high that does need
  949. // the identity structure !!
  950. return WbemSetProxyBlanket(pInterface,
  951. (pPrincipal) ? 16 : dwAuthenticationArg,
  952. dwAuthorizationArg,
  953. pPrincipal,
  954. dwAuthLevel,
  955. dwImpLevel,
  956. ((dwAuthLevel == RPC_C_AUTHN_LEVEL_DEFAULT) ||
  957. (dwAuthLevel >= RPC_C_AUTHN_LEVEL_CONNECT)) ? pAuthIdent : NULL,
  958. dwCapabilities);
  959. }
  960. //***************************************************************************
  961. //
  962. // HRESULT WbemAllocAuthIdentity
  963. //
  964. // DESCRIPTION:
  965. //
  966. // Walks a COAUTHIDENTITY structure and CoTaskMemAllocs the member data and the
  967. // structure.
  968. //
  969. // PARAMETERS:
  970. //
  971. // pUser Input
  972. // pPassword Input
  973. // pDomain Input
  974. // ppAuthInfo Output, Newly allocated structure
  975. //
  976. // RETURN VALUE:
  977. //
  978. // S_OK all is well
  979. //
  980. //***************************************************************************
  981. HRESULT WINAPI WbemAllocAuthIdentity( LPCWSTR pUser, LPCWSTR pPassword, LPCWSTR pDomain, COAUTHIDENTITY** ppAuthIdent )
  982. {
  983. if ( NULL == ppAuthIdent )
  984. {
  985. return WBEM_E_INVALID_PARAMETER;
  986. }
  987. // Handle an allocation failure
  988. COAUTHIDENTITY* pAuthIdent = NULL;
  989. pAuthIdent = (COAUTHIDENTITY*) CoTaskMemAlloc( sizeof(COAUTHIDENTITY) );
  990. if ( NULL == pAuthIdent )
  991. {
  992. return WBEM_E_OUT_OF_MEMORY;
  993. }
  994. memset((void *)pAuthIdent,0,sizeof(COAUTHIDENTITY));
  995. if(bIsNT())
  996. {
  997. // Allocate needed memory and copy in data. Cleanup if anything goes wrong
  998. if ( NULL != pUser )
  999. {
  1000. pAuthIdent->User = (LPWSTR) CoTaskMemAlloc( ( wcslen(pUser) + 1 ) * sizeof( WCHAR ) );
  1001. if ( NULL == pAuthIdent->User )
  1002. {
  1003. WbemFreeAuthIdentity( pAuthIdent );
  1004. return WBEM_E_OUT_OF_MEMORY;
  1005. }
  1006. pAuthIdent->UserLength = wcslen(pUser);
  1007. wcscpy( pAuthIdent->User, pUser );
  1008. }
  1009. if ( NULL != pDomain )
  1010. {
  1011. pAuthIdent->Domain = (LPWSTR) CoTaskMemAlloc( ( wcslen(pDomain) + 1 ) * sizeof( WCHAR ) );
  1012. if ( NULL == pAuthIdent->Domain )
  1013. {
  1014. WbemFreeAuthIdentity( pAuthIdent );
  1015. return WBEM_E_OUT_OF_MEMORY;
  1016. }
  1017. pAuthIdent->DomainLength = wcslen(pDomain);
  1018. wcscpy( pAuthIdent->Domain, pDomain );
  1019. }
  1020. if ( NULL != pPassword )
  1021. {
  1022. pAuthIdent->Password = (LPWSTR) CoTaskMemAlloc( ( wcslen(pPassword) + 1 ) * sizeof( WCHAR ) );
  1023. if ( NULL == pAuthIdent->Password )
  1024. {
  1025. WbemFreeAuthIdentity( pAuthIdent );
  1026. return WBEM_E_OUT_OF_MEMORY;
  1027. }
  1028. pAuthIdent->PasswordLength = wcslen(pPassword);
  1029. wcscpy( pAuthIdent->Password, pPassword );
  1030. }
  1031. pAuthIdent->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  1032. }
  1033. else
  1034. {
  1035. size_t nBufferLength;
  1036. // Allocate needed memory and copy in data. Cleanup if anything goes wrong
  1037. if ( NULL != pUser )
  1038. {
  1039. // How many characters do we need?
  1040. nBufferLength = wcstombs( NULL, pUser, 0 ) + 1;
  1041. pAuthIdent->User = (LPWSTR) CoTaskMemAlloc( nBufferLength );
  1042. if ( NULL == pAuthIdent->User )
  1043. {
  1044. WbemFreeAuthIdentity( pAuthIdent );
  1045. return WBEM_E_OUT_OF_MEMORY;
  1046. }
  1047. pAuthIdent->UserLength = wcslen(pUser);
  1048. wcstombs( (LPSTR) pAuthIdent->User, pUser, nBufferLength );
  1049. }
  1050. if ( NULL != pDomain )
  1051. {
  1052. // How many characters do we need?
  1053. nBufferLength = wcstombs( NULL, pDomain, 0 ) + 1;
  1054. pAuthIdent->Domain = (LPWSTR) CoTaskMemAlloc( nBufferLength );
  1055. if ( NULL == pAuthIdent->Domain )
  1056. {
  1057. WbemFreeAuthIdentity( pAuthIdent );
  1058. return WBEM_E_OUT_OF_MEMORY;
  1059. }
  1060. pAuthIdent->DomainLength = wcslen(pDomain);
  1061. wcstombs( (LPSTR) pAuthIdent->Domain, pDomain, nBufferLength );
  1062. }
  1063. if ( NULL != pPassword )
  1064. {
  1065. // How many characters do we need?
  1066. nBufferLength = wcstombs( NULL, pPassword, 0 ) + 1;
  1067. pAuthIdent->Password = (LPWSTR) CoTaskMemAlloc( nBufferLength );
  1068. if ( NULL == pAuthIdent->Password )
  1069. {
  1070. WbemFreeAuthIdentity( pAuthIdent );
  1071. return WBEM_E_OUT_OF_MEMORY;
  1072. }
  1073. pAuthIdent->PasswordLength = wcslen(pPassword);
  1074. wcstombs( (LPSTR) pAuthIdent->Password, pPassword, nBufferLength );
  1075. }
  1076. pAuthIdent->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  1077. }
  1078. *ppAuthIdent = pAuthIdent;
  1079. return S_OK;
  1080. }
  1081. //***************************************************************************
  1082. //
  1083. // HRESULT WbemFreeAuthIdentity
  1084. //
  1085. // DESCRIPTION:
  1086. //
  1087. // Walks a COAUTHIDENTITY structure and CoTaskMemFrees the member data and the
  1088. // structure.
  1089. //
  1090. // PARAMETERS:
  1091. //
  1092. // pAuthInfo Structure to free
  1093. //
  1094. // RETURN VALUE:
  1095. //
  1096. // S_OK all is well
  1097. //
  1098. //***************************************************************************
  1099. HRESULT WINAPI WbemFreeAuthIdentity( COAUTHIDENTITY* pAuthIdentity )
  1100. {
  1101. // Make sure we have a pointer, then walk the structure members and
  1102. // cleanup.
  1103. if ( NULL != pAuthIdentity )
  1104. {
  1105. if ( NULL != pAuthIdentity->User )
  1106. {
  1107. CoTaskMemFree( pAuthIdentity->User );
  1108. }
  1109. if ( NULL != pAuthIdentity->Password )
  1110. {
  1111. CoTaskMemFree( pAuthIdentity->Password );
  1112. }
  1113. if ( NULL != pAuthIdentity->Domain )
  1114. {
  1115. CoTaskMemFree( pAuthIdentity->Domain );
  1116. }
  1117. CoTaskMemFree( pAuthIdentity );
  1118. }
  1119. return S_OK;
  1120. }
  1121. //***************************************************************************
  1122. //
  1123. // HRESULT WbemCoQueryClientBlanket
  1124. // HRESULT WbemCoImpersonateClient( void)
  1125. // HRESULT WbemCoRevertToSelf( void)
  1126. //
  1127. // DESCRIPTION:
  1128. //
  1129. // These routine wrap some common dcom functions. They are wrapped just in
  1130. // case the code is running on nt 3.51.
  1131. //
  1132. // PARAMETERS:
  1133. //
  1134. // pInterface Interface to be set
  1135. // pauthident Structure with the identity info already set.
  1136. //
  1137. // RETURN VALUE:
  1138. //
  1139. // S_OK all is well
  1140. //
  1141. //***************************************************************************
  1142. HRESULT WINAPI WbemCoQueryClientBlanket(
  1143. /* [out] */ DWORD __RPC_FAR *pAuthnSvc,
  1144. /* [out] */ DWORD __RPC_FAR *pAuthzSvc,
  1145. /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *pServerPrincName,
  1146. /* [out] */ DWORD __RPC_FAR *pAuthnLevel,
  1147. /* [out] */ DWORD __RPC_FAR *pImpLevel,
  1148. /* [out] */ void __RPC_FAR *__RPC_FAR *pPrivs,
  1149. /* [out] */ DWORD __RPC_FAR *pCapabilities)
  1150. {
  1151. IServerSecurity * pss = NULL;
  1152. SCODE sc = WbemCoGetCallContext(IID_IServerSecurity, (void**)&pss);
  1153. if(S_OK == sc)
  1154. {
  1155. pss->QueryBlanket(pAuthnSvc, pAuthzSvc, pServerPrincName,
  1156. pAuthnLevel, pImpLevel, pPrivs, pCapabilities);
  1157. pss->Release();
  1158. }
  1159. return sc;
  1160. }
  1161. HRESULT WINAPI WbemCoImpersonateClient( void)
  1162. {
  1163. IServerSecurity * pss = NULL;
  1164. SCODE sc = WbemCoGetCallContext(IID_IServerSecurity, (void**)&pss);
  1165. if(S_OK == sc)
  1166. {
  1167. sc = pss->ImpersonateClient();
  1168. pss->Release();
  1169. }
  1170. return sc;
  1171. }
  1172. bool WINAPI WbemIsImpersonating(void)
  1173. {
  1174. bool bRet = false;
  1175. IServerSecurity * pss = NULL;
  1176. SCODE sc = WbemCoGetCallContext(IID_IServerSecurity, (void**)&pss);
  1177. if(S_OK == sc)
  1178. {
  1179. bRet = (pss->IsImpersonating() == TRUE);
  1180. pss->Release();
  1181. }
  1182. return bRet;
  1183. }
  1184. HRESULT WINAPI WbemCoRevertToSelf( void)
  1185. {
  1186. IServerSecurity * pss = NULL;
  1187. SCODE sc = WbemCoGetCallContext(IID_IServerSecurity, (void**)&pss);
  1188. if(S_OK == sc)
  1189. {
  1190. sc = pss->RevertToSelf();
  1191. pss->Release();
  1192. }
  1193. return sc;
  1194. }
  1195. void WINAPI CloseStuff()
  1196. {
  1197. if(g_LibHandleOle32.GetHandle())
  1198. {
  1199. FreeLibrary(g_LibHandleOle32.GetHandle());
  1200. g_LibHandleOle32.SetHandle( NULL );
  1201. g_bInitialized = FALSE;
  1202. }
  1203. }
  1204. // Encryption/Decryption helpers
  1205. void EncryptWCHARString( WCHAR* pwszString, ULONG nNumChars )
  1206. {
  1207. if ( NULL != pwszString )
  1208. {
  1209. for ( ULONG x = 0; x < nNumChars; x++ )
  1210. {
  1211. pwszString[x] += 1;
  1212. }
  1213. }
  1214. }
  1215. void DecryptWCHARString( WCHAR* pwszString, ULONG nNumChars )
  1216. {
  1217. if ( NULL != pwszString )
  1218. {
  1219. for ( ULONG x = 0; x < nNumChars; x++ )
  1220. {
  1221. pwszString[x] -= 1;
  1222. }
  1223. }
  1224. }
  1225. void EncryptAnsiString( char* pszString, ULONG nNumChars )
  1226. {
  1227. if ( NULL != pszString )
  1228. {
  1229. for ( ULONG x = 0; x < nNumChars; x++ )
  1230. {
  1231. pszString[x] += 1;
  1232. }
  1233. }
  1234. }
  1235. void DecryptAnsiString( char* pszString, ULONG nNumChars )
  1236. {
  1237. if ( NULL != pszString )
  1238. {
  1239. for ( ULONG x = 0; x < nNumChars; x++ )
  1240. {
  1241. pszString[x] -= 1;
  1242. }
  1243. }
  1244. }
  1245. //***************************************************************************
  1246. //
  1247. // SCODE EncryptCredentials
  1248. //
  1249. // DESCRIPTION:
  1250. //
  1251. // This routine is used to encrypt the supplied authidentity structure.
  1252. //
  1253. // PARAMETERS:
  1254. //
  1255. // pAuthIdent Structure to encrypt.
  1256. //
  1257. // RETURN VALUE:
  1258. //
  1259. // S_OK all is well
  1260. // else error listed in WBEMSVC.H
  1261. //
  1262. //***************************************************************************
  1263. HRESULT WINAPI EncryptCredentials( COAUTHIDENTITY* pAuthIdent )
  1264. {
  1265. HRESULT hr = WBEM_S_NO_ERROR;
  1266. if ( NULL != pAuthIdent )
  1267. {
  1268. // ANSI or WCHAR
  1269. if ( pAuthIdent->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI )
  1270. {
  1271. EncryptAnsiString( (char*) pAuthIdent->User, pAuthIdent->UserLength );
  1272. EncryptAnsiString( (char*) pAuthIdent->Domain, pAuthIdent->DomainLength );
  1273. EncryptAnsiString( (char*) pAuthIdent->Password, pAuthIdent->PasswordLength );
  1274. }
  1275. else
  1276. {
  1277. EncryptWCHARString( pAuthIdent->User, pAuthIdent->UserLength );
  1278. EncryptWCHARString( pAuthIdent->Domain, pAuthIdent->DomainLength );
  1279. EncryptWCHARString( pAuthIdent->Password, pAuthIdent->PasswordLength );
  1280. }
  1281. }
  1282. return hr;
  1283. }
  1284. //***************************************************************************
  1285. //
  1286. // SCODE DecryptCredentials
  1287. //
  1288. // DESCRIPTION:
  1289. //
  1290. // This routine is used to decrypt the supplied authidentity structure. The
  1291. // structure must have been encrypted by EncryptCredentials
  1292. //
  1293. // PARAMETERS:
  1294. //
  1295. // pAuthIdent Structure to decrypt.
  1296. //
  1297. // RETURN VALUE:
  1298. //
  1299. // S_OK all is well
  1300. // else error listed in WBEMSVC.H
  1301. //
  1302. //***************************************************************************
  1303. HRESULT WINAPI DecryptCredentials( COAUTHIDENTITY* pAuthIdent )
  1304. {
  1305. HRESULT hr = WBEM_S_NO_ERROR;
  1306. if ( NULL != pAuthIdent )
  1307. {
  1308. // ANSI or WCHAR
  1309. if ( pAuthIdent->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI )
  1310. {
  1311. DecryptAnsiString( (char*) pAuthIdent->User, pAuthIdent->UserLength );
  1312. DecryptAnsiString( (char*) pAuthIdent->Domain, pAuthIdent->DomainLength );
  1313. DecryptAnsiString( (char*) pAuthIdent->Password, pAuthIdent->PasswordLength );
  1314. }
  1315. else
  1316. {
  1317. DecryptWCHARString( pAuthIdent->User, pAuthIdent->UserLength );
  1318. DecryptWCHARString( pAuthIdent->Domain, pAuthIdent->DomainLength );
  1319. DecryptWCHARString( pAuthIdent->Password, pAuthIdent->PasswordLength );
  1320. }
  1321. }
  1322. return hr;
  1323. }
  1324. //***************************************************************************
  1325. //
  1326. // SCODE SetInterfaceSecurityEncrypt
  1327. //
  1328. // DESCRIPTION:
  1329. //
  1330. // This routine is used by clients in order to set the identity to be used by a connection.
  1331. // The returned AuthIdentity structure will be encrypted before returning.
  1332. //
  1333. // PARAMETERS:
  1334. //
  1335. // pInterface Interface to be set
  1336. // pAuthority Input, authority
  1337. // pUser Input, user name
  1338. // pPassword Input, password.
  1339. // dwAuthLevel Input, Authorization Level
  1340. // dwImpLevel Input, Impersonation Level
  1341. // dwCapabilities Input, Capability settings
  1342. // ppAuthIdent Output, Allocated AuthIdentity if applicable, caller must free
  1343. // manually (can use the FreeAuthInfo function).
  1344. // pPrincipal Output, Principal calculated from supplied data Caller must
  1345. // free using SysFreeString.
  1346. // GetInfoFirst if true, the authentication and authorization are retrived via
  1347. // QueryBlanket.
  1348. //
  1349. // RETURN VALUE:
  1350. //
  1351. // S_OK all is well
  1352. // else error listed in WBEMSVC.H
  1353. //
  1354. //***************************************************************************
  1355. HRESULT WINAPI SetInterfaceSecurityEncrypt(IUnknown * pInterface, LPWSTR pDomain, LPWSTR pUser, LPWSTR pPassword, DWORD dwAuthLevel, DWORD dwImpLevel, DWORD dwCapabilities,
  1356. COAUTHIDENTITY** ppAuthIdent, BSTR* ppPrinciple, bool GetInfoFirst )
  1357. {
  1358. HRESULT hr = SetInterfaceSecurityEx( pInterface, pDomain, pUser, pPassword, dwAuthLevel, dwImpLevel, dwCapabilities,
  1359. ppAuthIdent, ppPrinciple, GetInfoFirst );
  1360. if ( SUCCEEDED( hr ) )
  1361. {
  1362. if ( NULL != ppAuthIdent )
  1363. {
  1364. hr = EncryptCredentials( *ppAuthIdent );
  1365. }
  1366. }
  1367. return hr;
  1368. }
  1369. //***************************************************************************
  1370. //
  1371. // SCODE SetInterfaceSecurityDecrypt
  1372. //
  1373. // DESCRIPTION:
  1374. //
  1375. // This routine is used by clients in order to set the identity to be used by a connection.
  1376. // It will unencrypt and reencrypt the auth identity structure in place.
  1377. //
  1378. // PARAMETERS:
  1379. //
  1380. // pInterface Interface to be set
  1381. // pAuthIdent Input, Preset COAUTHIDENTITY structure pointer.
  1382. // pPrincipal Input, Preset principal argument
  1383. // dwAuthLevel Input, Authorization Level
  1384. // dwImpLevel Input, Impersonation Level
  1385. // dwCapabilities Input, Capability settings
  1386. // GetInfoFirst if true, the authentication and authorization are retrived via
  1387. // QueryBlanket.
  1388. // RETURN VALUE:
  1389. //
  1390. // S_OK all is well
  1391. // else error listed in WBEMSVC.H
  1392. //
  1393. //***************************************************************************
  1394. HRESULT WINAPI SetInterfaceSecurityDecrypt(IUnknown * pInterface, COAUTHIDENTITY* pAuthIdent, BSTR pPrincipal,
  1395. DWORD dwAuthLevel, DWORD dwImpLevel,
  1396. DWORD dwCapabilities, bool GetInfoFirst )
  1397. {
  1398. // Decrypt first
  1399. HRESULT hr = DecryptCredentials( pAuthIdent );
  1400. if ( SUCCEEDED( hr ) )
  1401. {
  1402. hr = SetInterfaceSecurityEx( pInterface, pAuthIdent, pPrincipal, dwAuthLevel, dwImpLevel,
  1403. dwCapabilities, GetInfoFirst );
  1404. hr = EncryptCredentials( pAuthIdent );
  1405. }
  1406. return hr;
  1407. }