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.

1836 lines
48 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name :
  4. tsvccfg.cxx
  5. Abstract:
  6. Defines the functions for TCP services Info class.
  7. This module is intended to capture the common scheduler
  8. code for the tcp services ( especially internet services)
  9. which involves the Service Controller dispatch functions.
  10. Also this class provides an interface for common dll of servers.
  11. Author:
  12. Murali R. Krishnan ( MuraliK ) 15-Nov-1994
  13. Project:
  14. Internet Servers Common DLL
  15. --*/
  16. #include "tcpdllp.hxx"
  17. #include <rpc.h>
  18. #include <tsunami.hxx>
  19. #include <iistypes.hxx>
  20. #include <iisendp.hxx>
  21. #include <iisbind.hxx>
  22. #include <iisassoc.hxx>
  23. #include "inetreg.h"
  24. #include "tcpcons.h"
  25. #include "apiutil.h"
  26. #include <rdns.hxx>
  27. #include <ole2.h>
  28. #include <imd.h>
  29. #include <inetreg.h>
  30. #include <mb.hxx>
  31. //
  32. // Used to configure
  33. //
  34. typedef struct _IIS_SOCKET_CONFIG {
  35. DWORD nAcceptExOutstanding;
  36. } IIS_SOCKET_CONFIG;
  37. IIS_SOCKET_CONFIG TsSocketConfig[3] = {{5}, {40}, {100}};
  38. //
  39. // from security.cxx
  40. //
  41. BOOL
  42. BuildAnonymousAcctDesc(
  43. IN OUT PCHAR pszAcctDesc,
  44. IN const CHAR * pszDomainAndUser,
  45. IN const CHAR * pszPwd,
  46. OUT LPDWORD pdwAcctDescLen
  47. );
  48. BOOL
  49. AppendDottedDecimal(
  50. STR * pstr,
  51. DWORD dwAddress
  52. );
  53. //
  54. // private functions
  55. //
  56. extern VOID
  57. CopyUnicodeStringToBuffer(
  58. OUT WCHAR * pwchBuffer,
  59. IN DWORD cchMaxSize,
  60. IN LPCWSTR pwszSource
  61. );
  62. DWORD
  63. SetInetLogConfiguration(
  64. IN LOGGING *pLogging,
  65. IN EVENT_LOG * pEventLog,
  66. IN const INET_LOG_CONFIGURATION * pRpcLogConfig
  67. );
  68. DWORD
  69. GetRPCLogConfiguration(
  70. LOGGING *pLogging,
  71. OUT LPINET_LOG_CONFIGURATION * ppLogConfig
  72. );
  73. BOOL
  74. GenerateIpList(
  75. BOOL fIsGrant,
  76. ADDRESS_CHECK *pCheck,
  77. LPINET_INFO_IP_SEC_LIST *ppInfo
  78. );
  79. BOOL
  80. FillAddrCheckFromIpList(
  81. BOOL fIsGrant,
  82. LPINET_INFO_IP_SEC_LIST pInfo,
  83. ADDRESS_CHECK *pCheck
  84. );
  85. BOOL
  86. GetVrootCount(
  87. PVOID pvContext,
  88. MB * pmb,
  89. VIRTUAL_ROOT * pvr
  90. );
  91. BOOL
  92. GetVroots(
  93. PVOID pvContext,
  94. MB * pmb,
  95. VIRTUAL_ROOT * pvr
  96. );
  97. VOID
  98. CopyUnicodeStringToBuffer(
  99. OUT WCHAR * pwchBuffer,
  100. IN DWORD cchMaxSize,
  101. IN LPCWSTR pwszSource)
  102. /*
  103. copies at most cbMaxSize-1 characters from pwszSource to pwchBuffer
  104. */
  105. {
  106. DBG_ASSERT( pwszSource != NULL);
  107. DWORD cchLen = lstrlenW( pwszSource);
  108. if ( cchLen >= cchMaxSize) {
  109. DBGPRINTF( ( DBG_CONTEXT,
  110. "Long String ( %d chars) %ws given."
  111. " Truncating to %d chars\n",
  112. cchLen, pwszSource,
  113. cchMaxSize - 1));
  114. // There is a bug in the lstrcpyn. hence need to work around it.
  115. #ifndef LSTRCPYN_DEBUGGED
  116. cchLen = cchMaxSize - 2;
  117. # else
  118. cchLen = cchMaxSize -1;
  119. # endif
  120. }
  121. #ifndef LSTRCPYN_DEBUGGED
  122. lstrcpynW( pwchBuffer, pwszSource, cchLen + 1);
  123. # else
  124. lstrcpynW( pwchBuffer, pwszSource, cchLen );
  125. # endif
  126. return;
  127. } // CopyUnicodeStringToBuffer()
  128. BOOL
  129. IIS_SERVER_INSTANCE::GetCommonConfig(
  130. IN OUT PCHAR pConfig,
  131. IN DWORD dwLevel
  132. )
  133. /*++
  134. This function copies the current configuration for a service (IIS_SERVER_INSTANCE)
  135. into the given RPC object pConfig.
  136. In case of any failures, it deallocates any memory block that was
  137. allocated during the process of copy by this function alone.
  138. Arguments:
  139. pConfig - pointer to RPC configuration object for a service.
  140. dwLevel - level of our configuration.
  141. Returns:
  142. TRUE for success and FALSE for any errors.
  143. --*/
  144. {
  145. BOOL fReturn = TRUE;
  146. LPINETA_CONFIG_INFO pInfoConfig = (LPINETA_CONFIG_INFO)pConfig;
  147. ADDRESS_CHECK acCheck;
  148. BOOL fMustRel;
  149. MB mb( (IMDCOM*) m_Service->QueryMDObject() );
  150. DWORD cRoots = 0;
  151. STR strAnon;
  152. STR strAnonPwd;
  153. STR strServerComment;
  154. DWORD err = NO_ERROR;
  155. IF_DEBUG(INSTANCE) {
  156. DBGPRINTF((DBG_CONTEXT,"GetCommonConfig called with L%d for instance %d\n",
  157. dwLevel, QueryInstanceId() ));
  158. }
  159. LockThisForRead();
  160. //
  161. // Get always retrieves all of the parameters except for the anonymous
  162. // password, which is retrieved as a secret
  163. //
  164. pInfoConfig->FieldControl = (FC_INET_INFO_ALL & ~FC_INET_INFO_ANON_PASSWORD);
  165. pInfoConfig->dwConnectionTimeout = QueryConnectionTimeout();
  166. pInfoConfig->dwMaxConnections = QueryMaxConnections();
  167. pInfoConfig->LangId = GetSystemDefaultLangID();
  168. pInfoConfig->LocalId = GetSystemDefaultLCID();
  169. //
  170. // This is the PSS product ID
  171. //
  172. ZeroMemory( pInfoConfig->ProductId,sizeof( pInfoConfig->ProductId ));
  173. //
  174. // Copy the strings
  175. //
  176. fReturn = (ConvertStringToRpc(&pInfoConfig->lpszAdminName,
  177. ""/*QueryAdminName()*/ ) &&
  178. ConvertStringToRpc( &pInfoConfig->lpszAdminEmail,
  179. "" /*QueryAdminEmail()*/ )
  180. );
  181. if ( !fReturn ) {
  182. IF_DEBUG(INSTANCE) {
  183. DBGPRINTF((DBG_CONTEXT,"ConvertStringToRpc failed with %d\n",
  184. GetLastError() ));
  185. }
  186. goto Exit;
  187. } else {
  188. DWORD dwError;
  189. dwError = GetRPCLogConfiguration(&m_Logging,
  190. &pInfoConfig->lpLogConfig);
  191. if ( dwError != NO_ERROR) {
  192. IF_DEBUG(INSTANCE) {
  193. DBGPRINTF((DBG_CONTEXT,"GetRPCLogConfiguration failed with %d\n",
  194. dwError));
  195. }
  196. SetLastError( dwError);
  197. fReturn = FALSE;
  198. goto Exit;
  199. }
  200. }
  201. pInfoConfig->fLogAnonymous = QueryLogAnonymous();
  202. pInfoConfig->fLogNonAnonymous = QueryLogNonAnonymous();
  203. ZeroMemory(
  204. pInfoConfig->szAnonPassword,
  205. sizeof( pInfoConfig->szAnonPassword )
  206. );
  207. //
  208. // Copy the IP security info from metabase
  209. //
  210. if ( mb.Open( QueryMDVRPath() ) )
  211. {
  212. VOID * pvData;
  213. DWORD cbData;
  214. DWORD dwTag;
  215. if ( mb.ReferenceData( "",
  216. MD_IP_SEC,
  217. IIS_MD_UT_FILE,
  218. BINARY_METADATA,
  219. &pvData,
  220. &cbData,
  221. &dwTag ) &&
  222. dwTag )
  223. {
  224. acCheck.BindCheckList( (BYTE *) pvData, cbData );
  225. fMustRel = TRUE;
  226. }
  227. else
  228. {
  229. fMustRel = FALSE;
  230. }
  231. fReturn = GenerateIpList( TRUE, &acCheck, &pInfoConfig->GrantIPList ) &&
  232. GenerateIpList( FALSE, &acCheck, &pInfoConfig->DenyIPList );
  233. if ( fMustRel )
  234. {
  235. DBG_REQUIRE( mb.ReleaseReferenceData( dwTag ));
  236. }
  237. DBG_REQUIRE( mb.Close() );
  238. }
  239. else
  240. {
  241. fReturn = FALSE;
  242. }
  243. if ( !fReturn )
  244. {
  245. goto Exit;
  246. }
  247. //
  248. // Copy the virtual root info, note a NULL VirtualRoots is not
  249. // valid as it is for IP security. This should be the last
  250. // allocated item for the pConfig structure
  251. //
  252. if ( !mb.Open( QueryMDPath(),
  253. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ))
  254. {
  255. fReturn = FALSE;
  256. goto Exit;
  257. }
  258. if ( TsEnumVirtualRoots( GetVrootCount, &cRoots, &mb ) )
  259. {
  260. DWORD cbSize = sizeof(INET_INFO_VIRTUAL_ROOT_LIST) +
  261. cRoots * sizeof(INET_INFO_VIRTUAL_ROOT_ENTRY)
  262. ;
  263. pInfoConfig->VirtualRoots = (LPINET_INFO_VIRTUAL_ROOT_LIST)
  264. MIDL_user_allocate( cbSize );
  265. memset( pInfoConfig->VirtualRoots, 0, cbSize );
  266. if ( pInfoConfig->VirtualRoots )
  267. {
  268. fReturn = TsEnumVirtualRoots( GetVroots, pInfoConfig->VirtualRoots, &mb );
  269. }
  270. // only used for UNC virtual directories (to store the passwords)
  271. err = TsSetSecretW( m_lpwszRootPasswordSecretName,
  272. L"",
  273. sizeof(WCHAR) );
  274. if ( err == ERROR_ACCESS_DENIED && g_fW3OnlyNoAuth )
  275. {
  276. err = 0;
  277. }
  278. }
  279. mb.Close();
  280. if ( !fReturn )
  281. {
  282. goto Exit;
  283. }
  284. if ( !mb.Open( QueryMDPath() ))
  285. {
  286. fReturn = FALSE;
  287. goto Exit;
  288. }
  289. mb.GetDword( "",
  290. MD_AUTHORIZATION,
  291. IIS_MD_UT_FILE,
  292. MD_AUTH_ANONYMOUS,
  293. &pInfoConfig->dwAuthentication );
  294. if ( !mb.GetStr( "",
  295. MD_ANONYMOUS_USER_NAME,
  296. IIS_MD_UT_FILE,
  297. &strAnon,
  298. METADATA_INHERIT,
  299. "<>" ))
  300. {
  301. fReturn = FALSE;
  302. goto Exit;
  303. }
  304. if ( !mb.GetStr( "",
  305. MD_SERVER_COMMENT,
  306. IIS_MD_UT_SERVER,
  307. &strServerComment,
  308. METADATA_INHERIT,
  309. INETA_DEF_SERVER_COMMENT ))
  310. {
  311. //
  312. // If this is a single instance service, this is also the
  313. // service comment
  314. //
  315. if ( !m_Service->IsMultiInstance() ) {
  316. m_Service->SetServiceComment( strServerComment.QueryStr() );
  317. }
  318. }
  319. fReturn = ConvertStringToRpc( &pInfoConfig->lpszServerComment,
  320. strServerComment.QueryStr() ) &&
  321. ConvertStringToRpc( &pInfoConfig->lpszAnonUserName,
  322. strAnon.QueryStr() );
  323. //
  324. // Get the anonymous user password but store it as an LSA secret
  325. //
  326. if ( mb.GetStr( "",
  327. MD_ANONYMOUS_PWD,
  328. IIS_MD_UT_FILE,
  329. &strAnonPwd,
  330. METADATA_INHERIT | METADATA_SECURE ))
  331. {
  332. BUFFER buff;
  333. if ( buff.Resize( (strAnonPwd.QueryCCH() + 1) * sizeof(WCHAR )))
  334. {
  335. if ( MultiByteToWideChar( CP_ACP,
  336. MB_PRECOMPOSED,
  337. strAnonPwd.QueryStr(),
  338. strAnonPwd.QueryCCH() + 1,
  339. (LPWSTR) buff.QueryPtr(),
  340. strAnonPwd.QueryCCH() + 1 ))
  341. {
  342. err = TsSetSecretW( m_lpwszAnonPasswordSecretName,
  343. (LPWSTR) buff.QueryPtr(),
  344. wcslen( (LPWSTR) buff.QueryPtr()) * sizeof(WCHAR) );
  345. if ( err == ERROR_ACCESS_DENIED && g_fW3OnlyNoAuth )
  346. {
  347. err = 0;
  348. }
  349. }
  350. }
  351. }
  352. else
  353. {
  354. //
  355. // store an empty password if there's no anonymous user at this level
  356. //
  357. err = TsSetSecretW( m_lpwszAnonPasswordSecretName,
  358. L"",
  359. sizeof(WCHAR) );
  360. if ( err == ERROR_ACCESS_DENIED && g_fW3OnlyNoAuth )
  361. {
  362. err = 0;
  363. }
  364. }
  365. if ( err ) {
  366. SetLastError( err );
  367. fReturn = FALSE;
  368. }
  369. if ( !fReturn ) {
  370. IF_DEBUG(INSTANCE) {
  371. DBGPRINTF((DBG_CONTEXT,"Cannot get anonymous user name"));
  372. }
  373. }
  374. Exit:
  375. if ( !fReturn ) {
  376. if ( pInfoConfig->lpLogConfig != NULL) {
  377. MIDL_user_free( pInfoConfig->lpLogConfig);
  378. pInfoConfig->lpLogConfig = NULL;
  379. }
  380. //
  381. // FreeRpcString checks for NULL pointer
  382. //
  383. FreeRpcString( pInfoConfig->lpszAdminName );
  384. FreeRpcString( pInfoConfig->lpszAdminEmail );
  385. FreeRpcString( pInfoConfig->lpszServerComment );
  386. FreeRpcString( pInfoConfig->lpszAnonUserName );
  387. pInfoConfig->lpszAdminName = NULL;
  388. pInfoConfig->lpszAdminEmail = NULL;
  389. pInfoConfig->lpszServerComment = NULL;
  390. pInfoConfig->lpszAnonUserName = NULL;
  391. if ( pInfoConfig->DenyIPList ) {
  392. MIDL_user_free( pInfoConfig->DenyIPList );
  393. pInfoConfig->DenyIPList = NULL;
  394. }
  395. if ( pInfoConfig->GrantIPList ) {
  396. MIDL_user_free( pInfoConfig->GrantIPList );
  397. pInfoConfig->GrantIPList = NULL;
  398. }
  399. }
  400. UnlockThis();
  401. return (fReturn);
  402. } // IIS_SERVER_INSTANCE::GetConfiguration()
  403. BOOL
  404. IIS_SERVER_INSTANCE::RegReadCommonParams(
  405. BOOL fReadAll,
  406. BOOL fReadVirtualDirs
  407. )
  408. /*++
  409. Description
  410. Reads the service common items from the registry
  411. Arguments:
  412. fReadAll - If TRUE read all parameters.
  413. If FALSE read only those parameters that are necessary for initialization.
  414. fReadVirtualDirs - Initalize Virtual DIrectories.
  415. Note:
  416. --*/
  417. {
  418. MB mb( (IMDCOM*) m_Service->QueryMDObject() );
  419. DBG_ASSERT( QueryInstanceId() != INET_INSTANCE_ROOT );
  420. IF_DEBUG( DLL_RPC) {
  421. DBGPRINTF(( DBG_CONTEXT,
  422. "IIS_SERVER_INSTANCE::ReadParamsFromRegistry() Entered. fReadAll = %d\n",
  423. fReadAll));
  424. }
  425. //
  426. // Open the metabase and read parameters for IIS_SERVER_INSTANCE object
  427. // itself.
  428. //
  429. if ( !mb.Open( QueryMDPath(),
  430. TsIsNtServer() ? METADATA_PERMISSION_READ :
  431. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ))
  432. {
  433. DBGPRINTF(( DBG_CONTEXT,
  434. "[ReadParamsFromRegistry] mb.Open returned error %d for path %s\n",
  435. GetLastError(),
  436. QueryMDPath() ));
  437. }
  438. LockThisForWrite();
  439. //
  440. // Values needed for initialization
  441. //
  442. mb.GetDword( "",
  443. MD_SERVER_AUTOSTART,
  444. IIS_MD_UT_SERVER,
  445. TRUE,
  446. (DWORD *) &m_fAutoStart
  447. );
  448. mb.GetDword( "",
  449. MD_CLUSTER_ENABLED,
  450. IIS_MD_UT_SERVER,
  451. FALSE,
  452. (DWORD *) &m_fClusterEnabled
  453. );
  454. /*
  455. That's a fix for a bug 367791 when restarting IIS with
  456. vhost sites marked for auto restart isn't bringing them online
  457. becuase of current disgn limitation how cluster service is checking for helth of
  458. vhost site it is not able to distinguish that only one of few vhost sites are running
  459. and is not starting the rest. The fix is to allow to admin to set autorestart on site
  460. and then during startup of IIS to start that site not with cluster command but automaticcally
  461. Because of that the following lines are removed.
  462. if ( m_fClusterEnabled )
  463. {
  464. m_fAutoStart = FALSE;
  465. }
  466. */
  467. if ( !mb.GetStr( "",
  468. MD_SERVER_COMMENT,
  469. IIS_MD_UT_SERVER,
  470. &m_strSiteName ) ||
  471. m_strSiteName.IsEmpty())
  472. {
  473. m_strSiteName.Copy(QueryMDPath());
  474. }
  475. //
  476. // Other values needed to run the instance
  477. //
  478. if ( fReadAll)
  479. {
  480. mb.GetDword( "",
  481. MD_CONNECTION_TIMEOUT,
  482. IIS_MD_UT_SERVER,
  483. INETA_DEF_CONNECTION_TIMEOUT,
  484. &m_dwConnectionTimeout
  485. );
  486. mb.GetDword( "",
  487. MD_MAX_CONNECTIONS,
  488. IIS_MD_UT_SERVER,
  489. INETA_DEF_MAX_CONNECTIONS,
  490. &m_dwMaxConnections
  491. );
  492. mb.GetDword( "",
  493. MD_MAX_ENDPOINT_CONNECTIONS,
  494. IIS_MD_UT_SERVER,
  495. (TsIsNtServer()
  496. ? TsSocketConfig[MD_SERVER_SIZE_LARGE].nAcceptExOutstanding
  497. : INETA_DEF_MAX_ENDPOINT_CONNECTIONS_PWS
  498. ),
  499. &m_dwMaxEndpointConnections
  500. );
  501. mb.GetDword( "",
  502. MD_LEVELS_TO_SCAN,
  503. IIS_MD_UT_SERVER,
  504. INETA_DEF_LEVELS_TO_SCAN,
  505. &m_dwLevelsToScan
  506. );
  507. //
  508. // if not NTS, limit the connections. If reg value exceeds 40,
  509. // set it to 10.
  510. //
  511. if ( !TsIsNtServer() ) {
  512. if ( m_dwMaxConnections > INETA_MAX_MAX_CONNECTIONS_PWS ) {
  513. m_dwMaxConnections = INETA_DEF_MAX_CONNECTIONS_PWS;
  514. mb.SetDword( "",
  515. MD_MAX_CONNECTIONS,
  516. IIS_MD_UT_SERVER,
  517. m_dwMaxConnections
  518. );
  519. }
  520. if ( m_dwMaxEndpointConnections > INETA_MAX_MAX_ENDPOINT_CONNECTIONS_PWS ) {
  521. m_dwMaxEndpointConnections = INETA_DEF_MAX_ENDPOINT_CONNECTIONS_PWS;
  522. mb.SetDword( "",
  523. MD_MAX_ENDPOINT_CONNECTIONS,
  524. IIS_MD_UT_SERVER,
  525. m_dwMaxEndpointConnections
  526. );
  527. }
  528. }
  529. //
  530. // Log anonymous and Log non-anonymous or for FTP only
  531. //
  532. mb.GetDword( "",
  533. MD_LOG_TYPE,
  534. IIS_MD_UT_SERVER,
  535. TRUE,
  536. (DWORD *) &m_fLoggingEnabled
  537. );
  538. mb.GetDword( "",
  539. MD_LOG_ANONYMOUS,
  540. IIS_MD_UT_SERVER,
  541. INETA_DEF_LOG_ANONYMOUS,
  542. (DWORD *) &m_fLogAnonymous
  543. );
  544. mb.GetDword( "",
  545. MD_LOG_NONANONYMOUS,
  546. IIS_MD_UT_SERVER,
  547. INETA_DEF_LOG_NONANONYMOUS,
  548. (DWORD *) &m_fLogNonAnonymous
  549. );
  550. #if 0
  551. //
  552. // I don't believe that ServerCommand can be set to
  553. // started without our noticing, so I'm removing this
  554. // code.
  555. //
  556. if (!m_fAutoStart) {
  557. //
  558. // Server Command to start this instance may
  559. // have been written while service was stopped.
  560. // Need to pick it up
  561. //
  562. DWORD dwServerCommand;
  563. mb.GetDword( "",
  564. MD_SERVER_COMMAND,
  565. IIS_MD_UT_SERVER,
  566. TRUE,
  567. (DWORD *) &dwServerCommand
  568. );
  569. if (dwServerCommand == MD_SERVER_COMMAND_START) {
  570. m_fAutoStart = TRUE;
  571. }
  572. }
  573. #endif
  574. //
  575. // Other fields
  576. //
  577. //
  578. // socket values
  579. //
  580. mb.GetDword( "",
  581. MD_SERVER_SIZE,
  582. IIS_MD_UT_SERVER,
  583. INETA_DEF_SERVER_SIZE,
  584. &m_dwServerSize
  585. );
  586. if ( m_dwServerSize > MD_SERVER_SIZE_LARGE ) {
  587. m_dwServerSize = INETA_DEF_SERVER_SIZE;
  588. }
  589. mb.GetDword( "",
  590. MD_SERVER_LISTEN_BACKLOG,
  591. IIS_MD_UT_SERVER,
  592. TsSocketConfig[m_dwServerSize].nAcceptExOutstanding,
  593. &m_nAcceptExOutstanding
  594. );
  595. mb.GetDword( "",
  596. MD_SERVER_LISTEN_TIMEOUT,
  597. IIS_MD_UT_SERVER,
  598. INETA_DEF_ACCEPTEX_TIMEOUT,
  599. &m_AcceptExTimeout
  600. );
  601. //
  602. // Setup a bandwidth throttle descriptor if necessary (for NT server)
  603. //
  604. SetBandwidthThrottle( &mb );
  605. //
  606. // Set the maximum number of blocked requests for throttler
  607. //
  608. SetBandwidthThrottleMaxBlocked( &mb );
  609. // Root instance does not have VRs. Close the metabase because the
  610. // virtual directories are going to be re-enumerated.
  611. //
  612. }
  613. mb.Close();
  614. if ( fReadVirtualDirs ) {
  615. TsReadVirtualRoots( );
  616. }
  617. UnlockThis();
  618. return TRUE;
  619. } // IIS_SERVER_INSTANCE::ReadParamsFromRegistry()
  620. BOOL
  621. IIS_SERVER_INSTANCE::SetCommonConfig(
  622. IN LPINETA_CONFIG_INFO pInfoConfig,
  623. IN BOOL fRefresh
  624. )
  625. /*++
  626. Description
  627. Writes the service common items to the registry
  628. Arguments:
  629. pInfoConfig - Admin items to write to the registry
  630. fRefresh - Indicates whether we need to read back the data
  631. Note:
  632. We don't need to lock "this" object because we only write to the registry
  633. The anonymous password is set as a secret from the client side
  634. --*/
  635. {
  636. DWORD err = NO_ERROR;
  637. FIELD_CONTROL fcConfig;
  638. ADDRESS_CHECK acCheck;
  639. BUFFER buff;
  640. MB mb( (IMDCOM*) m_Service->QueryMDObject() );
  641. //
  642. // Open the metabase and read parameters for IIS_SERVER_INSTANCE object
  643. // itself.
  644. //
  645. if ( !mb.Open( QueryMDPath(),
  646. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE )) {
  647. DBGPRINTF(( DBG_CONTEXT,
  648. "[SetCommonConfig] mb.Open returned error %d for path %s\n",
  649. GetLastError(),
  650. QueryMDPath() ));
  651. return FALSE;
  652. }
  653. fcConfig = pInfoConfig->FieldControl;
  654. if ( IsFieldSet( fcConfig, FC_INET_INFO_CONNECTION_TIMEOUT ))
  655. {
  656. mb.SetDword( "",
  657. MD_CONNECTION_TIMEOUT,
  658. IIS_MD_UT_SERVER,
  659. pInfoConfig->dwConnectionTimeout );
  660. }
  661. if ( (err == NO_ERROR) && IsFieldSet( fcConfig, FC_INET_INFO_MAX_CONNECTIONS ))
  662. {
  663. mb.SetDword( "",
  664. MD_MAX_CONNECTIONS,
  665. IIS_MD_UT_SERVER,
  666. pInfoConfig->dwMaxConnections );
  667. }
  668. if ( (err == NO_ERROR) &&
  669. IsFieldSet( fcConfig, FC_INET_INFO_SERVER_COMMENT ) &&
  670. (pInfoConfig->lpszServerComment != NULL) )
  671. {
  672. if ( buff.Resize( 2 * (wcslen(pInfoConfig->lpszServerComment) + 1) *
  673. sizeof(CHAR) ) )
  674. {
  675. (VOID) ConvertUnicodeToAnsi( pInfoConfig->lpszServerComment,
  676. (CHAR *) buff.QueryPtr(),
  677. buff.QuerySize() );
  678. mb.SetString( "",
  679. MD_SERVER_COMMENT,
  680. IIS_MD_UT_SERVER,
  681. (CHAR *) buff.QueryPtr() );
  682. }
  683. }
  684. if ( (err == NO_ERROR) &&
  685. IsFieldSet( fcConfig, FC_INET_INFO_ANON_USER_NAME ) &&
  686. (pInfoConfig->lpszAnonUserName != NULL) )
  687. {
  688. STR strAnonPwd;
  689. if ( buff.Resize( 2 * (wcslen(pInfoConfig->lpszAnonUserName) + 1) *
  690. sizeof(CHAR) ) )
  691. {
  692. (VOID) ConvertUnicodeToAnsi( pInfoConfig->lpszAnonUserName,
  693. (CHAR *) buff.QueryPtr(),
  694. buff.QuerySize() );
  695. mb.SetString( "",
  696. MD_ANONYMOUS_USER_NAME,
  697. IIS_MD_UT_FILE,
  698. (CHAR *) buff.QueryPtr() );
  699. }
  700. //
  701. // Set the anonymous password also. The client sets it as an LSA
  702. // secret
  703. //
  704. if ( TsGetSecretW( m_lpwszAnonPasswordSecretName,
  705. &strAnonPwd ) &&
  706. mb.SetString( "",
  707. MD_ANONYMOUS_PWD,
  708. IIS_MD_UT_FILE,
  709. strAnonPwd.QueryStr() ))
  710. {
  711. DBGPRINTF(( DBG_CONTEXT,
  712. "Failed to get/set anonymous secret, err %d\n",
  713. GetLastError() ));
  714. }
  715. }
  716. if ( (err == NO_ERROR) && IsFieldSet( fcConfig, FC_INET_INFO_AUTHENTICATION ))
  717. {
  718. mb.SetDword( "",
  719. MD_AUTHORIZATION,
  720. IIS_MD_UT_FILE,
  721. pInfoConfig->dwAuthentication );
  722. }
  723. //
  724. // Write other fields
  725. //
  726. if ( (err == NO_ERROR) &&
  727. IsFieldSet( fcConfig, FC_INET_INFO_SITE_SECURITY ))
  728. {
  729. if ( (pInfoConfig->GrantIPList && pInfoConfig->GrantIPList->cEntries)
  730. || (pInfoConfig->DenyIPList && pInfoConfig->DenyIPList->cEntries) )
  731. {
  732. acCheck.BindCheckList( NULL, 0 );
  733. if ( FillAddrCheckFromIpList( TRUE, pInfoConfig->GrantIPList, &acCheck ) &&
  734. FillAddrCheckFromIpList( FALSE, pInfoConfig->DenyIPList, &acCheck ) )
  735. {
  736. if ( !mb.SetData( IIS_MD_INSTANCE_ROOT,
  737. MD_IP_SEC,
  738. IIS_MD_UT_FILE,
  739. BINARY_METADATA,
  740. (acCheck.GetStorage()->GetAlloc()
  741. ? acCheck.GetStorage()->GetAlloc() : (LPBYTE)""),
  742. acCheck.GetStorage()->GetUsed(),
  743. METADATA_INHERIT | METADATA_REFERENCE ))
  744. {
  745. err = GetLastError();
  746. }
  747. }
  748. acCheck.UnbindCheckList();
  749. }
  750. else
  751. {
  752. if ( !mb.DeleteData( IIS_MD_INSTANCE_ROOT,
  753. MD_IP_SEC,
  754. IIS_MD_UT_FILE,
  755. BINARY_METADATA ) )
  756. {
  757. // not an error : property may not exists
  758. //err = GetLastError();
  759. }
  760. }
  761. }
  762. DBG_REQUIRE( mb.Close() );
  763. if ( (err == NO_ERROR) &&
  764. IsFieldSet( fcConfig, FC_INET_INFO_LOG_CONFIG) &&
  765. (pInfoConfig->lpLogConfig != NULL) ) {
  766. err = SetInetLogConfiguration(&m_Logging,
  767. m_Service->QueryEventLog(),
  768. pInfoConfig->lpLogConfig);
  769. if ( err != NO_ERROR) {
  770. DBGPRINTF(( DBG_CONTEXT,
  771. "SetConfiguration() SetInetLogConfig() failed. "
  772. " Err=%u\n",
  773. err));
  774. }
  775. }
  776. if ( (err == NO_ERROR) &&
  777. IsFieldSet( fcConfig, FC_INET_INFO_VIRTUAL_ROOTS )) {
  778. if ( QueryInstanceId() != INET_INSTANCE_ROOT ) {
  779. if ( !TsSetVirtualRoots( pInfoConfig
  780. )) {
  781. err = GetLastError();
  782. DBGPRINTF(( DBG_CONTEXT,
  783. "[SetConfiguration()]SetVirtualRoots "
  784. " returns error %d\n",
  785. err));
  786. }
  787. }
  788. }
  789. if ( err != NO_ERROR ) {
  790. IF_DEBUG( ERROR) {
  791. DBGPRINTF(( DBG_CONTEXT,
  792. "IIS_SERVER_INSTANCE::SetCommonConfig ==> Error = %u\n",
  793. err));
  794. }
  795. SetLastError( err );
  796. return(FALSE);
  797. }
  798. return TRUE;
  799. } // IIS_SERVER_INSTANCE::SetCommonConfig
  800. VOID
  801. IIS_SERVER_INSTANCE::MDChangeNotify(
  802. MD_CHANGE_OBJECT * pcoChangeList
  803. )
  804. /*++
  805. This method handles the metabase change notification for this service.
  806. Arguments:
  807. pcoChangeList - path and id that has changed
  808. --*/
  809. {
  810. DWORD i;
  811. DWORD status = NO_ERROR;
  812. BOOL fVRUpdated = FALSE;
  813. BOOL fReadCommon = FALSE;
  814. BOOL fShouldMirror = FALSE;
  815. HRESULT hr;
  816. BOOL fShouldCoUninitialize = FALSE;
  817. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  818. if ( SUCCEEDED(hr) ) {
  819. fShouldCoUninitialize = TRUE;
  820. }
  821. else if (hr != E_INVALIDARG &&
  822. hr != RPC_E_CHANGED_MODE) {
  823. //
  824. // E_INVALIDARG and RPC_E_CHANGED_MODE could mean com was already
  825. // initialized with different parameters, so ignore it but don't
  826. // Uninit. Assert on other errors.
  827. //
  828. DBGPRINTF((DBG_CONTEXT,"CoInitializeEx failed with %x\n",hr));
  829. DBG_ASSERT(FALSE);
  830. }
  831. if ( (pcoChangeList->dwMDChangeType &
  832. (MD_CHANGE_TYPE_DELETE_OBJECT |
  833. MD_CHANGE_TYPE_RENAME_OBJECT |
  834. MD_CHANGE_TYPE_ADD_OBJECT) ) != 0 )
  835. {
  836. //
  837. // Something got added/deleted/renamed
  838. //
  839. fShouldMirror = TRUE;
  840. }
  841. LockThisForWrite();
  842. for ( i = 0; i < pcoChangeList->dwMDNumDataIDs; i++ )
  843. {
  844. m_Logging.NotifyChange( pcoChangeList->pdwMDDataIDs[i] );
  845. switch ( pcoChangeList->pdwMDDataIDs[i] )
  846. {
  847. case MD_SERVER_BINDINGS:
  848. if( QueryServerState() != MD_SERVER_STATE_STOPPED ) {
  849. status = UpdateNormalBindings();
  850. if( status != NO_ERROR ) {
  851. DBGPRINTF((
  852. DBG_CONTEXT,
  853. "MDChangeNotify: UpdateNormalBindings() failed,error %lu\n",
  854. status
  855. ));
  856. }
  857. SetWin32Error( status );
  858. }
  859. break;
  860. case MD_SECURE_BINDINGS:
  861. if( QueryServerState() != MD_SERVER_STATE_STOPPED ) {
  862. status = UpdateSecureBindings();
  863. if( status != NO_ERROR ) {
  864. DBGPRINTF((
  865. DBG_CONTEXT,
  866. "MDChangeNotify: UpdateSecureBindings() failed,error %lu\n",
  867. status
  868. ));
  869. }
  870. SetWin32Error( status );
  871. }
  872. break;
  873. case MD_DISABLE_SOCKET_POOLING:
  874. if( QueryServerState() != MD_SERVER_STATE_STOPPED )
  875. {
  876. if (HasNormalBindings())
  877. {
  878. status = RemoveNormalBindings();
  879. if (NO_ERROR == status)
  880. {
  881. status = UpdateNormalBindings();
  882. if( status != NO_ERROR ) {
  883. DBGPRINTF((
  884. DBG_CONTEXT,
  885. "MDChangeNotify: UpdateNormalBindings() failed,error %lu\n",
  886. status
  887. ));
  888. }
  889. }
  890. else
  891. {
  892. DBGPRINTF((
  893. DBG_CONTEXT,
  894. "MDChangeNotify: RemoveNormalBindings() failed,error %lu\n",
  895. status
  896. ));
  897. }
  898. }
  899. if ( (status == NO_ERROR) && HasSecureBindings())
  900. {
  901. status = RemoveSecureBindings();
  902. if (NO_ERROR == status)
  903. {
  904. status = UpdateSecureBindings();
  905. if( status != NO_ERROR ) {
  906. DBGPRINTF((
  907. DBG_CONTEXT,
  908. "MDChangeNotify: UpdateSecureBindings() failed,error %lu\n",
  909. status
  910. ));
  911. }
  912. }
  913. else
  914. {
  915. DBGPRINTF((
  916. DBG_CONTEXT,
  917. "MDChangeNotify: RemoveSecureBindings() failed,error %lu\n",
  918. status
  919. ));
  920. }
  921. }
  922. SetWin32Error( status );
  923. }
  924. break;
  925. case MD_CLUSTER_ENABLED:
  926. status = PerformClusterModeChange();
  927. if( status != NO_ERROR ) {
  928. IF_DEBUG( INSTANCE ) {
  929. DBGPRINTF((
  930. DBG_CONTEXT,
  931. "MDChangeNotify: PerformClusterModeChange() failed, error %lu\n",
  932. status
  933. ));
  934. }
  935. }
  936. break;
  937. case MD_SERVER_COMMAND:
  938. //
  939. // If cluster mode is enabled command must be specified
  940. // using MD_CLUSTER_SERVER_COMMAND, so that ISM cannot set the server state :
  941. // State management is to be done by cluster code exclusively.
  942. //
  943. if ( IsClusterEnabled() )
  944. {
  945. break;
  946. }
  947. case MD_CLUSTER_SERVER_COMMAND:
  948. status = PerformStateChange();
  949. if( status != NO_ERROR ) {
  950. IF_DEBUG( INSTANCE ) {
  951. DBGPRINTF((
  952. DBG_CONTEXT,
  953. "MDChangeNotify: ProcessStateChange() failed, error %lu\n",
  954. status
  955. ));
  956. }
  957. }
  958. //
  959. // if command started server then need to reload virtual roots
  960. // as failing-over may have enabled new file system resources
  961. //
  962. if ( QueryServerState() != MD_SERVER_STATE_STARTED )
  963. {
  964. break;
  965. }
  966. // fall-through
  967. case MD_VR_PATH:
  968. case MD_VR_USERNAME:
  969. case MD_VR_PASSWORD:
  970. fShouldMirror = TRUE;
  971. if ( !fVRUpdated )
  972. {
  973. //
  974. // Note individual root errors log an event
  975. //
  976. if ( !TsReadVirtualRoots(pcoChangeList) )
  977. {
  978. DBGPRINTF(( DBG_CONTEXT,
  979. "Error %d (0x%lx) reading virtual root info for %s\n",
  980. GetLastError(), GetLastError(), pcoChangeList->pszMDPath ));
  981. }
  982. fVRUpdated = TRUE;
  983. }
  984. break;
  985. case MD_MAX_BANDWIDTH:
  986. {
  987. MB mb( (IMDCOM*) m_Service->QueryMDObject() );
  988. if ( mb.Open( QueryMDPath() ) )
  989. {
  990. if ( !SetBandwidthThrottle( &mb ) )
  991. {
  992. DWORD dwError = GetLastError();
  993. DBGPRINTF(( DBG_CONTEXT,
  994. "MDChangeNotify: SetBandwidthThrottle failed, error %lu\n",
  995. dwError ));
  996. SetWin32Error( dwError );
  997. }
  998. DBG_REQUIRE( mb.Close() );
  999. }
  1000. break;
  1001. }
  1002. case MD_MAX_BANDWIDTH_BLOCKED:
  1003. {
  1004. MB mb( (IMDCOM*) m_Service->QueryMDObject() );
  1005. if ( mb.Open( QueryMDPath() ) )
  1006. {
  1007. if ( !SetBandwidthThrottleMaxBlocked( &mb ) )
  1008. {
  1009. DWORD dwError = GetLastError();
  1010. DBGPRINTF(( DBG_CONTEXT,
  1011. "MDChangeNotify: SetBandwidthThrottle failed, error %lu\n",
  1012. dwError ));
  1013. SetWin32Error( dwError );
  1014. }
  1015. DBG_REQUIRE( mb.Close() );
  1016. }
  1017. break;
  1018. }
  1019. //
  1020. // Ignore state & status updates
  1021. //
  1022. case MD_SERVER_STATE:
  1023. case MD_WIN32_ERROR:
  1024. break;
  1025. case MD_ACCESS_PERM:
  1026. fShouldMirror = TRUE;
  1027. break;
  1028. case MD_LOG_TYPE:
  1029. {
  1030. DWORD dwLogType;
  1031. MB mb( (IMDCOM*) m_Service->QueryMDObject() );
  1032. if ( mb.Open( QueryMDPath() ) &&
  1033. mb.GetDword("", MD_LOG_TYPE, IIS_MD_UT_SERVER, &dwLogType)
  1034. )
  1035. {
  1036. m_fLoggingEnabled = (1 == dwLogType);
  1037. }
  1038. fReadCommon = TRUE;
  1039. break;
  1040. }
  1041. default:
  1042. fReadCommon = TRUE;
  1043. break;
  1044. }
  1045. }
  1046. if ( fReadCommon )
  1047. {
  1048. m_Logging.NotifyChange( 0 );
  1049. RegReadCommonParams( TRUE, FALSE );
  1050. }
  1051. if ((MD_CHANGE_TYPE_DELETE_OBJECT == pcoChangeList->dwMDChangeType) &&
  1052. (! _strnicmp( (LPCSTR) pcoChangeList->pszMDPath+QueryMDPathLen()+1,
  1053. IIS_MD_INSTANCE_ROOT,
  1054. sizeof(IIS_MD_INSTANCE_ROOT)-1))
  1055. )
  1056. {
  1057. if ( !TsReadVirtualRoots(pcoChangeList) )
  1058. {
  1059. DBGPRINTF(( DBG_CONTEXT,
  1060. "Error %d (0x%lx) removing virtual root %s\n",
  1061. GetLastError(), GetLastError(), pcoChangeList->pszMDPath ));
  1062. }
  1063. }
  1064. //
  1065. // reflect the changes to the registry
  1066. //
  1067. if ( fShouldMirror && IsDownLevelInstance() )
  1068. {
  1069. MDMirrorVirtualRoots( );
  1070. }
  1071. UnlockThis();
  1072. if ( fShouldCoUninitialize ) {
  1073. CoUninitialize( );
  1074. }
  1075. return;
  1076. } // IIS_SERVER_INSTANCE::MDChangeNotify
  1077. VOID
  1078. IIS_SERVER_INSTANCE::MDMirrorVirtualRoots(
  1079. VOID
  1080. )
  1081. {
  1082. DWORD err;
  1083. HKEY hkey = NULL;
  1084. //
  1085. // Delete VR key
  1086. //
  1087. err = RegOpenKeyEx(
  1088. HKEY_LOCAL_MACHINE,
  1089. m_Service->QueryRegParamKey(),
  1090. 0,
  1091. KEY_ALL_ACCESS,
  1092. &hkey );
  1093. if ( err != NO_ERROR ) {
  1094. DBGPRINTF(( DBG_CONTEXT, "RegOpenKeyEx for returned error %d\n",err ));
  1095. return;
  1096. }
  1097. //
  1098. // First delete the key to remove any old values
  1099. //
  1100. err = RegDeleteKey( hkey, VIRTUAL_ROOTS_KEY_A );
  1101. RegCloseKey(hkey);
  1102. if ( err != NO_ERROR )
  1103. {
  1104. DBGPRINTF(( DBG_CONTEXT,
  1105. "[MDMirrorVRoots] Unable to remove old values\n"));
  1106. return;
  1107. }
  1108. //
  1109. // Now recreate the keys
  1110. //
  1111. MoveMDVroots2Registry( );
  1112. return;
  1113. } // IIS_SERVER_INSTANCE::MDMirrorVirtualRoots
  1114. DWORD
  1115. GetRPCLogConfiguration(IN LOGGING *pLogging,
  1116. OUT LPINET_LOG_CONFIGURATION * ppLogConfig)
  1117. /*++
  1118. This function allocates space (using MIDL_ functions) and stores
  1119. log configuration for the given log handle in it.
  1120. Arguments:
  1121. hInetLog handle for InetLog object.
  1122. ppLogConfig pointer to INET_LOG_CONFIGURATION object which on return
  1123. contains valid log config informtion, on success.
  1124. Returns:
  1125. Win32 error code.
  1126. --*/
  1127. {
  1128. DWORD dwError = NO_ERROR;
  1129. LPINET_LOG_CONFIGURATION pRpcConfig;
  1130. WCHAR cBuffer[MAX_PATH];
  1131. DBG_ASSERT( ppLogConfig != NULL);
  1132. pRpcConfig = ((LPINET_LOG_CONFIGURATION )
  1133. MIDL_user_allocate( sizeof(INET_LOG_CONFIGURATION)));
  1134. if ( pRpcConfig != NULL) {
  1135. INETLOG_CONFIGURATIONA ilogConfig;
  1136. DWORD cbConfig = sizeof(ilogConfig);
  1137. BOOL fReturn=TRUE;
  1138. ZeroMemory( &ilogConfig, sizeof(ilogConfig ));
  1139. pLogging->GetConfig( &ilogConfig );
  1140. //
  1141. // we got valid config. copy it into pRpcConfig.
  1142. // since the enumerated values in inetlog.w are same in inetasrv.h
  1143. // we do no mapping, we directly copy values.
  1144. ZeroMemory( pRpcConfig, sizeof( INET_LOG_CONFIGURATION));
  1145. pRpcConfig->inetLogType = ilogConfig.inetLogType;
  1146. switch ( ilogConfig.inetLogType) {
  1147. case INET_LOG_TO_FILE:
  1148. pRpcConfig->ilPeriod = ilogConfig.u.logFile.ilPeriod;
  1149. pRpcConfig->cbSizeForTruncation =
  1150. ilogConfig.u.logFile.cbSizeForTruncation;
  1151. ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  1152. ilogConfig.u.logFile.rgchLogFileDirectory, -1,
  1153. (WCHAR *)cBuffer, MAX_PATH );
  1154. CopyUnicodeStringToBuffer(
  1155. pRpcConfig->rgchLogFileDirectory,
  1156. MAX_PATH,
  1157. cBuffer);
  1158. *((DWORD *)&(pRpcConfig->rgchDataSource[MAX_PATH-sizeof(DWORD)]))=ilogConfig.u.logFile.ilFormat;
  1159. *((DWORD *)&(pRpcConfig->rgchDataSource[MAX_PATH-2*sizeof(DWORD)]))=ilogConfig.u.logFile.dwFieldMask;
  1160. break;
  1161. case INET_LOG_TO_SQL:
  1162. ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  1163. ilogConfig.u.logSql.rgchDataSource, -1,
  1164. (WCHAR *)cBuffer, MAX_PATH );
  1165. CopyUnicodeStringToBuffer(
  1166. pRpcConfig->rgchDataSource,
  1167. MAX_PATH,
  1168. cBuffer);
  1169. ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  1170. ilogConfig.u.logSql.rgchTableName, -1,
  1171. (WCHAR *)cBuffer, MAX_PATH );
  1172. CopyUnicodeStringToBuffer(
  1173. pRpcConfig->rgchTableName,
  1174. MAX_TABLE_NAME_LEN,
  1175. cBuffer);
  1176. ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  1177. ilogConfig.u.logSql.rgchUserName, -1,
  1178. (WCHAR *)cBuffer, MAX_PATH );
  1179. CopyUnicodeStringToBuffer(
  1180. pRpcConfig->rgchUserName,
  1181. UNLEN,
  1182. cBuffer);
  1183. ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  1184. ilogConfig.u.logSql.rgchPassword, -1,
  1185. (WCHAR *)cBuffer, MAX_PATH );
  1186. CopyUnicodeStringToBuffer(
  1187. pRpcConfig->rgchPassword,
  1188. PWLEN,
  1189. cBuffer);
  1190. break;
  1191. case INET_LOG_DISABLED:
  1192. default:
  1193. // do nothing
  1194. break;
  1195. } // switch()
  1196. } else {
  1197. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1198. }
  1199. *ppLogConfig = pRpcConfig;
  1200. return (dwError);
  1201. } // GetRPCLogConfiguration()
  1202. DWORD
  1203. SetInetLogConfiguration(IN LOGGING *pLogging,
  1204. IN EVENT_LOG * pEventLog,
  1205. IN const INET_LOG_CONFIGURATION * pRpcLogConfig)
  1206. /*++
  1207. This function modifies the logconfiguration associated with a given InetLog
  1208. handle. It also updates the registry containing log configuration for service
  1209. with which the inetlog handle is associated.
  1210. Arguments:
  1211. hInetLog Handle to INETLOG object whose configuration needs to be
  1212. changed.
  1213. pRpcLogConfig new RPC log configuration
  1214. Returns:
  1215. Win32 Error code. NO_ERROR returned on success.
  1216. --*/
  1217. {
  1218. DWORD dwError = NO_ERROR;
  1219. INETLOG_CONFIGURATIONA ilConfig;
  1220. WCHAR cBuffer[MAX_PATH];
  1221. //
  1222. // initialize
  1223. //
  1224. ZeroMemory( &ilConfig, sizeof(INETLOG_CONFIGURATIONA));
  1225. // Copy the RPC inet log configuration into local INETLOG_CONFIGURATIONW
  1226. ilConfig.inetLogType = pRpcLogConfig->inetLogType;
  1227. switch (ilConfig.inetLogType) {
  1228. case INET_LOG_DISABLED:
  1229. break; // do nothing
  1230. case INET_LOG_TO_FILE:
  1231. CopyUnicodeStringToBuffer(cBuffer,
  1232. MAX_PATH,
  1233. pRpcLogConfig->rgchLogFileDirectory);
  1234. (VOID) ConvertUnicodeToAnsi(
  1235. cBuffer,
  1236. ilConfig.u.logFile.rgchLogFileDirectory,
  1237. MAX_PATH
  1238. );
  1239. ilConfig.u.logFile.ilPeriod = pRpcLogConfig->ilPeriod;
  1240. if ( ilConfig.u.logFile.ilPeriod > INET_LOG_PERIOD_MONTHLY ) {
  1241. return (ERROR_INVALID_PARAMETER);
  1242. }
  1243. ilConfig.u.logFile.cbSizeForTruncation =
  1244. pRpcLogConfig->cbSizeForTruncation;
  1245. ilConfig.u.logFile.ilFormat =
  1246. *((DWORD *)&(pRpcLogConfig->rgchDataSource[MAX_PATH-sizeof(DWORD)]));
  1247. ilConfig.u.logFile.dwFieldMask =
  1248. *((DWORD *)&(pRpcLogConfig->rgchDataSource[MAX_PATH-2*sizeof(DWORD)]));
  1249. break;
  1250. case INET_LOG_TO_SQL:
  1251. CopyUnicodeStringToBuffer(cBuffer,
  1252. MAX_PATH,
  1253. pRpcLogConfig->rgchDataSource);
  1254. (VOID) ConvertUnicodeToAnsi(
  1255. cBuffer,
  1256. ilConfig.u.logSql.rgchDataSource,
  1257. MAX_PATH);
  1258. CopyUnicodeStringToBuffer(cBuffer,
  1259. MAX_TABLE_NAME_LEN,
  1260. pRpcLogConfig->rgchTableName);
  1261. (VOID) ConvertUnicodeToAnsi(
  1262. cBuffer,
  1263. ilConfig.u.logSql.rgchTableName,
  1264. MAX_PATH);
  1265. CopyUnicodeStringToBuffer(cBuffer,
  1266. UNLEN,
  1267. pRpcLogConfig->rgchUserName);
  1268. (VOID) ConvertUnicodeToAnsi(
  1269. cBuffer,
  1270. ilConfig.u.logSql.rgchUserName,
  1271. MAX_PATH);
  1272. CopyUnicodeStringToBuffer(cBuffer,
  1273. CNLEN,
  1274. pRpcLogConfig->rgchPassword);
  1275. (VOID) ConvertUnicodeToAnsi(
  1276. cBuffer,
  1277. ilConfig.u.logSql.rgchPassword,
  1278. MAX_PATH);
  1279. break;
  1280. default:
  1281. return (ERROR_INVALID_PARAMETER);
  1282. } // switch()
  1283. //
  1284. // Now the ilConfig contains the local data related to configuration.
  1285. // call modify log config to modify dynamically the log handle.
  1286. //
  1287. pLogging->SetConfig( &ilConfig );
  1288. return (dwError);
  1289. } // SetInetLogConfiguration()
  1290. BOOL
  1291. GenerateIpList(
  1292. BOOL fIsGrant,
  1293. ADDRESS_CHECK *pCheck,
  1294. LPINET_INFO_IP_SEC_LIST *ppInfo
  1295. )
  1296. /*++
  1297. Routine Description:
  1298. generate an IP address list from an access check object
  1299. Arguments:
  1300. fIsGrant - TRUE to access grant list, FALSE to access deny list
  1301. pCheck - ptr to address check object to query from
  1302. ppInfo - updated with ptr to IP list if success
  1303. Return:
  1304. TRUE if success, otherwise FALSE
  1305. --*/
  1306. {
  1307. UINT iM = pCheck->GetNbAddr( fIsGrant );
  1308. LPINET_INFO_IP_SEC_LIST pInfo;
  1309. LPINET_INFO_IP_SEC_ENTRY pI;
  1310. UINT x;
  1311. if ( iM == 0 )
  1312. {
  1313. *ppInfo = NULL;
  1314. return TRUE;
  1315. }
  1316. if ( pInfo = (LPINET_INFO_IP_SEC_LIST)MIDL_user_allocate( sizeof(INET_INFO_IP_SEC_LIST) + iM * sizeof(INET_INFO_IP_SEC_ENTRY) ) )
  1317. {
  1318. pInfo->cEntries = 0;
  1319. for ( x = 0, pI = pInfo->aIPSecEntry ;
  1320. x < iM ;
  1321. ++x )
  1322. {
  1323. LPBYTE pM;
  1324. LPBYTE pA;
  1325. DWORD dwF;
  1326. if ( pCheck->GetAddr( fIsGrant, x, &dwF, &pM, &pA ) && dwF == AF_INET )
  1327. {
  1328. pI->dwMask = *(LPDWORD)pM;
  1329. pI->dwNetwork = *(LPDWORD)pA;
  1330. ++pI;
  1331. ++pInfo->cEntries;
  1332. }
  1333. }
  1334. *ppInfo = pInfo;
  1335. return TRUE;
  1336. }
  1337. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  1338. return FALSE;
  1339. }
  1340. BOOL
  1341. FillAddrCheckFromIpList(
  1342. BOOL fIsGrant,
  1343. LPINET_INFO_IP_SEC_LIST pInfo,
  1344. ADDRESS_CHECK *pCheck
  1345. )
  1346. /*++
  1347. Routine Description:
  1348. Fill an access check object from an IP address list from
  1349. Arguments:
  1350. fIsGrant - TRUE to access grant list, FALSE to access deny list
  1351. pInfo - ptr to IP address list
  1352. pCheck - ptr to address check object to update
  1353. Return:
  1354. TRUE if success, otherwise FALSE
  1355. --*/
  1356. {
  1357. UINT x;
  1358. if ( pInfo )
  1359. {
  1360. for ( x = 0 ; x < pInfo->cEntries ; ++x )
  1361. {
  1362. if ( ! pCheck->AddAddr( fIsGrant,
  1363. AF_INET,
  1364. (LPBYTE)&pInfo->aIPSecEntry[x].dwMask,
  1365. (LPBYTE)&pInfo->aIPSecEntry[x].dwNetwork ) )
  1366. {
  1367. return FALSE;
  1368. }
  1369. }
  1370. }
  1371. return TRUE;
  1372. }
  1373. BOOL
  1374. GetVrootCount(
  1375. PVOID pvContext,
  1376. MB * pmb,
  1377. VIRTUAL_ROOT * pvr
  1378. )
  1379. /*++
  1380. Routine Description:
  1381. Virtual directory enumerater callback that calculates the total required
  1382. buffer size
  1383. Arguments:
  1384. pvContext is a dword * that receives the count of virtual directories
  1385. Return:
  1386. TRUE if success, otherwise FALSE
  1387. --*/
  1388. {
  1389. *((DWORD *) pvContext) += 1;
  1390. return TRUE;
  1391. }
  1392. BOOL
  1393. GetVroots(
  1394. PVOID pvContext,
  1395. MB * pmb,
  1396. VIRTUAL_ROOT * pvr
  1397. )
  1398. /*++
  1399. Routine Description:
  1400. Virtual directory enumerater callback that allocates and builds the
  1401. virtual directory structure list
  1402. Arguments:
  1403. pvContext is a pointer to the midl allocated memory
  1404. Return:
  1405. TRUE if success, otherwise FALSE
  1406. --*/
  1407. {
  1408. LPINET_INFO_VIRTUAL_ROOT_LIST pvrl = (LPINET_INFO_VIRTUAL_ROOT_LIST) pvContext;
  1409. DWORD i = pvrl->cEntries;
  1410. LPINET_INFO_VIRTUAL_ROOT_ENTRY pvre = &pvrl->aVirtRootEntry[i];
  1411. //
  1412. // Password doesn't go on the wire
  1413. //
  1414. DBG_ASSERT( pvr->pszAlias[0] == '/' );
  1415. if ( !ConvertStringToRpc( &pvre->pszRoot,
  1416. pvr->pszAlias ) ||
  1417. !ConvertStringToRpc( &pvre->pszDirectory,
  1418. pvr->pszPath ) ||
  1419. !ConvertStringToRpc( &pvre->pszAddress,
  1420. "" ) ||
  1421. !ConvertStringToRpc( &pvre->pszAccountName,
  1422. pvr->pszUserName ))
  1423. {
  1424. FreeRpcString( pvre->pszRoot ); pvre->pszRoot = NULL;
  1425. FreeRpcString( pvre->pszDirectory ); pvre->pszDirectory = NULL;
  1426. FreeRpcString( pvre->pszAddress ); pvre->pszAddress = NULL;
  1427. FreeRpcString( pvre->pszAccountName ); pvre->pszAccountName = NULL;
  1428. return FALSE;
  1429. }
  1430. pvre->dwMask = pvr->dwAccessPerm;
  1431. pmb->GetDword( pvr->pszAlias,
  1432. MD_WIN32_ERROR,
  1433. IIS_MD_UT_SERVER,
  1434. &pvre->dwError );
  1435. pvrl->cEntries++;
  1436. return TRUE;
  1437. }