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.

435 lines
13 KiB

  1. // logui.cpp : Implementation of CLoguiApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "logui.h"
  4. #include "wrapmb.h"
  5. #include <iiscnfg.h>
  6. #include <iiscnfgp.h>
  7. #include <inetinfo.h>
  8. #include "initguid.h"
  9. #include <logtype.h>
  10. #include <ilogobj.hxx>
  11. #include "uincsa.h"
  12. #include "uiextnd.h"
  13. #include "uimsft.h"
  14. #include "uiodbc.h"
  15. #include "dcomperm.h"
  16. //_tlid
  17. // the global factory objects
  18. CFacNcsaLogUI facNcsa;
  19. CFacMsftLogUI facMsft;
  20. CFacOdbcLogUI facOdbc;
  21. CFacExtndLogUI facExtnd;
  22. const GUID CDECL BASED_CODE _tlid =
  23. { 0x31dcab8a, 0xbb3e, 0x11d0, { 0x92, 0x99, 0x0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b } };
  24. const WORD _wVerMajor = 1;
  25. const WORD _wVerMinor = 0;
  26. // the key type strings for the metabaes keys
  27. #define SZ_LOGGING_MAIN_TYPE _T("IIsLogModules")
  28. #define SZ_LOGGING_TYPE _T("IIsLogModule")
  29. BOOL _cdecl RegisterInMetabase( PWCHAR pszMachine );
  30. int SetInfoAdminACL( CWrapMetaBase* pMB, LPCTSTR szSubKeyPath );
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36. CLoguiApp NEAR theApp;
  37. HINSTANCE g_hInstance = NULL;
  38. //---------------------------------------------------------------
  39. void CLoguiApp::PrepHelp( OLECHAR* pocMetabasePath )
  40. {
  41. // figure out the correct help file to use
  42. CString szMetaPath = pocMetabasePath;
  43. szMetaPath.MakeLower();
  44. // default to the w3 help
  45. UINT iHelp = IDS_HELPLOC_W3SVCHELP;
  46. // test for ftp
  47. if ( szMetaPath.Find(_T("msftpsvc")) >= 0 )
  48. iHelp = IDS_HELPLOC_FTPHELP;
  49. // finally, we need to redirect the winhelp file location to something more desirable
  50. CString sz;
  51. CString szHelpLocation;
  52. sz.LoadString( iHelp );
  53. // expand the path
  54. ExpandEnvironmentStrings(
  55. sz, // pointer to string with environment variables
  56. szHelpLocation.GetBuffer(MAX_PATH + 1), // pointer to string with expanded environment variables
  57. MAX_PATH // maximum characters in expanded string
  58. );
  59. szHelpLocation.ReleaseBuffer();
  60. // free the existing path, and copy in the new one
  61. if ( m_pszHelpFilePath )
  62. free((void*)m_pszHelpFilePath);
  63. m_pszHelpFilePath = _tcsdup(szHelpLocation);
  64. }
  65. ////////////////////////////////////////////////////////////////////////////
  66. // CLoguiApp::InitInstance - DLL initialization
  67. BOOL CLoguiApp::InitInstance()
  68. {
  69. g_hInstance = m_hInstance;
  70. BOOL bInit = COleControlModule::InitInstance();
  71. if (bInit)
  72. {
  73. CString sz;
  74. // set the name of the application correctly
  75. sz.LoadString( IDS_LOGUI_ERR_TITLE );
  76. // Never free this string because now MF...kingC
  77. // uses it internally BEFORE call to this function
  78. //free((void*)m_pszAppName);
  79. m_pszAppName = _tcsdup(sz);
  80. }
  81. return bInit;
  82. }
  83. ////////////////////////////////////////////////////////////////////////////
  84. // CLoguiApp::ExitInstance - DLL termination
  85. int CLoguiApp::ExitInstance()
  86. {
  87. return COleControlModule::ExitInstance();
  88. }
  89. /////////////////////////////////////////////////////////////////////////////
  90. // DllRegisterServer - Adds entries to the system registry
  91. STDAPI DllRegisterServer(void)
  92. {
  93. AFX_MANAGE_STATE(_afxModuleAddrThis);
  94. if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
  95. return ResultFromScode(SELFREG_E_CLASS);
  96. // intialize the metabase /logging tree
  97. if ( !RegisterInMetabase( NULL ) )
  98. return GetLastError();
  99. return NOERROR;
  100. }
  101. /////////////////////////////////////////////////////////////////////////////
  102. // DllUnregisterServer - Removes entries from the system registry
  103. STDAPI DllUnregisterServer(void)
  104. {
  105. AFX_MANAGE_STATE(_afxModuleAddrThis);
  106. // if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
  107. // return ResultFromScode(SELFREG_E_TYPELIB);
  108. if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
  109. return ResultFromScode(SELFREG_E_CLASS);
  110. return NOERROR;
  111. }
  112. //-------------------------------------------------------------------------
  113. // add all the base logging info to the /LM portion of the tree Also, add in
  114. // the ftp and w3 service logging load strings
  115. BOOL _cdecl RegisterInMetabase( PWCHAR pszMachine )
  116. {
  117. CString sz;
  118. BOOL f;
  119. DWORD dw;
  120. BOOL fODBCW3 = FALSE;
  121. BOOL fODBCFTP = FALSE;
  122. DWORD fAnswer = FALSE;
  123. CString szAvail;
  124. CWrapMetaBase mbWrap;
  125. // specify the resources to use
  126. HINSTANCE hOldRes = AfxGetResourceHandle();
  127. AfxSetResourceHandle( g_hInstance );
  128. // prep the metabase - during install we always target the local machine
  129. IMSAdminBase* pMB = FInitMetabaseWrapper( pszMachine );
  130. if ( !pMB )
  131. {
  132. goto CLEANUP_RES;
  133. }
  134. if ( !mbWrap.FInit(pMB) )
  135. {
  136. goto CLEANUP_RES;
  137. }
  138. // first, we will add the basic tree to the metabase
  139. // start with the bottom item
  140. // open the target
  141. if ( !mbWrap.Open( _T("/lm"), METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ) )
  142. {
  143. goto CLEANUP_RES;
  144. }
  145. // test to see if we can do odbc logging
  146. if ( mbWrap.GetDword( _T("/w3svc/Info"), MD_SERVER_CAPABILITIES, IIS_MD_UT_SERVER, &dw ) )
  147. fODBCW3 = (dw & IIS_CAP1_ODBC_LOGGING) > 0;
  148. if ( mbWrap.GetDword( _T("/MSFTPSVC/Info"), MD_SERVER_CAPABILITIES, IIS_MD_UT_SERVER, &dw ) )
  149. fODBCFTP = (dw & IIS_CAP1_ODBC_LOGGING) > 0;
  150. // we shouldn't tie up the /lm object, so close it and open logging
  151. mbWrap.Close();
  152. // open the logging object
  153. if ( !mbWrap.Open( _T("/lm/logging"), METADATA_PERMISSION_WRITE ) )
  154. {
  155. // the logging node doesn't exist. Create it
  156. if ( !mbWrap.Open( _T("/lm"), METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ) )
  157. goto CLEANUP_RES;
  158. // add the logging object
  159. if ( mbWrap.AddObject(_T("logging")) )
  160. {
  161. // add the ACL to the node
  162. SetInfoAdminACL( &mbWrap, _T("logging") );
  163. }
  164. // we shouldn't tie up the /lm object, so close it and open logging
  165. mbWrap.Close();
  166. // open the logging object
  167. if ( !mbWrap.Open( _T("/lm/logging"), METADATA_PERMISSION_WRITE ) )
  168. goto CLEANUP_RES;
  169. }
  170. // set the logging key type
  171. mbWrap.SetString( _T(""), MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_MAIN_TYPE, 0 );
  172. // add ncsa first
  173. sz.LoadString( IDS_MTITLE_NCSA );
  174. if ( mbWrap.AddObject( sz ) )
  175. {
  176. // set the key type
  177. mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
  178. // add the logging module's guid string
  179. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, NCSALOG_CLSID );
  180. // add the logging ui's guid string
  181. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, NCSALOGUI_CLSID );
  182. }
  183. // add odbc logging
  184. sz.LoadString( IDS_MTITLE_ODBC );
  185. if ( (fODBCW3 || fODBCFTP) && mbWrap.AddObject( sz ) )
  186. {
  187. // set the key type
  188. mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
  189. // add the logging module's guid string
  190. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, ODBCLOG_CLSID );
  191. // add the logging ui's guid string
  192. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, ODBCLOGUI_CLSID );
  193. }
  194. // add microsoft logging
  195. sz.LoadString( IDS_MTITLE_MSFT );
  196. if ( mbWrap.AddObject( sz ) )
  197. {
  198. // set the key type
  199. mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
  200. // add the logging module's guid string
  201. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, ASCLOG_CLSID );
  202. // add the logging ui's guid string
  203. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, ASCLOGUI_CLSID );
  204. }
  205. // add extended logging
  206. sz.LoadString( IDS_MTITLE_XTND );
  207. if ( mbWrap.AddObject( sz ) )
  208. {
  209. // set the key type
  210. mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
  211. // add the logging module's guid string
  212. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, EXTLOG_CLSID );
  213. // add the logging ui's guid string
  214. f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, EXTLOGUI_CLSID );
  215. }
  216. // close the wrapper
  217. mbWrap.Close();
  218. // prepare the available logging extensions string
  219. // start with w3svc
  220. sz.LoadString( IDS_MTITLE_NCSA );
  221. szAvail = sz;
  222. sz.LoadString( IDS_MTITLE_MSFT );
  223. szAvail += _T(',') + sz;
  224. sz.LoadString( IDS_MTITLE_XTND );
  225. szAvail += _T(',') + sz;
  226. if ( fODBCW3 )
  227. {
  228. sz.LoadString( IDS_MTITLE_ODBC );
  229. szAvail += _T(',') + sz;
  230. }
  231. // save the string
  232. if ( mbWrap.Open( _T("/lm/w3svc/Info"), METADATA_PERMISSION_WRITE ) )
  233. {
  234. f = mbWrap.SetString( _T(""), MD_LOG_PLUGINS_AVAILABLE, IIS_MD_UT_SERVER, szAvail );
  235. // close the wrapper
  236. mbWrap.Close();
  237. }
  238. // now ftp - no ncsa
  239. sz.LoadString( IDS_MTITLE_MSFT );
  240. szAvail = sz;
  241. sz.LoadString( IDS_MTITLE_XTND );
  242. szAvail += _T(',') + sz;
  243. if ( fODBCFTP )
  244. {
  245. sz.LoadString( IDS_MTITLE_ODBC );
  246. szAvail += _T(',') + sz;
  247. }
  248. // save the string
  249. if ( mbWrap.Open( _T("/lm/msftpsvc/Info"), METADATA_PERMISSION_WRITE ) )
  250. {
  251. f = mbWrap.SetString( _T(""), MD_LOG_PLUGINS_AVAILABLE, IIS_MD_UT_SERVER, szAvail );
  252. // close the wrapper
  253. mbWrap.Close();
  254. }
  255. // close the metabase wrappings
  256. FCloseMetabaseWrapper(pMB);
  257. fAnswer = TRUE;
  258. CLEANUP_RES:
  259. // we want to be able to recover a meaningful error, so get it and set it again after
  260. // restoring the resource handle
  261. DWORD err = GetLastError();
  262. // restore the resources
  263. if ( hOldRes )
  264. AfxSetResourceHandle( hOldRes );
  265. // reset the error code
  266. SetLastError( err );
  267. // return the error - hopefully success
  268. return fAnswer;
  269. }
  270. //-------------------------------------------------------------------------
  271. int SetInfoAdminACL( CWrapMetaBase* pMB, LPCTSTR szSubKeyPath )
  272. {
  273. int retCode=-1;
  274. BOOL b = FALSE;
  275. DWORD dwLength = 0;
  276. PSECURITY_DESCRIPTOR pSD = NULL;
  277. PSECURITY_DESCRIPTOR outpSD = NULL;
  278. DWORD cboutpSD = 0;
  279. PACL pACLNew = NULL;
  280. DWORD cbACL = 0;
  281. PSID pAdminsSID = NULL, pEveryoneSID = NULL;
  282. BOOL bWellKnownSID = FALSE;
  283. // Initialize a new security descriptor
  284. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  285. if (NULL == pSD)
  286. goto Cleanup;
  287. InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
  288. // Get Local Admins Sid
  289. GetPrincipalSID (_T("Administrators"), &pAdminsSID, &bWellKnownSID);
  290. // Get everyone Sid
  291. GetPrincipalSID (_T("Everyone"), &pEveryoneSID, &bWellKnownSID);
  292. // Initialize a new ACL, which only contains 2 aaace
  293. cbACL = sizeof(ACL) +
  294. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pAdminsSID) - sizeof(DWORD)) +
  295. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pEveryoneSID) - sizeof(DWORD)) ;
  296. pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
  297. if (NULL == pACLNew)
  298. goto Cleanup;
  299. InitializeAcl(pACLNew, cbACL, ACL_REVISION);
  300. AddAccessAllowedAce(
  301. pACLNew,
  302. ACL_REVISION,
  303. (MD_ACR_READ |
  304. MD_ACR_WRITE |
  305. MD_ACR_RESTRICTED_WRITE |
  306. MD_ACR_UNSECURE_PROPS_READ |
  307. MD_ACR_ENUM_KEYS |
  308. MD_ACR_WRITE_DAC),
  309. pAdminsSID);
  310. AddAccessAllowedAce(
  311. pACLNew,
  312. ACL_REVISION,
  313. (MD_ACR_READ | MD_ACR_ENUM_KEYS),
  314. pEveryoneSID);
  315. // Add the ACL to the security descriptor
  316. b = SetSecurityDescriptorDacl(pSD, TRUE, pACLNew, FALSE);
  317. b = SetSecurityDescriptorOwner(pSD, pAdminsSID, TRUE);
  318. b = SetSecurityDescriptorGroup(pSD, pAdminsSID, TRUE);
  319. // Security descriptor blob must be self relative
  320. if (!MakeSelfRelativeSD(pSD, outpSD, &cboutpSD))
  321. goto Cleanup;
  322. outpSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GPTR, cboutpSD);
  323. if (NULL == outpSD)
  324. goto Cleanup;
  325. if (!MakeSelfRelativeSD( pSD, outpSD, &cboutpSD ))
  326. goto Cleanup;
  327. // below this modify pSD to outpSD
  328. // Apply the new security descriptor to the file
  329. dwLength = GetSecurityDescriptorLength(outpSD);
  330. // set the acl into the metabase at the given location
  331. b = pMB->SetData( szSubKeyPath, MD_ADMIN_ACL, IIS_MD_UT_SERVER, BINARY_METADATA,
  332. (LPBYTE)outpSD, dwLength,
  333. METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE );
  334. retCode = 0;
  335. Cleanup:
  336. // both of Administrators and Everyone are well-known SIDs, use FreeSid() to free them.
  337. if (outpSD)
  338. GlobalFree(outpSD);
  339. if (pAdminsSID)
  340. FreeSid(pAdminsSID);
  341. if (pEveryoneSID)
  342. FreeSid(pEveryoneSID);
  343. if (pSD)
  344. LocalFree((HLOCAL) pSD);
  345. if (pACLNew)
  346. LocalFree((HLOCAL) pACLNew);
  347. return (retCode);
  348. }