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.

1690 lines
35 KiB

  1. /*++
  2. Copyright (c) 1994-1999 Microsoft Corporation
  3. Module Name :
  4. w3sht.cpp
  5. Abstract:
  6. WWW Property Sheet
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "common.h"
  18. #include "inetprop.h"
  19. #include "InetMgrApp.h"
  20. #include "shts.h"
  21. #include "w3sht.h"
  22. #include "iisfilt.h"
  23. #include "fltdlg.h"
  24. #include "iisobj.h"
  25. // from pshed.cpp
  26. HRESULT CallINetCfg(BOOL Install);
  27. //
  28. // Help IDs
  29. //
  30. #define HIDD_DIRECTORY_PROPERTIES (IDD_WEB_DIRECTORY_PROPERTIES + 0x20000)
  31. #define HIDD_HOME_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20000)
  32. #define HIDD_FS_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20001)
  33. #define HIDD_FS_FILE_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20002)
  34. //
  35. // Metabase node ID
  36. //
  37. const LPCTSTR g_cszSvc = _T("W3SVC");
  38. const LPCTSTR g_cszFilters = _T("Filters");
  39. const LPCTSTR g_cszSSLKeys = _T("SSLKeys");
  40. //
  41. // Helper Functions
  42. //
  43. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  44. BOOL
  45. IsCertInstalledOnServer(
  46. IN CComAuthInfo * pAuthInfo,
  47. IN LPCTSTR lpszMDPath
  48. )
  49. /*++
  50. Routine Description:
  51. Check to see if a certificate is installed on this virtual server.
  52. This routine only checks that the cert metabase key was read in.
  53. by boydm
  54. Arguments:
  55. None
  56. Return Value:
  57. TRUE if a certificate are installed, FALSE otherwise
  58. --*/
  59. {
  60. CError err;
  61. BOOL fCertInstalled = FALSE;
  62. CW3InstanceProps * ppropInst;
  63. CString strNewPath;
  64. //
  65. // Get the instance properties
  66. //
  67. CMetabasePath::GetInstancePath(lpszMDPath,strNewPath);
  68. ppropInst = new CW3InstanceProps(pAuthInfo, strNewPath);
  69. //
  70. // If it succeeded, load the data, then check the answer
  71. //
  72. if (ppropInst)
  73. {
  74. err = ppropInst->LoadData();
  75. if (err.Succeeded())
  76. {
  77. fCertInstalled = !(MP_V(ppropInst->m_CertHash).IsEmpty());
  78. }
  79. }
  80. //
  81. // Clean up since we don't really need the ppropInst after this.
  82. //
  83. if (ppropInst)
  84. {
  85. delete ppropInst;
  86. ppropInst = NULL;
  87. }
  88. //
  89. // if that test failed. we want to check the metabase key itself
  90. // since the above check is all cached information and won't reflect
  91. // any certificates which are removed/added via scripts, while mmc is open
  92. //
  93. if (!fCertInstalled)
  94. {
  95. CMetaKey key(pAuthInfo,strNewPath,METADATA_PERMISSION_READ);
  96. if (key.Succeeded())
  97. {
  98. CBlob hash;
  99. if (SUCCEEDED(key.QueryValue(MD_SSL_CERT_HASH, hash)))
  100. {
  101. fCertInstalled = TRUE;
  102. }
  103. }
  104. }
  105. //
  106. // If that test failed, we may be admining a downlevel IIS4 machine.
  107. // Unfortunately we can't tell by examining the capability bits,
  108. // so look to see if the old certs are there.
  109. //
  110. if (!fCertInstalled)
  111. {
  112. CString strKey;
  113. CMetaEnumerator me(pAuthInfo, CMetabasePath(SZ_MBN_WEB));
  114. HRESULT err = me.Next(strKey, g_cszSSLKeys);
  115. fCertInstalled = SUCCEEDED(err);
  116. }
  117. return fCertInstalled;
  118. }
  119. //
  120. // CW3InstanceProps implementation
  121. //
  122. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  123. CW3InstanceProps::CW3InstanceProps(
  124. IN CComAuthInfo * pAuthInfo,
  125. IN LPCTSTR lpszMDPath
  126. )
  127. /*++
  128. Routine Description:
  129. Constructor for WWW instance properties
  130. Arguments:
  131. CComAuthInfo * pAuthInfo : COM Authentication info
  132. LPCTSTR lpszMDPath : MD Path
  133. Return Value:
  134. None.
  135. --*/
  136. : CInstanceProps(pAuthInfo, lpszMDPath, 80U),
  137. /**/
  138. m_nMaxConnections(INITIAL_MAX_CONNECTIONS),
  139. m_nConnectionTimeOut((LONG)900L),
  140. m_strlSecureBindings(),
  141. m_dwLogType(MD_LOG_TYPE_DISABLED),
  142. /**/
  143. m_fUseKeepAlives(TRUE),
  144. m_nServerSize(MD_SERVER_SIZE_MEDIUM),
  145. m_dwMaxBandwidth(INFINITE_BANDWIDTH),
  146. /**/
  147. m_acl(),
  148. /**/
  149. m_dwDownlevelInstance(1),
  150. m_CertHash()
  151. {
  152. //
  153. // Fetch everything
  154. //
  155. m_dwMDUserType = ALL_METADATA;
  156. m_dwMDDataType = ALL_METADATA;
  157. }
  158. CW3InstanceProps::~CW3InstanceProps()
  159. {
  160. }
  161. /* virtual */
  162. void
  163. CW3InstanceProps::ParseFields()
  164. /*++
  165. Routine Description:
  166. Break into fields.
  167. Arguments:
  168. None.
  169. Return Value:
  170. None.
  171. --*/
  172. {
  173. //
  174. // Fetch base properties
  175. //
  176. CInstanceProps::ParseFields();
  177. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  178. HANDLE_META_RECORD(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  179. HANDLE_META_RECORD(MD_SECURE_BINDINGS, m_strlSecureBindings)
  180. HANDLE_META_RECORD(MD_LOG_TYPE, m_dwLogType)
  181. HANDLE_META_RECORD(MD_SERVER_SIZE, m_nServerSize)
  182. HANDLE_META_RECORD(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives)
  183. HANDLE_META_RECORD(MD_MAX_BANDWIDTH, m_dwMaxBandwidth)
  184. HANDLE_META_RECORD(MD_MAX_GLOBAL_BANDWIDTH,m_dwMaxGlobalBandwidth)
  185. HANDLE_META_RECORD(MD_MAX_CONNECTIONS, m_nMaxConnections)
  186. HANDLE_META_RECORD(MD_ADMIN_ACL, m_acl)
  187. HANDLE_META_RECORD(MD_DOWNLEVEL_ADMIN_INSTANCE, m_dwDownlevelInstance);
  188. HANDLE_META_RECORD(MD_SSL_CERT_HASH, m_CertHash)
  189. HANDLE_META_RECORD(MD_SSL_CERT_STORE_NAME, m_strCertStoreName)
  190. HANDLE_META_RECORD(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier)
  191. HANDLE_META_RECORD(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName)
  192. END_PARSE_META_RECORDS
  193. if (CMetabasePath::IsMasterInstance(QueryMetaRoot()))
  194. {
  195. m_dwMaxBandwidth = m_dwMaxGlobalBandwidth;
  196. }
  197. }
  198. /* virtual */
  199. HRESULT
  200. CW3InstanceProps::WriteDirtyProps()
  201. /*++
  202. Routine Description:
  203. Write the dirty properties to the metabase
  204. Arguments:
  205. None
  206. Return Value:
  207. HRESULT
  208. --*/
  209. {
  210. CError err(CInstanceProps::WriteDirtyProps());
  211. if (err.Failed())
  212. {
  213. return err;
  214. }
  215. if (m_dwMaxBandwidth != INFINITE_BANDWIDTH)
  216. {
  217. err = CallINetCfg(TRUE);
  218. }
  219. BEGIN_META_WRITE()
  220. META_WRITE(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  221. META_WRITE(MD_SECURE_BINDINGS, m_strlSecureBindings)
  222. META_WRITE(MD_LOG_TYPE, m_dwLogType)
  223. META_WRITE(MD_SERVER_SIZE, m_nServerSize)
  224. META_WRITE(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives)
  225. if (CMetabasePath::IsMasterInstance(QueryMetaRoot()))
  226. {
  227. META_WRITE(MD_MAX_GLOBAL_BANDWIDTH, m_dwMaxBandwidth)
  228. }
  229. else
  230. {
  231. META_WRITE(MD_MAX_BANDWIDTH, m_dwMaxBandwidth)
  232. }
  233. META_WRITE(MD_MAX_CONNECTIONS, m_nMaxConnections)
  234. META_WRITE(MD_ADMIN_ACL, m_acl)
  235. META_WRITE(MD_DOWNLEVEL_ADMIN_INSTANCE, m_dwDownlevelInstance);
  236. META_WRITE(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier)
  237. META_WRITE(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName)
  238. END_META_WRITE(err);
  239. return err;
  240. }
  241. //
  242. // CW3DirProps Implementation
  243. //
  244. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  245. CW3DirProps::CW3DirProps(
  246. IN CComAuthInfo * pAuthInfo,
  247. IN LPCTSTR lpszMDPath
  248. )
  249. /*++
  250. Routine Description:
  251. WWW Directory Properties Constructor
  252. Arguments:
  253. CComAuthInfo * pAuthInfo : COM Authentication info
  254. LPCTSTR lpszMDPath : MD Path
  255. Return Value:
  256. N/A
  257. --*/
  258. : CChildNodeProps(
  259. pAuthInfo,
  260. lpszMDPath,
  261. WITH_INHERITANCE,
  262. FALSE // Complete information
  263. ),
  264. /**/
  265. m_strUserName(),
  266. m_strPassword(),
  267. m_strDefaultDocument(),
  268. m_strFooter(),
  269. m_dwDirBrowsing(0L),
  270. m_fEnableFooter(FALSE),
  271. m_fDontLog(FALSE),
  272. m_fIndexed(FALSE),
  273. /**/
  274. m_strExpiration(),
  275. m_strlCustomHeaders(),
  276. /**/
  277. m_strlCustomErrors(),
  278. /**/
  279. m_strAnonUserName(),
  280. m_strAnonPassword(),
  281. m_fPasswordSync(TRUE),
  282. m_fU2Installed(FALSE),
  283. m_fUseNTMapper(FALSE),
  284. m_dwAuthFlags(MD_AUTH_ANONYMOUS),
  285. m_dwSSLAccessPermissions(0L),
  286. m_strBasicDomain(),
  287. m_strRealm(),
  288. m_ipl()
  289. {
  290. //
  291. // Fetch everything
  292. //
  293. m_dwMDUserType = ALL_METADATA;
  294. m_dwMDDataType = ALL_METADATA;
  295. }
  296. /* virtual */
  297. void
  298. CW3DirProps::ParseFields()
  299. /*++
  300. Routine Description:
  301. Break into fields.
  302. Arguments:
  303. None.
  304. Return Value:
  305. None.
  306. --*/
  307. {
  308. //
  309. // Fetch base properties
  310. //
  311. CChildNodeProps::ParseFields();
  312. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  313. //
  314. // VDir Page
  315. //
  316. HANDLE_META_RECORD(MD_VR_USERNAME, m_strUserName)
  317. HANDLE_META_RECORD(MD_VR_PASSWORD, m_strPassword)
  318. HANDLE_META_RECORD(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument);
  319. HANDLE_META_RECORD(MD_FOOTER_ENABLED, m_fEnableFooter);
  320. HANDLE_META_RECORD(MD_FOOTER_DOCUMENT, m_strFooter);
  321. HANDLE_META_RECORD(MD_DIRECTORY_BROWSING, m_dwDirBrowsing);
  322. HANDLE_META_RECORD(MD_DONT_LOG, m_fDontLog);
  323. HANDLE_META_RECORD(MD_IS_CONTENT_INDEXED, m_fIndexed);
  324. //
  325. // HTTP Page
  326. //
  327. HANDLE_META_RECORD(MD_HTTP_EXPIRES, m_strExpiration);
  328. HANDLE_META_RECORD(MD_HTTP_CUSTOM, m_strlCustomHeaders);
  329. //
  330. // Custom Errors
  331. //
  332. HANDLE_META_RECORD(MD_CUSTOM_ERROR, m_strlCustomErrors);
  333. //
  334. // Security page
  335. //
  336. HANDLE_META_RECORD(MD_AUTHORIZATION, m_dwAuthFlags);
  337. HANDLE_META_RECORD(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions);
  338. HANDLE_META_RECORD(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain);
  339. HANDLE_META_RECORD(MD_REALM, m_strRealm);
  340. HANDLE_META_RECORD(MD_ANONYMOUS_USER_NAME, m_strAnonUserName)
  341. HANDLE_META_RECORD(MD_ANONYMOUS_PWD, m_strAnonPassword)
  342. // if (QueryMajorVersion() < 6)
  343. {
  344. HANDLE_META_RECORD(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  345. }
  346. HANDLE_META_RECORD(MD_U2_AUTH, m_fU2Installed)
  347. HANDLE_META_RECORD(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper);
  348. HANDLE_META_RECORD(MD_IP_SEC, m_ipl);
  349. END_PARSE_META_RECORDS
  350. }
  351. /* virtual */
  352. HRESULT
  353. CW3DirProps::WriteDirtyProps()
  354. /*++
  355. Routine Description:
  356. Write the dirty properties to the metabase
  357. Arguments:
  358. None
  359. Return Value:
  360. HRESULT
  361. --*/
  362. {
  363. CError err(CChildNodeProps::WriteDirtyProps());
  364. if (err.Failed())
  365. {
  366. return err;
  367. }
  368. DWORD dwAuth = m_dwAuthFlags;
  369. DWORD dwBuf = m_dwAuthFlags;
  370. if (IS_FLAG_SET(dwBuf, MD_AUTH_PASSPORT))
  371. {
  372. // Clear Windows authentication flags, if passport set
  373. //
  374. dwBuf &= ~(MD_AUTH_MD5 | MD_AUTH_BASIC | MD_AUTH_NT);
  375. m_dwAuthFlags = dwBuf;
  376. }
  377. //
  378. // CODEWORK: Consider DDX/DDV like methods which do both
  379. // ParseFields and WriteDirtyProps in a single method. Must
  380. // take care not to write data which should only be read, not
  381. // written
  382. //
  383. BEGIN_META_WRITE()
  384. //
  385. // VDir Page
  386. //
  387. META_WRITE(MD_VR_USERNAME, m_strUserName)
  388. // If some bozo wants to have empty password, we should force to write it here
  389. if (!MP_V(m_strUserName).IsEmpty() && MP_V(m_strPassword).IsEmpty())
  390. {
  391. MP_V(m_strPassword) = _T("");
  392. }
  393. MP_D(m_strPassword) = TRUE;
  394. META_WRITE(MD_VR_PASSWORD, m_strPassword)
  395. META_WRITE(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument)
  396. META_WRITE(MD_FOOTER_ENABLED, m_fEnableFooter)
  397. META_WRITE(MD_FOOTER_DOCUMENT, m_strFooter)
  398. META_WRITE(MD_DIRECTORY_BROWSING, m_dwDirBrowsing)
  399. META_WRITE(MD_DONT_LOG, m_fDontLog)
  400. META_WRITE(MD_IS_CONTENT_INDEXED, m_fIndexed)
  401. //
  402. // HTTP Page
  403. //
  404. META_WRITE(MD_HTTP_EXPIRES, m_strExpiration)
  405. META_WRITE(MD_HTTP_CUSTOM, m_strlCustomHeaders)
  406. //
  407. // Custom Errors
  408. //
  409. META_WRITE(MD_CUSTOM_ERROR, m_strlCustomErrors)
  410. //
  411. // Security page
  412. //
  413. META_WRITE(MD_AUTHORIZATION, m_dwAuthFlags)
  414. META_WRITE(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions)
  415. META_WRITE(MD_REALM, m_strRealm)
  416. META_WRITE(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain)
  417. META_WRITE(MD_ANONYMOUS_USER_NAME, m_strAnonUserName)
  418. META_WRITE(MD_ANONYMOUS_PWD, m_strAnonPassword)
  419. // if (QueryMajorVersion() < 6)
  420. {
  421. META_WRITE(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  422. }
  423. META_WRITE(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper)
  424. META_WRITE(MD_IP_SEC, m_ipl)
  425. END_META_WRITE(err);
  426. m_dwAuthFlags = dwAuth;
  427. return err;
  428. }
  429. //
  430. // CIISFilter Implementation
  431. //
  432. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  433. CIISFilter::CIISFilter()
  434. /*++
  435. Routine Description:
  436. Filter contructor for a new filter
  437. Arguments:
  438. None
  439. Return Value:
  440. N/A
  441. --*/
  442. : CObjectPlus(),
  443. m_strName(),
  444. //
  445. // Default Values
  446. //
  447. m_strExecutable(),
  448. m_nPriority(FLTR_PR_INVALID),
  449. m_nOrder(-1),
  450. m_dwState(MD_FILTER_STATE_UNDEFINED),
  451. m_dwFlags(0L),
  452. m_hrResult(S_OK),
  453. m_dwWin32Error(ERROR_SUCCESS),
  454. m_fEnabled(TRUE),
  455. m_fDirty(FALSE),
  456. m_fFlaggedForDeletion(FALSE)
  457. {
  458. }
  459. CIISFilter::CIISFilter(
  460. IN CMetaKey * pKey,
  461. IN LPCTSTR lpszName
  462. )
  463. /*++
  464. Routine Description:
  465. Fully defined constructor
  466. Arguments:
  467. CMetaKey * pKey : Open key to read from
  468. LPCTSTR lpszName : Name of the filter
  469. Return Value:
  470. N/A
  471. --*/
  472. : m_strName(lpszName),
  473. //
  474. // Default Values
  475. //
  476. m_strExecutable(),
  477. m_nPriority(FLTR_PR_INVALID),
  478. m_nOrder(-1),
  479. m_dwState(MD_FILTER_STATE_UNDEFINED),
  480. m_dwFlags(0L),
  481. m_hrResult(S_OK),
  482. m_dwWin32Error(ERROR_SUCCESS),
  483. m_fEnabled(TRUE),
  484. m_fDirty(FALSE),
  485. m_fFlaggedForDeletion(FALSE)
  486. {
  487. ASSERT(pKey != NULL);
  488. m_hrResult = pKey->QueryValue(
  489. MD_FILTER_IMAGE_PATH,
  490. m_strExecutable,
  491. NULL,
  492. m_strName
  493. );
  494. pKey->QueryValue(MD_FILTER_ENABLED, m_fEnabled, NULL, m_strName);
  495. pKey->QueryValue(MD_FILTER_STATE, m_dwState, NULL, m_strName);
  496. pKey->QueryValue(MD_FILTER_FLAGS, m_dwFlags, NULL, m_strName);
  497. if (m_dwFlags & SF_NOTIFY_ORDER_HIGH)
  498. {
  499. m_nPriority = FLTR_PR_HIGH;
  500. }
  501. else if (m_dwFlags & SF_NOTIFY_ORDER_MEDIUM)
  502. {
  503. m_nPriority = FLTR_PR_MEDIUM;
  504. }
  505. else if (m_dwFlags & SF_NOTIFY_ORDER_LOW)
  506. {
  507. m_nPriority = FLTR_PR_LOW;
  508. }
  509. else
  510. {
  511. m_nPriority = FLTR_PR_INVALID;
  512. }
  513. }
  514. CIISFilter::CIISFilter(
  515. IN const CIISFilter & flt
  516. )
  517. /*++
  518. Routine Description:
  519. Copy Constructor
  520. Arguments:
  521. const CIISFilter & flt : Source filter object
  522. Return Value:
  523. N/A
  524. --*/
  525. : m_strName(flt.m_strName),
  526. m_strExecutable(flt.m_strExecutable),
  527. m_nPriority(flt.m_nPriority),
  528. m_nOrder(flt.m_nOrder),
  529. m_hrResult(flt.m_hrResult),
  530. m_dwState(flt.m_dwState),
  531. m_dwFlags(flt.m_dwFlags),
  532. m_dwWin32Error(flt.m_dwWin32Error),
  533. m_fEnabled(flt.m_fEnabled),
  534. m_fDirty(FALSE),
  535. m_fFlaggedForDeletion(FALSE)
  536. {
  537. }
  538. HRESULT
  539. CIISFilter::Write(
  540. IN CMetaKey * pKey
  541. )
  542. /*++
  543. Routine Description:
  544. Write the current value to the metabase
  545. Arguments:
  546. CMetaKey * pKey : Open key
  547. Return Value:
  548. HRESULT
  549. --*/
  550. {
  551. ASSERT(pKey != NULL);
  552. CError err;
  553. CString strKey(_T("IIsFilter"));
  554. err = pKey->SetValue(MD_KEY_TYPE, strKey, NULL, QueryName());
  555. if (err.Succeeded())
  556. {
  557. err = pKey->SetValue(
  558. MD_FILTER_IMAGE_PATH,
  559. m_strExecutable,
  560. NULL,
  561. QueryName()
  562. );
  563. }
  564. return err;
  565. }
  566. int
  567. CIISFilter::OrderByPriority(
  568. IN const CObjectPlus * pobAccess
  569. ) const
  570. /*++
  571. Routine Description:
  572. Compare two filters against each other, and sort on priority first, and
  573. order secondarily.
  574. Arguments:
  575. const CObjectPlus * pobAccess : This really refers to another
  576. CIISFilter to be compared to.
  577. Return Value:
  578. Sort (+1, 0, -1) return value
  579. --*/
  580. {
  581. const CIISFilter * pob = (CIISFilter *)pobAccess;
  582. if (pob->m_nPriority != m_nPriority)
  583. {
  584. return pob->m_nPriority - m_nPriority;
  585. }
  586. //
  587. // Sort by order in reverse order
  588. //
  589. return m_nOrder - pob->m_nOrder;
  590. }
  591. //
  592. // Static initialization
  593. //
  594. const LPCTSTR CIISFilterList::s_lpszSep = _T(",");
  595. //
  596. // CIISFilterList implementation
  597. //
  598. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  599. CIISFilterList::CIISFilterList(
  600. IN CComAuthInfo * pAuthInfo,
  601. IN LPCTSTR lpszMetaPath
  602. )
  603. /*++
  604. Routine Description:
  605. Constructor for filter list
  606. Arguments:
  607. LPCTSTR lpszServerName : Server name
  608. DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
  609. Return Value:
  610. N/A
  611. --*/
  612. : CMetaKey(
  613. pAuthInfo,
  614. CMetabasePath(FALSE, lpszMetaPath, g_cszFilters),
  615. METADATA_PERMISSION_READ
  616. ),
  617. m_hrResult(S_OK),
  618. m_strFilterOrder(),
  619. m_fFiltersLoaded(FALSE)
  620. {
  621. m_hrResult = CMetaKey::QueryResult();
  622. if (SUCCEEDED(m_hrResult))
  623. {
  624. m_hrResult = QueryValue(MD_FILTER_LOAD_ORDER, m_strFilterOrder);
  625. }
  626. if ( m_hrResult == CError::HResult(ERROR_PATH_NOT_FOUND)
  627. || m_hrResult == MD_ERROR_DATA_NOT_FOUND
  628. )
  629. {
  630. //
  631. // Harmless
  632. //
  633. m_hrResult = S_OK;
  634. }
  635. if (IsOpen())
  636. {
  637. Close();
  638. }
  639. }
  640. HRESULT
  641. CIISFilterList::LoadAllFilters()
  642. /*++
  643. Routine Description:
  644. Loop through the filter order string, and load information
  645. about each filter in turn.
  646. Arguments:
  647. None.
  648. Return Value:
  649. HRESULT. The first error stops filter loading.
  650. --*/
  651. {
  652. ASSERT(SUCCEEDED(m_hrResult));
  653. if (m_fFiltersLoaded)
  654. {
  655. //
  656. // Already done
  657. //
  658. return S_OK;
  659. }
  660. int cItems = 0;
  661. CError err(ReOpen(METADATA_PERMISSION_READ));
  662. if (err.Failed())
  663. {
  664. return err;
  665. }
  666. try
  667. {
  668. CString strSrc(m_strFilterOrder);
  669. LPTSTR lp = strSrc.GetBuffer(0);
  670. while (isspace(*lp) || *lp == (TCHAR)s_lpszSep)
  671. lp++;
  672. lp = _tcstok(lp, s_lpszSep);
  673. int nOrder = 0;
  674. while (lp)
  675. {
  676. CString str(lp);
  677. str.TrimLeft();
  678. str.TrimRight();
  679. TRACEEOLID("Adding filter: " << str);
  680. CIISFilter * pFilter = new CIISFilter(this, str);
  681. err = pFilter->QueryResult();
  682. if (err.Failed())
  683. {
  684. break;
  685. }
  686. pFilter->m_nOrder = nOrder++;
  687. m_oblFilters.AddTail(pFilter);
  688. lp = _tcstok(NULL, s_lpszSep);
  689. ++cItems;
  690. }
  691. //
  692. // Sort filters list
  693. //
  694. m_oblFilters.Sort(
  695. (CObjectPlus::PCOBJPLUS_ORDER_FUNC)
  696. &CIISFilter::OrderByPriority
  697. );
  698. }
  699. catch(CMemoryException * e)
  700. {
  701. e->Delete();
  702. err = ERROR_NOT_ENOUGH_MEMORY;
  703. }
  704. m_fFiltersLoaded = err.Succeeded();
  705. if (IsOpen())
  706. {
  707. Close();
  708. }
  709. return err;
  710. }
  711. HRESULT
  712. CIISFilterList::WriteIfDirty()
  713. /*++
  714. Routine Description:
  715. Write all the changes in the filters list to the metabase
  716. Arguments:
  717. None.
  718. Return Value:
  719. HRESULT
  720. --*/
  721. {
  722. CError err;
  723. CString strNewOrder;
  724. VERIFY(BuildFilterOrderString(strNewOrder));
  725. //
  726. // Check to see if this new list is different
  727. //
  728. if (!strNewOrder.CompareNoCase(m_strFilterOrder) && !HasDirtyFilter())
  729. {
  730. //
  731. // The priority list hasn't changed, and no filter is marked
  732. // as dirty, so all done.
  733. //
  734. return err;
  735. }
  736. //
  737. // It's dirty -- save it
  738. //
  739. do
  740. {
  741. err = ReOpen(METADATA_PERMISSION_WRITE);
  742. if (err.Failed())
  743. {
  744. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  745. {
  746. //
  747. // Path didn't exist yet, create it and reopen
  748. // it.
  749. //
  750. err = CreatePathFromFailedOpen();
  751. if (err.Succeeded())
  752. {
  753. err = ReOpen(METADATA_PERMISSION_WRITE);
  754. }
  755. }
  756. if (err.Failed())
  757. {
  758. break;
  759. }
  760. }
  761. //
  762. // Delete deleted filters
  763. //
  764. POSITION pos1, pos2;
  765. for (pos1 = m_oblFilters.GetHeadPosition(); (pos2 = pos1) != NULL; )
  766. {
  767. CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos1);
  768. ASSERT(pFilter != NULL);
  769. if (pFilter->IsFlaggedForDeletion())
  770. {
  771. TRACEEOLID("Deleting filter " << pFilter->QueryName());
  772. if (S_OK == DoesPathExist(pFilter->QueryName()))
  773. {
  774. err = DeleteKey(pFilter->QueryName());
  775. }
  776. if (err.Failed())
  777. {
  778. break;
  779. }
  780. m_oblFilters.RemoveAt(pos2);
  781. }
  782. }
  783. if (err.Failed())
  784. {
  785. break;
  786. }
  787. //
  788. // Two passes are necessary, because the filter may
  789. // have been re-added after it was deleted from the
  790. // list as new entry. This could be somewhat improved
  791. //
  792. ResetEnumerator();
  793. while(MoreFilters())
  794. {
  795. CIISFilter * pFilter = GetNextFilter();
  796. ASSERT(pFilter != NULL);
  797. if (pFilter->IsDirty())
  798. {
  799. TRACEEOLID("Writing filter " << pFilter->QueryName());
  800. err = pFilter->Write(this);
  801. if (err.Failed())
  802. {
  803. break;
  804. }
  805. pFilter->Dirty(FALSE);
  806. }
  807. }
  808. if (err.Failed())
  809. {
  810. break;
  811. }
  812. //
  813. // Write the new filter load order
  814. //
  815. err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
  816. if (err.Failed())
  817. {
  818. break;
  819. }
  820. CString strKey(_T("IIsFilters"));
  821. err = SetValue(MD_KEY_TYPE, strKey);
  822. err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
  823. m_strFilterOrder = strNewOrder;
  824. }
  825. while(FALSE);
  826. if (IsOpen())
  827. {
  828. Close();
  829. }
  830. return err;
  831. }
  832. POSITION
  833. CIISFilterList::GetFilterPositionByIndex(
  834. IN int nSel
  835. )
  836. /*++
  837. Routine Description:
  838. Return the position of a filter object by index, skipping filters
  839. marked for deletion.
  840. Arguments:
  841. int nSel - 0 based index into the list
  842. Return Value:
  843. The POSITION into the filters ObList of the filter at the index
  844. specified, or NULL if the filter is not found.
  845. --*/
  846. {
  847. int nIndex = -1;
  848. CIISFilter * pFilter;
  849. POSITION pos,
  850. posReturn = NULL;
  851. pos = m_oblFilters.GetHeadPosition();
  852. while(pos && nIndex < nSel)
  853. {
  854. posReturn = pos;
  855. pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
  856. //
  857. // Skipping deleted filters
  858. //
  859. if (!pFilter->IsFlaggedForDeletion())
  860. {
  861. ++nIndex;
  862. }
  863. }
  864. return posReturn;
  865. }
  866. BOOL
  867. CIISFilterList::ExchangePositions(
  868. IN int nSel1,
  869. IN int nSel2,
  870. OUT CIISFilter *& p1,
  871. OUT CIISFilter *& p2
  872. )
  873. /*++
  874. Routine Description:
  875. Exchange the positions of two filters in the list
  876. Arguments:
  877. int nSel1 : Item 1
  878. int nSel2 : Item 2
  879. CIISFilter *& p1 : Returns the item moved to position 1
  880. CIISFilter *& p2 : Returns the item moved to position 2
  881. Return Value:
  882. TRUE for success, FALSE for failure.
  883. --*/
  884. {
  885. ASSERT(SUCCEEDED(m_hrResult));
  886. //
  887. // Fetch filters at the two positions (deleted filters are
  888. // skipped in the index count)
  889. //
  890. POSITION pos1 = GetFilterPositionByIndex(nSel1);
  891. POSITION pos2 = GetFilterPositionByIndex(nSel2);
  892. p1 = pos2 ? (CIISFilter *)m_oblFilters.GetAt(pos2) : NULL;
  893. p2 = pos1 ? (CIISFilter *)m_oblFilters.GetAt(pos1) : NULL;
  894. if (!p1 || !p2)
  895. {
  896. TRACEEOLID("Invalid internal state -- filter exchange impossible");
  897. ASSERT(FALSE);
  898. return FALSE;
  899. }
  900. TRACEEOLID("Filter (1) name is " << p1->m_strName);
  901. TRACEEOLID("Filter (2) name is " << p2->m_strName);
  902. //
  903. // Exchange
  904. //
  905. m_oblFilters.SetAt(pos1, p1);
  906. m_oblFilters.SetAt(pos2, p2);
  907. //
  908. // Success
  909. //
  910. return TRUE;
  911. }
  912. LPCTSTR
  913. CIISFilterList::BuildFilterOrderString(
  914. OUT CString & strFilterOrder
  915. )
  916. /*++
  917. Routine Description:
  918. Convert the oblist of filters to a single filter order string
  919. fit to be stuffed into the metabase
  920. Arguments:
  921. CString & strFilterOrder : Output to receive the order string
  922. Return Value:
  923. A pointer to the new filter order string.
  924. --*/
  925. {
  926. BOOL fFirst = TRUE;
  927. POSITION pos = m_oblFilters.GetHeadPosition();
  928. strFilterOrder.Empty();
  929. while(pos)
  930. {
  931. CIISFilter * pFlt = (CIISFilter *)m_oblFilters.GetNext(pos);
  932. if (!pFlt->IsFlaggedForDeletion())
  933. {
  934. if (!fFirst)
  935. {
  936. strFilterOrder += s_lpszSep;
  937. }
  938. else
  939. {
  940. fFirst = FALSE;
  941. }
  942. strFilterOrder += pFlt->m_strName;
  943. }
  944. }
  945. return (LPCTSTR)strFilterOrder;
  946. }
  947. BOOL
  948. CIISFilterList::HasDirtyFilter() const
  949. /*++
  950. Routine Description:
  951. Go through the list of filters, and return TRUE if any filter
  952. in the list is dirty or flagged for deletion
  953. Arguments:
  954. None
  955. Return Value:
  956. TRUE if any filter is dirty or flagged for deletion.
  957. --*/
  958. {
  959. ASSERT(SUCCEEDED(m_hrResult));
  960. POSITION pos = m_oblFilters.GetHeadPosition();
  961. while(pos)
  962. {
  963. CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
  964. if (pFilter->IsFlaggedForDeletion() || pFilter->IsDirty())
  965. {
  966. return TRUE;
  967. }
  968. }
  969. return FALSE;
  970. }
  971. //
  972. // CW3Sheet implementation
  973. //
  974. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  975. CW3Sheet::CW3Sheet(
  976. IN CComAuthInfo * pAuthInfo,
  977. IN LPCTSTR lpszMetaPath,
  978. IN DWORD dwAttributes,
  979. IN CWnd * pParentWnd, OPTIONAL
  980. IN LPARAM lParam, OPTIONAL
  981. IN LPARAM lParamParent, OPTIONAL
  982. IN UINT iSelectPage
  983. )
  984. /*++
  985. Routine Description:
  986. WWW Property sheet constructor
  987. Arguments:
  988. CComAuthInfo * pAuthInfo : Authentication information
  989. LPCTSTR lpszMetPath : Metabase path
  990. DWORD dwAttributes : File attributes
  991. CWnd * pParentWnd : Optional parent window
  992. LPARAM lParam : MMC Console parameter
  993. UINT iSelectPage : Initial page to be selected
  994. Return Value:
  995. N/A
  996. --*/
  997. : CInetPropertySheet(
  998. pAuthInfo,
  999. lpszMetaPath,
  1000. pParentWnd,
  1001. lParam,
  1002. lParamParent,
  1003. iSelectPage
  1004. ),
  1005. m_ppropInst(NULL),
  1006. m_ppropDir(NULL),
  1007. m_fNew(FALSE),
  1008. m_dwAttributes(dwAttributes),
  1009. m_fCompatMode(FALSE)
  1010. {
  1011. }
  1012. CW3Sheet::~CW3Sheet()
  1013. /*++
  1014. Routine Description:
  1015. Sheet destructor
  1016. Arguments:
  1017. N/A
  1018. Return Value:
  1019. N/A
  1020. --*/
  1021. {
  1022. FreeConfigurationParameters();
  1023. }
  1024. HRESULT
  1025. CW3Sheet::SetKeyType()
  1026. {
  1027. CError err;
  1028. CIISObject * pNode = (CIISObject *)GetParameter();
  1029. ASSERT(pNode != NULL);
  1030. if (pNode == NULL)
  1031. {
  1032. return E_FAIL;
  1033. }
  1034. CMetaKey mk(QueryAuthInfo(), m_ppropDir->QueryMetaRoot(), METADATA_PERMISSION_WRITE);
  1035. err = mk.QueryResult();
  1036. if (err.Succeeded())
  1037. {
  1038. err = mk.SetValue(MD_KEY_TYPE, CString(pNode->GetKeyType(m_ppropDir->QueryMetaRoot())));
  1039. }
  1040. else if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  1041. {
  1042. err.Reset();
  1043. }
  1044. return err;
  1045. }
  1046. HRESULT
  1047. CW3Sheet::SetSheetType(int fSheetType)
  1048. {
  1049. m_fSheetType = fSheetType;
  1050. return S_OK;
  1051. }
  1052. void
  1053. CW3Sheet::WinHelp(
  1054. IN DWORD dwData,
  1055. IN UINT nCmd
  1056. )
  1057. /*++
  1058. Routine Description:
  1059. WWW Property sheet help handler
  1060. Arguments:
  1061. DWORD dwData : WinHelp data (dialog ID)
  1062. UINT nCmd : WinHelp command
  1063. Return Value:
  1064. None
  1065. Notes:
  1066. Replace the dialog ID if this is the directory tab. We have
  1067. different help depending on virtual directory, home, file, directory.
  1068. --*/
  1069. {
  1070. if (dwData == HIDD_DIRECTORY_PROPERTIES)
  1071. {
  1072. if (m_fSheetType == SHEET_TYPE_FILE)
  1073. {
  1074. dwData = HIDD_FS_FILE_PROPERTIES;
  1075. }
  1076. else if (m_fSheetType == SHEET_TYPE_DIR)
  1077. {
  1078. dwData = HIDD_FS_DIRECTORY_PROPERTIES;
  1079. }
  1080. else if (m_fSheetType == SHEET_TYPE_VDIR)
  1081. {
  1082. dwData = HIDD_DIRECTORY_PROPERTIES;
  1083. }
  1084. else if (m_fSheetType == SHEET_TYPE_SERVER)
  1085. {
  1086. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  1087. }
  1088. else if (m_fSheetType == SHEET_TYPE_SITE)
  1089. {
  1090. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  1091. }
  1092. else
  1093. {
  1094. ASSERT(m_ppropDir != NULL);
  1095. if (!::lstrcmpi(m_ppropDir->m_strAlias, g_cszRoot))
  1096. {
  1097. //
  1098. // It's a home virtual directory -- change the ID
  1099. //
  1100. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  1101. }
  1102. }
  1103. }
  1104. WinHelpDebug(dwData);
  1105. CInetPropertySheet::WinHelp(dwData, nCmd);
  1106. }
  1107. /* virtual */
  1108. HRESULT
  1109. CW3Sheet::LoadConfigurationParameters()
  1110. /*++
  1111. Routine Description:
  1112. Load configuration parameters information
  1113. Arguments:
  1114. None
  1115. Return Value:
  1116. HRESULT
  1117. --*/
  1118. {
  1119. //
  1120. // Load base properties
  1121. //
  1122. CError err(CInetPropertySheet::LoadConfigurationParameters());
  1123. if (err.Failed())
  1124. {
  1125. return err;
  1126. }
  1127. if (m_ppropInst == NULL)
  1128. {
  1129. //
  1130. // First call -- load values
  1131. //
  1132. ASSERT(m_ppropDir == NULL);
  1133. m_ppropInst = new CW3InstanceProps(QueryAuthInfo(), QueryInstancePath());
  1134. m_ppropDir = new CW3DirProps(QueryAuthInfo(), QueryDirectoryPath());
  1135. if (!m_ppropInst || !m_ppropDir)
  1136. {
  1137. TRACEEOLID("LoadConfigurationParameters: OOM");
  1138. SAFE_DELETE(m_ppropDir);
  1139. SAFE_DELETE(m_ppropInst);
  1140. err = ERROR_NOT_ENOUGH_MEMORY;
  1141. return err;
  1142. }
  1143. err = m_ppropInst->LoadData();
  1144. if (err.Succeeded())
  1145. {
  1146. err = m_ppropDir->LoadData();
  1147. if (err.Succeeded() && QueryMajorVersion() >= 6)
  1148. {
  1149. CMetaKey mk(QueryAuthInfo(), QueryServicePath(), METADATA_PERMISSION_READ);
  1150. err = mk.QueryResult();
  1151. if (err.Succeeded())
  1152. {
  1153. err = mk.QueryValue(MD_GLOBAL_STANDARD_APP_MODE_ENABLED, m_fCompatMode);
  1154. if (err.Failed())
  1155. {
  1156. // Reset the error here, so at least
  1157. // we will not return error.
  1158. // (if we return error, then we will AV elsewhere)
  1159. err.MessageBoxOnFailure();
  1160. err.Reset();
  1161. }
  1162. }
  1163. }
  1164. else if (err.Succeeded())
  1165. {
  1166. // We will enable this for IIS5.1 and lower
  1167. m_fCompatMode = TRUE;
  1168. }
  1169. }
  1170. }
  1171. return err;
  1172. }
  1173. /* virtual */
  1174. void
  1175. CW3Sheet::FreeConfigurationParameters()
  1176. /*++
  1177. Routine Description:
  1178. Clean up configuration data
  1179. Arguments:
  1180. None
  1181. Return Value:
  1182. None
  1183. --*/
  1184. {
  1185. //
  1186. // Base class
  1187. //
  1188. CInetPropertySheet::FreeConfigurationParameters();
  1189. ASSERT(m_ppropInst != NULL);
  1190. ASSERT(m_ppropDir != NULL);
  1191. SAFE_DELETE(m_ppropInst);
  1192. SAFE_DELETE(m_ppropDir);
  1193. }
  1194. DWORD
  1195. IsSSLEnabledOnServer(
  1196. IN CComAuthInfo * pAuthInfo,
  1197. OUT BOOL & fInstalled,
  1198. OUT BOOL & fEnabled
  1199. )
  1200. /*++
  1201. Routine Description:
  1202. Determine if SSL is installed on the server.
  1203. Arguments:
  1204. LPCTSTR lpszServer : Server name
  1205. BOOL & fInstalled : Returns TRUE if SSL is installed
  1206. BOOL & fEnabled : Returns TRUE if SSL is enabled
  1207. Return Value:
  1208. Error return code.
  1209. --*/
  1210. {
  1211. /*
  1212. LPW3_CONFIG_INFO lp = NULL;
  1213. CString str;
  1214. DWORD err = ::W3GetAdminInformation((LPTSTR)lpszServer, &lp);
  1215. if (err != ERROR_SUCCESS)
  1216. {
  1217. TRACEEOLID("Failed to determine if SSL is installed");
  1218. return err;
  1219. }
  1220. fInstalled = (lp->dwEncCaps & ENC_CAPS_NOT_INSTALLED) == 0;
  1221. fEnabled = (lp->dwEncCaps & ENC_CAPS_DISABLED) == 0;
  1222. NETAPIBUFFERFREE(lp);
  1223. */
  1224. //
  1225. // Above doesn't work for Beta I -- hack to assume true.
  1226. //
  1227. fInstalled = fEnabled = TRUE;
  1228. return ERROR_SUCCESS;
  1229. }
  1230. //
  1231. // Message Map
  1232. //
  1233. BEGIN_MESSAGE_MAP(CW3Sheet, CInetPropertySheet)
  1234. //{{AFX_MSG_MAP(CInetPropertySheet)
  1235. //}}AFX_MSG_MAP
  1236. END_MESSAGE_MAP()
  1237. HRESULT
  1238. CW3Sheet::EnumAppPools(CStringListEx& pools)
  1239. {
  1240. CError err;
  1241. CIISMBNode * p = (CIISMBNode *)GetParameter();
  1242. ASSERT(p != NULL);
  1243. CIISMachine * pMachine = p->GetOwner();
  1244. ASSERT(pMachine != NULL);
  1245. CString machine = pMachine->QueryMachineName();
  1246. do
  1247. {
  1248. CMetabasePath pools_path(TRUE, SZ_MBN_WEB, SZ_MBN_APP_POOLS);
  1249. CMetaEnumerator en(pMachine->QueryAuthInfo(), pools_path);
  1250. CString id, key_type;
  1251. err = en.QueryResult();
  1252. BREAK_ON_ERR_FAILURE(err);
  1253. while (err.Succeeded())
  1254. {
  1255. err = en.Next(id);
  1256. BREAK_ON_ERR_FAILURE(err);
  1257. err = en.QueryValue(MD_KEY_TYPE, key_type, NULL, id);
  1258. BREAK_ON_ERR_FAILURE(err);
  1259. if (0 == key_type.CompareNoCase(_T("IIsApplicationPool")))
  1260. {
  1261. pools.AddTail(id);
  1262. }
  1263. }
  1264. } while (FALSE);
  1265. err.Reset();
  1266. return err;
  1267. }
  1268. HRESULT
  1269. CW3Sheet::QueryDefaultPoolId(CString& id)
  1270. {
  1271. CError err;
  1272. CIISMBNode * p = (CIISMBNode *)GetParameter();
  1273. ASSERT(p != NULL);
  1274. CIISMachine * pMachine = p->GetOwner();
  1275. ASSERT(pMachine != NULL);
  1276. do
  1277. {
  1278. CMetabasePath service(TRUE, SZ_MBN_WEB);
  1279. CMetaKey mk(pMachine->QueryAuthInfo(), service, METADATA_PERMISSION_READ);
  1280. err = mk.QueryResult();
  1281. BREAK_ON_ERR_FAILURE(err);
  1282. err = mk.QueryValue(MD_APP_APPPOOL_ID, id);
  1283. } while (FALSE);
  1284. return err;
  1285. }