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.

475 lines
19 KiB

  1. // certmap.cpp : Implementation of CCertmapApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "certmap.h"
  4. #include "iishelp.h"
  5. #include <iiscnfgp.h>
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. CCertmapApp /*NEAR*/ theApp; // tompop: does this have to be near? We are now getting errors when we finish refering to this var's addr
  12. const GUID CDECL BASED_CODE _tlid =
  13. { 0xbbd8f298, 0x6f61, 0x11d0, { 0xa2, 0x6e, 0x8, 0, 0x2b, 0x2c, 0x6f, 0x32 } };
  14. const WORD _wVerMajor = 1;
  15. const WORD _wVerMinor = 0;
  16. //--------------------------------------------------------------------------
  17. void CCertmapApp::WinHelp(DWORD dwData, UINT nCmd )
  18. {
  19. WinHelpDebug(dwData);
  20. COleControlModule::WinHelp(dwData,nCmd);
  21. }
  22. ////////////////////////////////////////////////////////////////////////////
  23. // CCertmapApp::InitInstance - DLL initialization
  24. BOOL CCertmapApp::InitInstance()
  25. {
  26. BOOL bInit = COleControlModule::InitInstance();
  27. // init ole stuff
  28. HRESULT hRes = CoInitialize(NULL);
  29. // finally, we need to redirect the winhelp file location to something more desirable
  30. CString sz;
  31. CString szHelpLocation;
  32. sz.LoadString( IDS_HELPLOC_PWSHELP );
  33. // expand the path
  34. ExpandEnvironmentStrings(
  35. sz, // pointer to string with environment variables
  36. szHelpLocation.GetBuffer(MAX_PATH + 1), // pointer to string with expanded environment variables
  37. MAX_PATH // maximum characters in expanded string
  38. );
  39. szHelpLocation.ReleaseBuffer();
  40. // free the existing path, and copy in the new one
  41. if ( m_pszHelpFilePath )
  42. free((void*)m_pszHelpFilePath);
  43. m_pszHelpFilePath = _tcsdup(szHelpLocation);
  44. // get debug flag
  45. GetOutputDebugFlag();
  46. return bInit;
  47. }
  48. ////////////////////////////////////////////////////////////////////////////
  49. // CCertmapApp::ExitInstance - DLL termination
  50. // tjp: note that in 'CCertmapApp::InitInstance()' we add our help file to the
  51. // help path. do we need to remove it on clean up here?
  52. int CCertmapApp::ExitInstance()
  53. {
  54. CoUninitialize();
  55. return COleControlModule::ExitInstance();
  56. }
  57. /////////////////////////////////////////////////////////////////////////////
  58. // MigrateGUIDS - does all the GUID migration work. We pass back the
  59. // return value of True iff we find GUIDs in the registry and migrate
  60. // them to the metabase.
  61. //
  62. // We are called by top level fnct: InstallCertServerGUIDs that creates
  63. // our 'info' structure and handles all the metabase init work.
  64. /////////////////////////////////////////////////////////////////////////////
  65. // This code is written in response to bug # 167410.
  66. //
  67. // This fix will handle all the GUID migration work, moving GUIDS that
  68. // CertServer placed in the registry into the metabase for Beta2.
  69. // A more general install/deinstall mechanism for products that
  70. // work with IIS will be come post-Beta2.
  71. //
  72. // DETAILS:
  73. // --------
  74. //
  75. // We look for evidence of CertServer by examing the Registry because
  76. // CertServer will write some entries under:
  77. // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\KeyRing\Parameters\Certificate
  78. // Authorities\Microsoft Certificate Server
  79. //
  80. // CertServer currently outputs:
  81. // CertGetConfig "{C6CC49B0-CE17-11D0-8833-00A0C903B83C}"
  82. // CertRequest "{98AFF3F0-5524-11D0-8812-00A0C903B83C}"
  83. //
  84. // If we see the manditory 'CertRequest' entry, we will load as many strings
  85. // as we find, while defaulting the ones that are missing. See below
  86. // for the equivalent mdutil commands for what defaults are used
  87. //
  88. // => if we dont find 'CertRequest' we give up [meaning remove
  89. // any present MB GUID string entries]
  90. //
  91. // When we find that CertServer is installed, we dont fully believe that
  92. // certserver is still there. To prove that its there we will do a
  93. // CoCreateInstance on CertConfig. If that works we install metabase
  94. // entries that are the equivalent of the following mdutil commands:
  95. //
  96. // ## ICERTGETCONFIG default setting:
  97. // mdutil SET "w3svc/CertServers/Microsoft Certificate Server" -dtype:STRING -
  98. // -utype:UT_SERVER -prop 5571 -value "{C6CC49B0-CE17-11D0-8833-00A0C903B83C}"
  99. //
  100. // ## ICERTREQUEST default setting:
  101. // mdutil SET "w3svc/CertServers/Microsoft Certificate Server" -dtype:STRING
  102. // -utype:UT_SERVER -prop 5572 -value "{98AFF3F0-5524-11D0-8812-00A0C903B83C}"
  103. //
  104. // ## ICERTCONFIG default setting:
  105. // mdutil SET "w3svc/CertServers/Microsoft Certificate Server" -dtype:STRING
  106. // -utype:UT_SERVER -prop 5574 -value "{372fce38-4324-11d0-8810-00a0c903b83c}"
  107. //
  108. // If the CoCreateInstance fails, we give up and remove MB GUID entries.
  109. //
  110. // ---------------------------------------------------------------
  111. // NOTE that we will either install or DE-install the metabase
  112. // GUID strings based on its decision that CertServer is present.
  113. // If we find GUID strings in the metabase but can not do a
  114. // CoCreateInstance on CertConfig:
  115. // we remove them so that the rest of CertWizard will see CertServer
  116. // Guids iff we can use CertServer.
  117. // ---------------------------------------------------------------
  118. // NOTE also that if we make a decision to install GUID strings
  119. // into the metabase, we honor/preserve any present GUID strings that
  120. // are present in the metabase.
  121. // ---------------------------------------------------------------
  122. //
  123. /////////////////////////////////////////////////////////////////////////////
  124. /*ddddddddddddddd
  125. BOOL MigrateGUIDS( ADMIN_INFO& info )
  126. {
  127. BOOL bRet = FALSE; // value to return, set to F
  128. // for defensive reasons.
  129. BOOL bFoundCertSrvRegistryEntries = FALSE; // assume false for now
  130. TCHAR* szRegPath = _T("SOFTWARE\\Microsoft\\KeyRing\\Parameters\\Certificate Authorities\\Microsoft Certificate Server");
  131. //-----------------------------------------------------------------------
  132. // In each of the following 3 sets of parameters, we have (1) a string
  133. // like "CertRequest" that CertServer uses in the registry, (2) a default
  134. // value to use like "{98AFF3F0-5524-11D0-8812-00A0C903B83C}" that we
  135. // use if we can not find anything in the registry, and (3) a CString
  136. // to hold the GUID. The value in the CString will be stored in the MB.
  137. //-----------------------------------------------------------------------
  138. // CertRequest - variables
  139. TCHAR* szCertRequest = _T("CertRequest");
  140. TCHAR* szCertRequestGUIDdefault = _T( "{98AFF3F0-5524-11D0-8812-00A0C903B83C}" );
  141. CString szCertRequestGUID;
  142. // CertConfig - variables
  143. TCHAR* szCertConfig = _T("CertConfig");
  144. TCHAR* szCertConfigGUIDdefault = _T( "{372fce38-4324-11d0-8810-00a0c903b83c}" );
  145. CString szCertConfigGUID;
  146. // CertGetConfig - variables
  147. TCHAR* szCertGetConfig = _T("CertGetConfig");
  148. TCHAR* szCertGetConfigGUIDdefault = _T( "{C6CC49B0-CE17-11D0-8833-00A0C903B83C}");
  149. CString szCertGetConfigGUID;
  150. CString szCertServerMetabaseRoot( SZ_ROOT_CERT_SERV_MB_PATH );
  151. // SZ_ROOT_CERT_SERV_MB_PATH = "/LM/W3SVC/CertServers"
  152. szCertServerMetabaseRoot += _T("/Microsoft Certificate Server");
  153. #ifdef DEBUGGING
  154. CEditDialog dlg(szCertServerMetabaseRoot,
  155. _T("use this to test adding new CertServer entries."
  156. " In order for us to install a new key you have to change the path"
  157. " below to something [strange] and not already in the metabase."));
  158. dlg.DoModal();
  159. #endif
  160. // the following string will be restored into info.szMetaBasePath before
  161. // we exit this fnct. We switch out the [info.szMetaBasePath] so that
  162. // we can use our native Set/Get metabase string fncts.
  163. // We switch it to: "/LM/W3SVC/CertServers/Microsoft Certificate Server"
  164. //
  165. CString szSaved_info_szMetaBasePath( info.szMetaBasePath );
  166. info.szMetaBasePath = szCertServerMetabaseRoot;
  167. // if we dont find HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\KeyRing\Parameters\
  168. // Certificate Authorities\Microsoft Certificate Server"
  169. // with key: CertRequest quit! CertServer should have installed this.
  170. // We are forgiving about the other 2 Registry GUID strings
  171. //-------------------------------------------------------------------------
  172. if ( Reg::GetNameValueIn( szRegPath, szCertRequest,
  173. szCertRequestGUID, HKEY_LOCAL_MACHINE )) {
  174. bFoundCertSrvRegistryEntries = TRUE;
  175. }
  176. if (! Reg::GetNameValueIn( szRegPath, szCertConfig,
  177. szCertConfigGUID, HKEY_LOCAL_MACHINE )) {
  178. szCertConfigGUID = szCertConfigGUIDdefault; // assign default
  179. }
  180. if (! Reg::GetNameValueIn( szRegPath, szCertGetConfig,
  181. szCertGetConfigGUID, HKEY_LOCAL_MACHINE )) {
  182. szCertGetConfigGUID = szCertGetConfigGUIDdefault; // assign default
  183. }
  184. //------------------------------------------------------------------------
  185. // First lets try to create the directory path: the user might have
  186. // deleted it or this might be a virgin machine.
  187. //------------------------------------------------------------------------
  188. {
  189. CWrapMetaBase& MB = info.meta.m_mbWrap; // this is the MetaBase Wrapper
  190. // its already been openned by
  191. // openMetaDataForWrite
  192. if ( FALSE == openMetaDataForWrite(info, FALSE) ) {
  193. if (ERROR_PATH_NOT_FOUND == HRESULT_CODE( MB.getHRESULT() )) {
  194. // lets create the path in the metabase, using AddObject.
  195. // recursively creates a "pathway in the metabase". E.g. assume that you
  196. // want to make sure that "/LM/W3SVC/CertServers/Microsoft Certificate Server"
  197. // is in the metabase. you can open /LM/W3SVC and do a AddKey() on
  198. // "CertServers/Microsoft Certificate Server" to create that stub.
  199. // above we set: info.szMetaBasePath = szCertServerMetabaseRoot
  200. // here we will temporarily pretend that our root is at level
  201. // /LM/W3SVC which we assume is at the top of szCertServerMetabaseRoot
  202. // and then call AddKey
  203. TCHAR szPath[400];
  204. TCHAR* szRootPrefix = _T("/LM/W3SVC");
  205. UINT nRootPrefixLen = STRLEN(szRootPrefix);
  206. STRCPY(szPath, szCertServerMetabaseRoot);
  207. if (STRNICMP(szRootPrefix, szPath, nRootPrefixLen) != 0)
  208. goto returnFALSE; // we could not figure out a common Root
  209. info.szMetaBasePath = szRootPrefix;
  210. if ( FALSE == openMetaDataForWrite(info) )
  211. goto returnFALSE; // we could not open the metabase
  212. // the metabase path is already position to the proper directory
  213. // in the MB object. MB will prepend that path to the subDirectory
  214. // that we want to create, the following will jump past the trailing
  215. // '/' separating the root and the rest of the sub-directory
  216. // e.g. "/CertServers/Microsoft Certificate Server"
  217. //
  218. // We dont do any other error checking besides notifying and
  219. // returning FALSE.
  220. if (FALSE == MB.AddObject( &szPath[nRootPrefixLen] )) {
  221. NotifyUsers_CouldNotAccessMetaBase( MB.getHRESULT() );
  222. goto returnFALSE; // we could not create required path
  223. }
  224. // since we are continuing, we reset back our proper path.
  225. info.szMetaBasePath = szCertServerMetabaseRoot;
  226. } else {
  227. goto returnFALSE; // we could not open the metabase
  228. }
  229. }
  230. }
  231. //------------------------------------------------------------------------
  232. // Below we dont deal with the XENROLL GUID setting that is for future usage
  233. // PLUS its not CertServer Related, its Xenroll related. We dont touch it.
  234. //------------------------------------------------------------------------
  235. {
  236. // lets see if we can do a CoCreateInstance on CertRequest. If we can not
  237. // we believe that certServer is not installed and set/clear MB entries
  238. // The following values are set or cleared:
  239. //
  240. // # define MD_SSL_CERT_WIZGUID_ICERTGETCONFIG ( IIS_MD_SSL_BASE+71 )
  241. // # define MD_SSL_CERT_WIZGUID_ICERTREQUEST ( IIS_MD_SSL_BASE+72 )
  242. // # define MD_SSL_CERT_WIZGUID_XENROLL ( IIS_MD_SSL_BASE+73 ) FUTURE USAGE
  243. // # define MD_SSL_CERT_WIZGUID_ICERTCONFIG ( IIS_MD_SSL_BASE+74 )
  244. //------------------------------------------------------------------------
  245. IPtr<ICertConfig, &IID_ICertConfig> iptr;
  246. CString szRemoteDCOMTargetMachine;
  247. // REMEMBER bRet returns whether we were able to delete everything
  248. // or set everything that we were wanting to set
  249. // in both cases assume now that we have success and update bRet when
  250. // we find errors, we continue as long as possible. E.g. we add or delete
  251. // as many entries as possible and return our status value to the caller.
  252. bRet = TRUE;
  253. if ( (FALSE == bFoundCertSrvRegistryEntries) ||
  254. (FALSE == GetICertConfigIPtrFromGuid( iptr, szCertConfigGUID,
  255. &szRemoteDCOMTargetMachine)) )
  256. {
  257. // remove MB entries!
  258. #ifdef DEBUGGING
  259. DODBG MsgBox( _T("adding CertServer MB entries"));
  260. #endif
  261. if ( FALSE == openMetaDataForWrite(info) ) {
  262. goto returnFALSE; // we could not open the metabase
  263. }
  264. // We just need to blow away the cert info in the metabase
  265. // which we do using the meta data wrapper
  266. // deleting values
  267. CWrapMetaBase& MB = info.meta.m_mbWrap; // this is the MetaBase Wrapper
  268. // its already been openned by
  269. // openMetaDataForWrite
  270. // try deletes once
  271. // In C++ &&= does not exist. However [bRet &= FALSE;] is OK, but we dont
  272. // have a uniform single value of TRUE in C/C++ so its not safe to use &=
  273. // to chain a set of TRUE-value
  274. // so we can not do:
  275. // bRet &&= MB.DeleteData( _T(""),
  276. // MD_SSL_CERT_WIZGUID_ICERTGETCONFIG, STRING_METADATA);
  277. // so we will use a [if (! xxx) bRet=FALSE;] construct below
  278. if (! MB.DeleteData( _T(""),
  279. MD_SSL_CERT_WIZGUID_ICERTGETCONFIG, STRING_METADATA)) bRet=FALSE;
  280. if (! MB.DeleteData( _T(""),
  281. MD_SSL_CERT_WIZGUID_ICERTREQUEST, STRING_METADATA)) bRet=FALSE;
  282. if (! MB.DeleteData( _T(""),
  283. MD_SSL_CERT_WIZGUID_ICERTCONFIG, STRING_METADATA)) bRet=FALSE;
  284. MB.Close();
  285. } else {
  286. CString szPresentValue; // used to read the present value
  287. // any metabase value so that we
  288. // can preserve it.
  289. #ifdef DEBUGGING
  290. DODBG MsgBox( _T("adding CertServer MB entries"));
  291. #endif
  292. // add MB entries! If an entry already exists, leave it alone.
  293. if (! GetMetaBaseString ( info,
  294. IN MD_SSL_CERT_WIZGUID_ICERTREQUEST,
  295. IN szPresentValue ) )
  296. {
  297. if (!SetMetaBaseString ( info,
  298. IN MD_SSL_CERT_WIZGUID_ICERTREQUEST,
  299. IN szCertRequestGUID ) ) bRet=FALSE;
  300. }
  301. if (! GetMetaBaseString ( info,
  302. IN MD_SSL_CERT_WIZGUID_ICERTCONFIG,
  303. IN szPresentValue ) )
  304. {
  305. if (!SetMetaBaseString ( info,
  306. IN MD_SSL_CERT_WIZGUID_ICERTCONFIG,
  307. IN szCertConfigGUID ) ) bRet=FALSE;
  308. }
  309. if (! GetMetaBaseString ( info,
  310. IN MD_SSL_CERT_WIZGUID_ICERTGETCONFIG,
  311. IN szPresentValue ) )
  312. {
  313. if (!SetMetaBaseString ( info,
  314. IN MD_SSL_CERT_WIZGUID_ICERTGETCONFIG,
  315. IN szCertGetConfigGUID ) ) bRet=FALSE;
  316. }
  317. }
  318. }
  319. commonReturn: // this is the common return so that we an set
  320. // back the metabase path. We saved it so that
  321. // we can switch to where the GUIDs live:
  322. // the following will restore the original [info.szMetaBasePath] value
  323. // before we switched it to: "/LM/W3SVC/CertServers/..."
  324. //
  325. info.szMetaBasePath = szSaved_info_szMetaBasePath;
  326. return(bRet);
  327. returnFALSE: // this will cause a FALSE return and do all things
  328. // required in our "common return"
  329. bRet = FALSE;
  330. goto commonReturn;
  331. }
  332. */
  333. /////////////////////////////////////////////////////////////////////////////
  334. // DllRegisterServer - Adds entries to the system registry
  335. STDAPI DllRegisterServer(void)
  336. {
  337. AFX_MANAGE_STATE(_afxModuleAddrThis);
  338. if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
  339. return ResultFromScode(SELFREG_E_TYPELIB);
  340. if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
  341. return ResultFromScode(SELFREG_E_CLASS);
  342. return NOERROR;
  343. }
  344. /////////////////////////////////////////////////////////////////////////////
  345. // DllUnregisterServer - Removes entries from the system registry
  346. STDAPI DllUnregisterServer(void)
  347. {
  348. AFX_MANAGE_STATE(_afxModuleAddrThis);
  349. if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
  350. return ResultFromScode(SELFREG_E_TYPELIB);
  351. if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
  352. return ResultFromScode(SELFREG_E_CLASS);
  353. return NOERROR;
  354. }
  355. BOOL IsLegacyMetabase(IMSAdminBase* pMB)
  356. {
  357. BOOL bReturn = FALSE;
  358. CWrapMetaBase mbBase;
  359. CString szObjectPath = _T("LM/W3SVC/Info");
  360. DWORD dwMajorVersion = 0;
  361. BOOL f = mbBase.FInit(pMB);
  362. if ( !f ) return FALSE;
  363. // open the base object
  364. f = mbBase.Open( szObjectPath, METADATA_PERMISSION_READ);
  365. if ( !f )
  366. {
  367. return FALSE;
  368. }
  369. DWORD dwFlags = METADATA_NO_ATTRIBUTES;
  370. if (mbBase.GetDword( _T(""), MD_SERVER_VERSION_MAJOR, IIS_MD_UT_SERVER, &dwMajorVersion) )
  371. {
  372. if (dwMajorVersion < 6)
  373. {
  374. bReturn = TRUE;
  375. }
  376. }
  377. mbBase.Close();
  378. return bReturn;
  379. }