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.

306 lines
7.8 KiB

  1. #include <crtdbg.h>
  2. #include <comdef.h>
  3. #include <iostream>
  4. #include <memory>
  5. #include <string>
  6. #include <wbemprov.h>
  7. #include <genlex.h> //for wmi object path parser
  8. #include <objbase.h>
  9. #include <wlbsconfig.h>
  10. #include <ntrkcomm.h>
  11. using namespace std;
  12. #include "objpath.h"
  13. #include "debug.h"
  14. #include "utils.h"
  15. #include <strsafe.h>
  16. #include "utils.tmh"
  17. ////////////////////////////////////////////////////////////////////////////////
  18. //
  19. // CErrorWlbsControl::CErrorWlbsControl
  20. //
  21. // Purpose: This object is ultimately caught and used to send WLBS error codes
  22. // back to the user via an __ExtendedStatus object. Strings are not
  23. // sent back in release mode due to localization concerns.
  24. //
  25. ////////////////////////////////////////////////////////////////////////////////
  26. CErrorWlbsControl::CErrorWlbsControl
  27. (
  28. DWORD a_dwError,
  29. WLBS_COMMAND a_CmdCommand,
  30. BOOL a_bAllClusterCall
  31. )
  32. {
  33. #ifdef DBG
  34. static char* pszWlbsCommand[] =
  35. {
  36. "WlbsAddPortRule",
  37. "WlbsAddressToName",
  38. "WlbsAddressToString",
  39. "WlbsAdjust",
  40. "WlbsCommitChanges",
  41. "WlbsDeletePortRule",
  42. "WlbsDestinationSet",
  43. "WlbsDisable",
  44. "WlbsDrain",
  45. "WlbsDrainStop",
  46. "WlbsEnable",
  47. "WlbsFormatMessage",
  48. "WlbsGetEffectiveVersion",
  49. "WlbsGetNumPortRules",
  50. "WlbsEnumPortRules",
  51. "WlbsGetPortRule",
  52. "WlbsInit",
  53. "WlbsPasswordSet",
  54. "WlbsPortSet",
  55. "WlbsQuery",
  56. "WlbsReadReg",
  57. "WlbsResolve",
  58. "WlbsResume",
  59. "WlbsSetDefaults",
  60. "WlbsSetRemotePassword",
  61. "WlbsStart",
  62. "WlbsStop",
  63. "WlbsSuspend",
  64. "WlbsTimeoutSet",
  65. "WlbsWriteReg",
  66. "WlbsQueryPortState"
  67. };
  68. char buf[512];
  69. if (a_CmdCommand <= CmdWlbsWriteReg)
  70. {
  71. if (a_CmdCommand != CmdWlbsQuery || a_dwError != WLBS_TIMEOUT)
  72. {
  73. StringCbPrintfA(buf, sizeof(buf), "wlbsprov: %s failed, AllCluster = %d, error = %d\n",
  74. pszWlbsCommand[a_CmdCommand], (int)a_bAllClusterCall, a_dwError);
  75. }
  76. }
  77. else
  78. {
  79. StringCbPrintfA(buf, sizeof(buf), "wlbsprov: %d failed, AllCluster = %d, error = %d\n",
  80. a_CmdCommand, (int)a_bAllClusterCall, a_dwError);
  81. }
  82. OutputDebugStringA(buf);
  83. #endif
  84. WlbsFormatMessageWrapper( a_dwError,
  85. a_CmdCommand,
  86. a_bAllClusterCall,
  87. m_wstrDescription );
  88. m_dwError = a_dwError;
  89. }
  90. ////////////////////////////////////////////////////////////////////////////////
  91. //
  92. // AddressToString
  93. //
  94. // Purpose: Converts a DWORD address to a wstring in dotted notation. This
  95. // function wraps the WlbsAddressToString function.
  96. //
  97. //
  98. ////////////////////////////////////////////////////////////////////////////////
  99. void AddressToString( DWORD a_dwAddress, wstring& a_szIPAddress )
  100. {
  101. DWORD dwLenIPAddress = 32;
  102. WCHAR *szIPAddress = new WCHAR[dwLenIPAddress];
  103. if( !szIPAddress )
  104. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  105. try {
  106. for( short nTryTwice = 2; nTryTwice > 0; nTryTwice--) {
  107. if( ::WlbsAddressToString( a_dwAddress, szIPAddress, &dwLenIPAddress ) )
  108. break;
  109. delete [] szIPAddress;
  110. szIPAddress = new WCHAR[dwLenIPAddress];
  111. if( !szIPAddress )
  112. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  113. }
  114. if( !nTryTwice )
  115. throw _com_error( WBEM_E_FAILED );
  116. a_szIPAddress = szIPAddress;
  117. if ( szIPAddress ) {
  118. delete [] szIPAddress;
  119. szIPAddress = NULL;
  120. }
  121. }
  122. catch(...) {
  123. if ( szIPAddress )
  124. delete [] szIPAddress;
  125. throw;
  126. }
  127. }
  128. ////////////////////////////////////////////////////////////////////////////////
  129. //
  130. // CWmiWlbsCluster::FormatMessage
  131. //
  132. // Purpose: Obtains a descriptive string associated with a WLBS return value.
  133. //
  134. ////////////////////////////////////////////////////////////////////////////////
  135. void WlbsFormatMessageWrapper
  136. (
  137. DWORD a_dwError,
  138. WLBS_COMMAND a_Command,
  139. BOOL a_bClusterWide,
  140. wstring& a_wstrMessage
  141. )
  142. {
  143. DWORD dwBuffSize = 255;
  144. TCHAR* pszMessageBuff = new WCHAR[dwBuffSize];
  145. if( !pszMessageBuff )
  146. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  147. try {
  148. for( short nTryTwice = 2; nTryTwice > 0; nTryTwice-- ) {
  149. if( WlbsFormatMessage( a_dwError,
  150. a_Command,
  151. a_bClusterWide,
  152. pszMessageBuff,
  153. &dwBuffSize)
  154. ) break;
  155. delete [] pszMessageBuff;
  156. pszMessageBuff = new WCHAR[dwBuffSize];
  157. if( !pszMessageBuff )
  158. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  159. }
  160. if( !nTryTwice )
  161. throw _com_error( WBEM_E_FAILED );
  162. a_wstrMessage = pszMessageBuff;
  163. delete [] pszMessageBuff;
  164. } catch (...) {
  165. if( pszMessageBuff )
  166. delete [] pszMessageBuff;
  167. throw;
  168. }
  169. }
  170. ////////////////////////////////////////////////////////////////////////////////
  171. //
  172. // ClusterStatusOK
  173. //
  174. // Purpose:
  175. //
  176. ////////////////////////////////////////////////////////////////////////////////
  177. BOOL ClusterStatusOK(DWORD a_dwStatus)
  178. {
  179. if( a_dwStatus > 0 && a_dwStatus <= WLBS_MAX_HOSTS )
  180. return TRUE;
  181. switch( a_dwStatus ) {
  182. case WLBS_SUSPENDED:
  183. case WLBS_STOPPED:
  184. case WLBS_DRAINING:
  185. case WLBS_CONVERGING:
  186. case WLBS_CONVERGED:
  187. return TRUE;
  188. break;
  189. default:
  190. return FALSE;
  191. }
  192. }
  193. ////////////////////////////////////////////////////////////////////////////////
  194. //
  195. // Check_Load_Unload_Driver_Privilege
  196. //
  197. // Purpose: This function checks if the SE_LOAD_DRIVER_NAME (= "SeLoadDriverPrivilege")
  198. // is enabled in the impersonation access token. Ofcourse, this function
  199. // must be called AFTER impersonating the client.
  200. //
  201. ////////////////////////////////////////////////////////////////////////////////
  202. BOOL Check_Load_Unload_Driver_Privilege()
  203. {
  204. PRIVILEGE_SET PrivilegeSet;
  205. LUID Luid;
  206. BOOL bResult = FALSE;
  207. HANDLE TokenHandle = NULL;
  208. TRACE_INFO("->%!FUNC!");
  209. // Look up the LUID for "SeLoadDriverPrivilege"
  210. if (!LookupPrivilegeValue(NULL, // lookup privilege on local system
  211. SE_LOAD_DRIVER_NAME, // "SeLoadDriverPrivilege" : Load and unload device drivers
  212. &Luid)) // receives LUID of privilege
  213. {
  214. TRACE_CRIT("%!FUNC! LookupPrivilegeValue error: %u", GetLastError());
  215. TRACE_INFO("<-%!FUNC! Returning FALSE");
  216. return FALSE;
  217. }
  218. //
  219. // Get a handle to the impersonation access token with TOKEN_QUERY right.
  220. //
  221. // Note: If this thread is NOT impersonating, then, the following call
  222. // will fail with ERROR_NO_TOKEN.
  223. //
  224. if (!OpenThreadToken(GetCurrentThread(),
  225. TOKEN_QUERY,
  226. FALSE, // Use the credentials of the client that is being impersonated
  227. &TokenHandle))
  228. {
  229. TRACE_CRIT("%!FUNC! OpenThreadToken error: %u", GetLastError());
  230. TRACE_INFO("<-%!FUNC! Returning FALSE");
  231. return FALSE;
  232. }
  233. PrivilegeSet.PrivilegeCount = 1;
  234. PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
  235. PrivilegeSet.Privilege[0].Luid = Luid;
  236. PrivilegeSet.Privilege[0].Attributes = 0;
  237. if (!PrivilegeCheck(TokenHandle, &PrivilegeSet, &bResult))
  238. {
  239. bResult = FALSE;
  240. TRACE_CRIT("%!FUNC! PrivilegeCheck error: %u", GetLastError());
  241. }
  242. CloseHandle(TokenHandle);
  243. TRACE_INFO(L"<-%!FUNC! Returning %ls", bResult ? L"TRUE" : L"FALSE");
  244. return bResult;
  245. }