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.

381 lines
11 KiB

  1. //***************************************************************************
  2. //
  3. // METHPROV.CPP
  4. //
  5. // Module: WBEM Method provider sample code
  6. //
  7. // Purpose: Defines the CMethodPro class. An object of this class is
  8. // created by the class factory for each connection.
  9. //
  10. // Copyright (c)1998 Microsoft Corporation, All Rights Reserved
  11. //
  12. //***************************************************************************
  13. #include <objbase.h>
  14. #include "methprov.h"
  15. #include <process.h>
  16. #include <wbemidl.h>
  17. #include <stdio.h>
  18. #include "cominit.h"
  19. //***************************************************************************
  20. //
  21. // CMethodPro::CMethodPro
  22. // CMethodPro::~CMethodPro
  23. //
  24. //***************************************************************************
  25. CMethodPro::CMethodPro()
  26. {
  27. InterlockedIncrement(&g_cObj);
  28. return;
  29. }
  30. CMethodPro::~CMethodPro(void)
  31. {
  32. InterlockedDecrement(&g_cObj);
  33. return;
  34. }
  35. //***************************************************************************
  36. //
  37. // CMethodPro::QueryInterface
  38. // CMethodPro::AddRef
  39. // CMethodPro::Release
  40. //
  41. // Purpose: IUnknown members for CMethodPro object.
  42. //***************************************************************************
  43. STDMETHODIMP CMethodPro::QueryInterface(REFIID riid, PPVOID ppv)
  44. {
  45. *ppv=NULL;
  46. if (IID_IUnknown==riid || IID_IWbemServices == riid || IID_IWbemProviderInit==riid)
  47. if(riid== IID_IWbemServices){
  48. *ppv=(IWbemServices*)this;
  49. }
  50. if(IID_IUnknown==riid || riid== IID_IWbemProviderInit){
  51. *ppv=(IWbemProviderInit*)this;
  52. }
  53. if (NULL!=*ppv) {
  54. AddRef();
  55. return NOERROR;
  56. }
  57. else
  58. return E_NOINTERFACE;
  59. }
  60. STDMETHODIMP_(ULONG) CMethodPro::AddRef(void)
  61. {
  62. return ++m_cRef;
  63. }
  64. STDMETHODIMP_(ULONG) CMethodPro::Release(void)
  65. {
  66. ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
  67. if (0L == nNewCount)
  68. delete this;
  69. return nNewCount;
  70. }
  71. /***********************************************************************
  72. * *
  73. *CMethodPro::Initialize *
  74. * *
  75. *Purpose: This is the implementation of IWbemProviderInit. The method *
  76. * is need to initialize with CIMOM. *
  77. * *
  78. ***********************************************************************/
  79. STDMETHODIMP CMethodPro::Initialize(LPWSTR pszUser, LONG lFlags,
  80. LPWSTR pszNamespace, LPWSTR pszLocale,
  81. IWbemServices *pNamespace,
  82. IWbemContext *pCtx,
  83. IWbemProviderInitSink *pInitSink)
  84. {
  85. m_pWbemSvcs=pNamespace;
  86. m_pWbemSvcs->AddRef();
  87. //Let CIMOM know your initialized
  88. //===============================
  89. pInitSink->SetStatus(WBEM_S_INITIALIZED,0);
  90. return WBEM_S_NO_ERROR;
  91. }
  92. /************************************************************************
  93. * *
  94. *CMethodPro::ExecMethodAsync *
  95. * *
  96. *Purpose: This is the Async function implementation. *
  97. * The only method supported in this sample is GetUserID. It *
  98. * returns the user name and domain name of the thread in which *
  99. * the provider is called. The mof definition is *
  100. * *
  101. * [dynamic: ToInstance, provider("UserIDProvider")]class UserID *
  102. * { *
  103. * [implemented, static] *
  104. * void GetUserID( *
  105. * [out]string sDomain, *
  106. * [out] string sUser, *
  107. * [out] string dImpLevel, *
  108. * [out] string sPrivileges [], *
  109. * [out] boolean bPrivilegesEnabled []); *
  110. * }; *
  111. * *
  112. ************************************************************************/
  113. STDMETHODIMP CMethodPro::ExecMethodAsync(const BSTR ObjectPath, const BSTR MethodName,
  114. long lFlags, IWbemContext* pCtx, IWbemClassObject* pInParams,
  115. IWbemObjectSink* pResultSink)
  116. {
  117. HRESULT hr = WBEM_E_FAILED;
  118. if (FAILED (WbemCoImpersonateClient ()))
  119. return WBEM_E_ACCESS_DENIED;
  120. IWbemClassObject * pClass = NULL;
  121. IWbemClassObject * pOutClass = NULL;
  122. IWbemClassObject* pOutParams = NULL;
  123. if(_wcsicmp(MethodName, L"GetUserID"))
  124. return WBEM_E_INVALID_PARAMETER;
  125. // Allocate some BSTRs
  126. BSTR ClassName = SysAllocString(L"UserID");
  127. BSTR DomainOutputArgName = SysAllocString(L"sDomain");
  128. BSTR UserOutputArgName = SysAllocString(L"sUser");
  129. BSTR ImpOutputArgName = SysAllocString(L"sImpLevel");
  130. BSTR PrivOutputArgName = SysAllocString(L"sPrivileges");
  131. BSTR EnabledOutputArgName = SysAllocString(L"bPrivilegesEnabled");
  132. BSTR retValName = SysAllocString(L"ReturnValue");
  133. // Get the class object, this is hard coded and matches the class
  134. // in the MOF. A more sophisticated example would parse the
  135. // ObjectPath to determine the class and possibly the instance.
  136. hr = m_pWbemSvcs->GetObject(ClassName, 0, pCtx, &pClass, NULL);
  137. if(hr != S_OK)
  138. {
  139. pResultSink->SetStatus(0,hr, NULL, NULL);
  140. return WBEM_S_NO_ERROR;
  141. }
  142. // This method returns values, and so create an instance of the
  143. // output argument class.
  144. hr = pClass->GetMethod(MethodName, 0, NULL, &pOutClass);
  145. pOutClass->SpawnInstance(0, &pOutParams);
  146. // Get the user and domain from the thread token
  147. HANDLE hToken;
  148. HANDLE hThread = GetCurrentThread ();
  149. // Open thread token
  150. if (OpenThreadToken (hThread, TOKEN_QUERY, true, &hToken))
  151. {
  152. DWORD dwRequiredSize = 0;
  153. DWORD dwLastError = 0;
  154. bool status = false;
  155. // Step 0 - get impersonation level
  156. SECURITY_IMPERSONATION_LEVEL secImpLevel;
  157. if (GetTokenInformation (hToken, TokenImpersonationLevel, &secImpLevel,
  158. sizeof (SECURITY_IMPERSONATION_LEVEL), &dwRequiredSize))
  159. {
  160. VARIANT var;
  161. VariantInit (&var);
  162. var.vt = VT_BSTR;
  163. switch (secImpLevel)
  164. {
  165. case SecurityAnonymous:
  166. var.bstrVal = SysAllocString (L"Anonymous");
  167. break;
  168. case SecurityIdentification:
  169. var.bstrVal = SysAllocString (L"Identification");
  170. break;
  171. case SecurityImpersonation:
  172. var.bstrVal = SysAllocString (L"Impersonation");
  173. break;
  174. case SecurityDelegation:
  175. var.bstrVal = SysAllocString (L"Delegation");
  176. break;
  177. default:
  178. var.bstrVal = SysAllocString (L"Unknown");
  179. break;
  180. }
  181. pOutParams->Put(ImpOutputArgName , 0, &var, 0);
  182. VariantClear (&var);
  183. }
  184. DWORD dwUSize = sizeof (TOKEN_USER);
  185. TOKEN_USER *tu = (TOKEN_USER *) new BYTE [dwUSize];
  186. // Step 1 - get user info
  187. if (0 == GetTokenInformation (hToken, TokenUser,
  188. (LPVOID) tu, dwUSize, &dwRequiredSize))
  189. {
  190. delete [] tu;
  191. dwUSize = dwRequiredSize;
  192. dwRequiredSize = 0;
  193. tu = (TOKEN_USER *) new BYTE [dwUSize];
  194. if (!GetTokenInformation (hToken, TokenUser, (LPVOID) tu, dwUSize,
  195. &dwRequiredSize))
  196. dwLastError = GetLastError ();
  197. else
  198. status = true;
  199. }
  200. if (status)
  201. {
  202. // Dig out the user info
  203. dwRequiredSize = BUFSIZ;
  204. char *userName = new char [dwRequiredSize];
  205. char *domainName = new char [dwRequiredSize];
  206. SID_NAME_USE eUse;
  207. LookupAccountSid (NULL, (tu->User).Sid, userName, &dwRequiredSize,
  208. domainName, &dwRequiredSize, &eUse);
  209. VARIANT var;
  210. VariantInit (&var);
  211. var.vt = VT_BSTR;
  212. wchar_t wUserName [BUFSIZ];
  213. size_t len = mbstowcs( wUserName, userName, strlen (userName));
  214. wUserName [len] = NULL;
  215. var.bstrVal = SysAllocString (wUserName);
  216. pOutParams->Put(UserOutputArgName , 0, &var, 0);
  217. SysFreeString (var.bstrVal);
  218. wchar_t wDomainName [BUFSIZ];
  219. len = mbstowcs( wDomainName, domainName, strlen (domainName));
  220. wDomainName [len] = NULL;
  221. var.bstrVal = SysAllocString (wDomainName);
  222. pOutParams->Put(DomainOutputArgName , 0, &var, 0);
  223. VariantClear (&var);
  224. delete [] userName;
  225. delete [] domainName;
  226. }
  227. delete [] tu;
  228. // Step 2 - get privilege info
  229. status = false;
  230. dwRequiredSize = 0;
  231. DWORD dwSize = sizeof (TOKEN_PRIVILEGES);
  232. TOKEN_PRIVILEGES *tp = (TOKEN_PRIVILEGES *) new BYTE [dwSize];
  233. // Step 2 - get privilege info
  234. if (0 == GetTokenInformation (hToken, TokenPrivileges,
  235. (LPVOID) tp, dwSize, &dwRequiredSize))
  236. {
  237. delete [] tp;
  238. dwSize = dwRequiredSize;
  239. dwRequiredSize = 0;
  240. tp = (TOKEN_PRIVILEGES *) new BYTE [dwSize];
  241. if (!GetTokenInformation (hToken, TokenPrivileges,
  242. (LPVOID) tp, dwSize, &dwRequiredSize))
  243. {
  244. dwLastError = GetLastError ();
  245. }
  246. else
  247. status = true;
  248. }
  249. else
  250. status = true;
  251. if (status)
  252. {
  253. SAFEARRAYBOUND rgsabound;
  254. rgsabound.cElements = tp->PrivilegeCount;
  255. rgsabound.lLbound = 0;
  256. SAFEARRAY *pPrivArray = SafeArrayCreate (VT_BSTR, 1, &rgsabound);
  257. SAFEARRAY *pEnabArray = SafeArrayCreate (VT_BOOL, 1, &rgsabound);
  258. for (ULONG i = 0; i < tp->PrivilegeCount; i++)
  259. {
  260. TCHAR name [BUFSIZ];
  261. WCHAR wName [BUFSIZ];
  262. DWORD dwRequiredSize = BUFSIZ;
  263. if (LookupPrivilegeName (NULL, &(tp->Privileges [i].Luid), name, &dwRequiredSize))
  264. {
  265. VARIANT_BOOL enabled = (tp->Privileges [i].Attributes &
  266. (SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT)) ?
  267. VARIANT_TRUE : VARIANT_FALSE;
  268. mbstowcs (wName, name, strlen (name));
  269. wName [dwRequiredSize] = NULL;
  270. BSTR bsName = SysAllocString (wName);
  271. SafeArrayPutElement (pPrivArray, (LONG*) &i, bsName);
  272. SafeArrayPutElement (pEnabArray, (LONG*) &i, &enabled);
  273. }
  274. }
  275. VARIANT var1;
  276. var1.vt = VT_ARRAY|VT_BSTR;
  277. var1.parray = pPrivArray;
  278. pOutParams->Put(PrivOutputArgName , 0, &var1, 0);
  279. VariantClear (&var1);
  280. var1.vt = VT_ARRAY|VT_BOOL;
  281. var1.parray = pEnabArray;
  282. pOutParams->Put(EnabledOutputArgName , 0, &var1, 0);
  283. VariantClear (&var1);
  284. }
  285. delete [] tp;
  286. CloseHandle (hToken);
  287. }
  288. CloseHandle (hThread);
  289. // Send the output object back to the client via the sink. Then
  290. // release the pointers and free the strings.
  291. hr = pResultSink->Indicate(1, &pOutParams);
  292. pOutParams->Release();
  293. pOutClass->Release();
  294. pClass->Release();
  295. SysFreeString(ClassName);
  296. SysFreeString(DomainOutputArgName);
  297. SysFreeString(UserOutputArgName);
  298. SysFreeString(ImpOutputArgName);
  299. SysFreeString(PrivOutputArgName);
  300. SysFreeString(EnabledOutputArgName);
  301. SysFreeString(retValName);
  302. // all done now, set the status
  303. hr = pResultSink->SetStatus(0,WBEM_S_NO_ERROR,NULL,NULL);
  304. return WBEM_S_NO_ERROR;
  305. }