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.

260 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. metabase.cxx
  5. Abstract:
  6. IIS MetaBase exported routines.
  7. Routine comments are in metadata.h.
  8. Author:
  9. Michael W. Thomas 31-May-96
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #include <initguid.h>
  14. DEFINE_GUID(CLSID_MDCOM,
  15. 0xba4e57f0, 0xfab6, 0x11cf, 0x9d, 0x1a, 0x00, 0xaa, 0x00, 0xa7, 0x0d, 0x51);
  16. DEFINE_GUID(CLSID_MDCOMEXE,
  17. 0xba4e57f1, 0xfab6, 0x11cf, 0x9d, 0x1a, 0x00, 0xaa, 0x00, 0xa7, 0x0d, 0x51);
  18. DEFINE_GUID(IID_IMDCOM,
  19. 0xc1aa48c0, 0xfacc, 0x11cf, 0x9d, 0x1a, 0x00, 0xaa, 0x00, 0xa7, 0x0d, 0x51);
  20. DEFINE_GUID(IID_IMDCOM2,
  21. 0x08dbe811, 0x20e5, 0x4e09, 0xb0, 0xc8, 0xcf, 0x87, 0x19, 0x0c, 0xe6, 0x0e);
  22. DEFINE_GUID(IID_IMDCOM3,
  23. 0xa53fd4aa, 0x6f0d, 0x4fe3, 0x9f, 0x81, 0x2b, 0x56, 0x19, 0x7b, 0x47, 0xdb);
  24. DEFINE_GUID(IID_IMDCOMSINK_A,
  25. 0x5229ea36, 0x1bdf, 0x11d0, 0x9d, 0x1c, 0x00, 0xaa, 0x00, 0xa7, 0x0d, 0x51);
  26. DEFINE_GUID(IID_IMDCOMSINK_W,
  27. 0x6906ee20, 0xb69f, 0x11d0, 0xb9, 0xb9, 0x00, 0xa0, 0xc9, 0x22, 0xe7, 0x50);
  28. extern "C"
  29. {
  30. BOOL
  31. WINAPI
  32. DllMain(
  33. HINSTANCE hDll,
  34. DWORD dwReason,
  35. LPVOID lpvReserved
  36. );
  37. }
  38. HRESULT
  39. AssureRunningAsAdministrator(VOID);
  40. BOOL
  41. WINAPI
  42. DllMain(
  43. HINSTANCE ,
  44. DWORD dwReason,
  45. LPVOID
  46. )
  47. /*++
  48. Routine Description:
  49. DLL entrypoint.
  50. Arguments:
  51. hDLL - Instance handle.
  52. Reason - The reason the entrypoint was called.
  53. DLL_PROCESS_ATTACH
  54. DLL_PROCESS_DETACH
  55. DLL_THREAD_ATTACH
  56. DLL_THREAD_DETACH
  57. Reserved - Reserved.
  58. Return Value:
  59. BOOL - TRUE if the action succeeds.
  60. --*/
  61. {
  62. BOOL bReturn = TRUE;
  63. HRESULT hr = S_OK;
  64. switch ( dwReason )
  65. {
  66. case DLL_PROCESS_ATTACH:
  67. if (InterlockedIncrement((long *)&g_dwProcessAttached) > 1)
  68. {
  69. DBGPRINTF(( DBG_CONTEXT,
  70. "Metadata.dll failed to load.\n"
  71. "Most likely cause is IISADMIN service is already running.\n"
  72. "Do a \"net stop iisadmin\" and stop all instances of inetinfo.exe.\n" ));
  73. bReturn = FALSE;
  74. }
  75. else
  76. {
  77. CREATE_DEBUG_PRINT_OBJECT("Metadata");
  78. LOAD_DEBUG_FLAGS_FROM_REG_STR( "System\\CurrentControlSet\\Services\\iisadmin\\Parameters", 0 );
  79. g_pboMasterRoot = NULL;
  80. g_phHandleHead = NULL;
  81. g_ppbdDataHashTable = NULL;
  82. for (int i = 0; i < EVENT_ARRAY_LENGTH; i++)
  83. {
  84. g_phEventHandles[i] = NULL;
  85. }
  86. g_hReadSaveSemaphore = NULL;
  87. g_bSaveDisallowed = FALSE;
  88. g_rSinkResource = new TS_RESOURCE();
  89. if (g_rSinkResource == NULL)
  90. {
  91. bReturn = FALSE;
  92. }
  93. if (bReturn)
  94. {
  95. hr = AssureRunningAsAdministrator();
  96. if ( SUCCEEDED(hr) )
  97. {
  98. g_pFactory = new CMDCOMSrvFactory();
  99. if (g_pFactory == NULL)
  100. {
  101. bReturn = FALSE;
  102. }
  103. }
  104. }
  105. if (bReturn)
  106. {
  107. bReturn = InitializeMetabaseSecurity();
  108. }
  109. }
  110. break;
  111. case DLL_PROCESS_DETACH:
  112. if (InterlockedDecrement((long *)&g_dwProcessAttached) == 0)
  113. {
  114. g_LockMasterResource.WriteLock();
  115. // TerminateWorker1 was not called, or did not succeed, so call it in a loop until it reaches 0
  116. // stops EWR, saves the metabase (if there are any unsaved changes) and calls TerminateWorker.
  117. // However if TerminateWorker1 fails it won't decrement g_dwInitialized and we will be caught in an endless loop,
  118. // so exit the loop on failure from TerminateWorker1
  119. while ( ( g_dwInitialized > 0 ) && SUCCEEDED(hr) )
  120. {
  121. hr = TerminateWorker1(TRUE);
  122. }
  123. // In all cases g_dwInitialized must be 0 now.
  124. g_dwInitialized = 0;
  125. // In all cases call TerminateWorker too
  126. TerminateWorker();
  127. g_LockMasterResource.WriteUnlock();
  128. delete g_rSinkResource;
  129. g_rSinkResource = NULL;
  130. delete g_pFactory;
  131. g_pFactory = NULL;
  132. TerminateMetabaseSecurity();
  133. DELETE_DEBUG_PRINT_OBJECT();
  134. }
  135. break;
  136. default:
  137. break;
  138. }
  139. return bReturn;
  140. }
  141. HRESULT
  142. AssureRunningAsAdministrator(VOID)
  143. /*++
  144. Routine Description:
  145. Verifies that process that loaded the dll is the process of IISADMIN service.
  146. Since there is no easy way to get the pid of the service if it is launched
  147. under a debugger, just checks that the owner of the process is Builtin\Administrators or LocalSystem.
  148. Arguments:
  149. None
  150. Returns:
  151. HRESULT. S_OK success, E_ACCESSDENIED if not running in IISADMIN, E_* on failure.
  152. --*/
  153. {
  154. // Locals
  155. HRESULT hr = S_OK;
  156. BOOL fRet;
  157. DWORD dwError;
  158. PSID psidOwner = NULL;
  159. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  160. // Get the security info of the process
  161. dwError = GetSecurityInfo( GetCurrentProcess(),
  162. SE_KERNEL_OBJECT,
  163. OWNER_SECURITY_INFORMATION,
  164. &psidOwner,
  165. NULL,
  166. NULL,
  167. NULL,
  168. &pSecurityDescriptor );
  169. if ( dwError != ERROR_SUCCESS )
  170. {
  171. hr = HRESULT_FROM_WIN32( dwError );
  172. DBGPRINTF(( DBG_CONTEXT,
  173. "GetSecurityInfo() failed in AssureRunningAsAdministrator hr=0x%08x.\n",
  174. hr ));
  175. goto exit;
  176. }
  177. if ( psidOwner == NULL )
  178. {
  179. hr = E_FAIL;
  180. DBGPRINTF(( DBG_CONTEXT,
  181. "GetSecurityInfo() returned NULL sid.\n" ));
  182. goto exit;
  183. }
  184. // Check whether we are running as administrators
  185. fRet = IsWellKnownSid( psidOwner,
  186. WinBuiltinAdministratorsSid );
  187. if ( !fRet )
  188. {
  189. // Check whether we are running as local system
  190. fRet = IsWellKnownSid( psidOwner,
  191. WinLocalSystemSid );
  192. }
  193. if ( !fRet )
  194. {
  195. hr = E_ACCESSDENIED;
  196. DBGPRINTF(( DBG_CONTEXT,
  197. "Not running as Administrators/LocalSystem in AssureRunningInIISADMIN.\n",
  198. hr ));
  199. goto exit;
  200. }
  201. exit:
  202. // Cleanup
  203. if ( pSecurityDescriptor != NULL )
  204. {
  205. LocalFree( pSecurityDescriptor );
  206. pSecurityDescriptor = NULL;
  207. }
  208. return hr;
  209. }