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.

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