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.

451 lines
13 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ftpinst.hxx
  5. Abstract:
  6. This module defines the FTP_IIS_SERVICE type
  7. Author:
  8. Johnson Apacible (johnsona) 04-Sep-1996
  9. --*/
  10. #ifndef _FTPINST_HXX_
  11. #define _FTPINST_HXX_
  12. #include "iistypes.hxx"
  13. #include "stats.hxx"
  14. #include "type.hxx"
  15. typedef LPUSER_DATA PICLIENT_CONNECTION;
  16. typedef BOOL (*PFN_CLIENT_CONNECTION_ENUM)( PICLIENT_CONNECTION pcc,
  17. LPVOID pContext);
  18. // specifies the size of cache block for padding ==> to avoid false sharing
  19. # define MAX_CACHE_BLOCK_SIZE ( 64)
  20. class FTP_IIS_SERVICE : public IIS_SERVICE {
  21. public:
  22. FTP_IIS_SERVICE(
  23. IN LPCTSTR lpszServiceName,
  24. IN LPCSTR lpszModuleName,
  25. IN LPCSTR lpszRegParamKey,
  26. IN DWORD dwServiceId,
  27. IN ULONGLONG SvcLocId,
  28. IN BOOL MultipleInstanceSupport,
  29. IN DWORD cbAcceptExRecvBuffer,
  30. IN ATQ_CONNECT_CALLBACK pfnConnect,
  31. IN ATQ_COMPLETION pfnConnectEx,
  32. IN ATQ_COMPLETION pfnIoCompletion
  33. )
  34. :IIS_SERVICE(
  35. lpszServiceName,
  36. lpszModuleName,
  37. lpszRegParamKey,
  38. dwServiceId,
  39. SvcLocId,
  40. MultipleInstanceSupport,
  41. cbAcceptExRecvBuffer,
  42. pfnConnect,
  43. pfnConnectEx,
  44. pfnIoCompletion
  45. )
  46. {
  47. InitializeListHead( & m_InstanceList );
  48. INITIALIZE_CRITICAL_SECTION( &m_csInstanceLock);
  49. }
  50. ~FTP_IIS_SERVICE()
  51. {
  52. DeleteCriticalSection( &m_csInstanceLock);
  53. }
  54. VOID LockInstanceList( VOID) { EnterCriticalSection( &m_csInstanceLock); }
  55. VOID UnLockInstanceList( VOID) { LeaveCriticalSection( &m_csInstanceLock); }
  56. virtual DWORD GetServiceConfigInfoSize(IN DWORD dwLevel);
  57. virtual BOOL AddInstanceInfo( IN DWORD dwInstance, IN BOOL fMigrateRoots );
  58. virtual DWORD DisconnectUsersByInstance( IN IIS_SERVER_INSTANCE * pInstance );
  59. BOOL AggregateStatistics(
  60. IN PCHAR pDestination,
  61. IN PCHAR pSource
  62. );
  63. BOOL
  64. GetGlobalStatistics(
  65. IN DWORD dwLevel,
  66. OUT PCHAR *pBuffer
  67. );
  68. LIST_ENTRY m_InstanceList;
  69. CRITICAL_SECTION m_csInstanceLock;
  70. };
  71. typedef FTP_IIS_SERVICE *PFTP_IIS_SERVICE;
  72. //
  73. // This is the FTP version of the instance. Will contain all the
  74. // FTP specific operations.
  75. //
  76. class FTP_SERVER_INSTANCE : public IIS_SERVER_INSTANCE {
  77. public:
  78. FTP_SERVER_INSTANCE(
  79. IN PFTP_IIS_SERVICE pService,
  80. IN DWORD dwInstanceId,
  81. IN USHORT sPort,
  82. IN LPCSTR lpszRegParamKey,
  83. IN LPWSTR lpwszAnonPasswordSecretName,
  84. IN LPWSTR lpwszRootPasswordSecretName,
  85. IN BOOL fMigrateVroots
  86. ) ;
  87. ~FTP_SERVER_INSTANCE();
  88. //
  89. // Instance start & stop
  90. //
  91. virtual DWORD StartInstance();
  92. virtual DWORD StopInstance();
  93. //
  94. // VIRTUALS for service specific params/RPC admin
  95. //
  96. virtual BOOL SetServiceConfig(IN PCHAR pConfig );
  97. virtual BOOL GetServiceConfig(IN OUT PCHAR pConfig,IN DWORD dwLevel);
  98. virtual BOOL GetStatistics( IN DWORD dwLevel, OUT PCHAR *pBuffer);
  99. virtual BOOL ClearStatistics( VOID );
  100. virtual BOOL DisconnectUser( IN DWORD dwIdUser );
  101. virtual BOOL EnumerateUsers( OUT PCHAR* pBuffer, OUT PDWORD nRead );
  102. virtual VOID MDChangeNotify( MD_CHANGE_OBJECT * pco );
  103. BOOL FreeAllocCachedClientConn(VOID);
  104. PICLIENT_CONNECTION AllocClientConnFromAllocCache(VOID);
  105. VOID FreeClientConnToAllocCache(IN PICLIENT_CONNECTION pClient);
  106. //
  107. // Initialize the configuration data from registry information
  108. //
  109. // Arguments
  110. // hkeyReg key to the registry entry for parameters
  111. // FieldsToRead bitmapped flags indicating which data to be read.
  112. //
  113. // Returns:
  114. // NO_ERROR on success
  115. // Win32 error code otherwise
  116. //
  117. DWORD InitFromRegistry( IN FIELD_CONTROL FieldsToRead);
  118. DWORD
  119. ReadAuthentInfo(
  120. IN BOOL ReadAll = TRUE,
  121. IN DWORD SingleItemToRead = 0
  122. );
  123. DWORD
  124. GetConfigInformation( OUT LPFTP_CONFIG_INFO pConfigInfo);
  125. DWORD
  126. SetConfigInformation( IN LPFTP_CONFIG_INFO pConfigInfo);
  127. BOOL IsValid( VOID) const { return ( m_fValid); }
  128. VOID LockConfig( VOID) { EnterCriticalSection( &m_csLock); }
  129. VOID UnLockConfig( VOID) { LeaveCriticalSection( &m_csLock); }
  130. VOID LockConnectionsList()
  131. { EnterCriticalSection(&m_csConnectionsList); }
  132. VOID UnlockConnectionsList()
  133. { LeaveCriticalSection(&m_csConnectionsList); }
  134. DWORD GetCurrentConnectionsCount( VOID) const
  135. { return m_cCurrentConnections; }
  136. DWORD GetMaxCurrentConnectionsCount( VOID) const
  137. { return m_cMaxCurrentConnections; }
  138. DWORD SetLocalHostName(IN LPCSTR pszHost);
  139. LPCSTR QueryLocalHostName(VOID) const { return (m_pszLocalHostName); }
  140. DWORD QueryUserFlags(VOID) const { return (m_dwUserFlags); }
  141. BOOL QueryLowercaseFiles(VOID) const { return (m_fLowercaseFiles); }
  142. BOOL AllowAnonymous(VOID) const { return (m_fAllowAnonymous); }
  143. BOOL AllowGuestAccess(VOID) const { return (m_fAllowGuestAccess); }
  144. BOOL IsAllowedUser(IN BOOL fAnonymous)
  145. {
  146. return ((fAnonymous && m_fAllowAnonymous) ||
  147. (!fAnonymous && !m_fAllowAnonymous) ||
  148. (!fAnonymous && !m_fAnonymousOnly));
  149. }
  150. BOOL IsEnableDataConnTo3rdIP(VOID) const { return (m_fEnableDataConnTo3rdIP); }
  151. BOOL IsEnablePasvConnFrom3rdIP(VOID) const { return (m_fEnablePasvConnFrom3rdIP); };
  152. DWORD NumListenBacklog(VOID) const { return (m_ListenBacklog); }
  153. // Following functions return pointers to strings which should be used
  154. // within locked sections of config
  155. // Marked by LockConfig() and UnLockConfig()
  156. LPCSTR QueryMaxClientsMsg(VOID) const
  157. { return (LPCSTR)m_MaxClientsMessage.QueryStr(); }
  158. LPCSTR QueryGreetingMsg(VOID) const
  159. { return (LPCSTR)m_GreetingMessage.QueryStr(); }
  160. LPCSTR QueryBannerMsg(VOID) const
  161. { return (LPCSTR)m_BannerMessage.QueryStr(); }
  162. LPCSTR QueryExitMsg(VOID) const
  163. { return (LPCSTR)m_ExitMessage.QueryStr(); }
  164. BOOL EnumerateConnection( IN PFN_CLIENT_CONNECTION_ENUM pfnConnEnum,
  165. IN LPVOID pContext,
  166. IN DWORD dwConnectionId);
  167. VOID DisconnectAllConnections( VOID);
  168. PICLIENT_CONNECTION
  169. AllocNewConnection();
  170. VOID RemoveConnection( IN OUT PICLIENT_CONNECTION pcc);
  171. BOOL WriteParamsToRegistry( LPFTP_CONFIG_INFO pConfig );
  172. VOID Print( VOID) const;
  173. METADATA_REF_HANDLER* QueryMetaDataRefHandler() { return &m_rfAccessCheck; }
  174. PTCP_AUTHENT_INFO QueryAuthentInfo() { return &m_TcpAuthentInfo; }
  175. PUSER_AUTHENT_INFO QueryADConnAuthentInfo() { return &m_ADConnAuthentInfo; }
  176. BOOL AllowReplaceOnRename( VOID ) const {
  177. return m_fAllowReplaceOnRename;
  178. }
  179. LPFTP_SERVER_STATISTICS QueryStatsObj( VOID ) { return m_pFTPStats; }
  180. DWORD QueryIsolationMode( VOID ) const {
  181. return m_UserIsolationMode;
  182. }
  183. LPAD_IO QueryAdIo( VOID ) const {
  184. return m_pAdIo;
  185. }
  186. inline DWORD QueryAnonymousHomeDir( STR & strTargetPath) {
  187. return m_pAdIo ?
  188. m_pAdIo->GetAnonymHomeDir( strTargetPath ) :
  189. ERROR_BAD_CONFIGURATION;
  190. }
  191. inline DWORD QueryUserHomeDir(
  192. const STR & strUser,
  193. const STR & strDomain,
  194. STR * pstrTarget,
  195. ADIO_ASYNC ** ppadioReqCtx,
  196. tpAdioAsyncCallback pfnCallback,
  197. HANDLE hCLientCtx) {
  198. return m_pAdIo ?
  199. m_pAdIo->GetUserHomeDir(
  200. strUser,
  201. strDomain,
  202. pstrTarget,
  203. ppadioReqCtx,
  204. pfnCallback,
  205. hCLientCtx) :
  206. ERROR_BAD_CONFIGURATION;
  207. }
  208. private:
  209. DWORD SetAdIoInfo( VOID );
  210. //
  211. // Connections related data
  212. //
  213. // m_cMaxConnections: max connections permitted by config
  214. // m_cCurrentConnections: count of currently connected users
  215. // m_cMaxCurrentConnections: max connections seen in this session
  216. // Always m_cCurrentConnections
  217. // <= m_cMaxCurrentConnections
  218. // <= m_cMaxConnections;
  219. //
  220. // DWORD m_cMaxConnections;
  221. // replaced by TSVC_INFO::QueryMaxConnections()
  222. DWORD m_cCurrentConnections;
  223. DWORD m_cMaxCurrentConnections;
  224. BOOL m_fAllowAnonymous;
  225. BOOL m_fAllowGuestAccess;
  226. BOOL m_fAnnotateDirectories; // annotate dirs when dir changes
  227. BOOL m_fAnonymousOnly;
  228. BOOL m_fEnableDataConnTo3rdIP;
  229. BOOL m_fEnablePasvConnFrom3rdIP;
  230. // if m_LowercaseFiles is TRUE, then dir listings from non-case-preserving
  231. // filesystems will be mapped to lowercase.
  232. BOOL m_fLowercaseFiles;
  233. BOOL m_fMsdosDirOutput; // send msdos style dir listings
  234. BOOL m_fFourDigitYear; // send 4 digit year dir listings
  235. STR m_ExitMessage;
  236. STR m_MaxClientsMessage;
  237. TCP_AUTHENT_INFO m_TcpAuthentInfo;
  238. USER_AUTHENT_INFO m_ADConnAuthentInfo;
  239. //
  240. // Greeting Message can be a multiline message.
  241. // We maintain two copies of the message
  242. // 1) double null terminated seq. of strings with one line per string
  243. // 2) single null terminated string with \n characters interspersed.
  244. //
  245. // Representation 1 is used for sending data to clients
  246. // Representation 2 is used for RPC admin facility
  247. // We maintain the string as MULTI_SZ in the registry
  248. //
  249. MULTISZ m_GreetingMessage;
  250. LPTSTR m_pszGreetingMessageWithLineFeed;
  251. //
  252. // Same as for the greeting message, the banner could be multiline too.
  253. // Same handling.
  254. //
  255. MULTISZ m_BannerMessage;
  256. LPTSTR m_pszBannerMessageWithLineFeed;
  257. BOOL m_fEnableLicensing;
  258. DWORD m_ListenBacklog;
  259. CHAR * m_pszLocalHostName; // this machine name running ftp service
  260. DWORD m_dwUserFlags; // user flags established at start of conn
  261. //
  262. // For FTP server configuration information
  263. //
  264. //
  265. // TODO: merge configuration and instance object together
  266. //
  267. // LPFTP_SERVER_CONFIG m_pFtpServerConfig;
  268. HKEY m_hkeyParams;
  269. //
  270. // Other data related to configuration load and store
  271. //
  272. BOOL m_fValid;
  273. CRITICAL_SECTION m_csLock; // used for updating this object
  274. CHAR m_rgchCacheBlock[MAX_CACHE_BLOCK_SIZE]; // to avoid false sharing
  275. // we should avoid cache block conflict
  276. // Following set of data constitute the dynamic data for connections
  277. // ==> it will be good if they are closeby, within one cache block.
  278. CRITICAL_SECTION m_csConnectionsList;
  279. LIST_ENTRY m_ActiveConnectionsList; // list of all active connections
  280. LIST_ENTRY m_FreeConnectionsList; // free list for connection objects
  281. METADATA_REF_HANDLER m_rfAccessCheck;
  282. LPFTP_SERVER_STATISTICS m_pFTPStats;
  283. BOOL m_fAllowReplaceOnRename;
  284. DWORD m_UserIsolationMode;
  285. BOOL m_fLogInUtf8;
  286. LPAD_IO m_pAdIo;
  287. };
  288. typedef FTP_SERVER_INSTANCE *PFTP_SERVER_INSTANCE;
  289. //
  290. // Class for managing port range allocations
  291. //
  292. class FTP_PASV_PORT
  293. {
  294. public:
  295. FTP_PASV_PORT()
  296. {
  297. m_dwRemainingRetries =
  298. m_dwNextPasvPort == 0 ? 0 : m_dwPasvPortRangeEnd - m_dwPasvPortRangeStart + 1;
  299. }
  300. ~FTP_PASV_PORT() {}
  301. static VOID Init()
  302. {
  303. INITIALIZE_CRITICAL_SECTION( &m_csPasvPortRange);
  304. }
  305. static VOID Terminate()
  306. {
  307. DeleteCriticalSection( &m_csPasvPortRange);
  308. }
  309. static BOOL Configure();
  310. PORT GetPort()
  311. {
  312. LONG Port = 0;
  313. if (m_dwRemainingRetries > 0)
  314. {
  315. m_dwRemainingRetries--;
  316. EnterCriticalSection(&m_csPasvPortRange);
  317. Port = m_dwNextPasvPort;
  318. if (++m_dwNextPasvPort > m_dwPasvPortRangeEnd) {
  319. m_dwNextPasvPort = m_dwPasvPortRangeStart;
  320. }
  321. LeaveCriticalSection(&m_csPasvPortRange);
  322. }
  323. return (PORT)Port;
  324. }
  325. private:
  326. static CRITICAL_SECTION m_csPasvPortRange;
  327. static PORT m_dwPasvPortRangeStart; // configured range start
  328. static PORT m_dwPasvPortRangeEnd; // configured range end
  329. static LONG m_dwNextPasvPort; // next port to allocate
  330. DWORD m_dwRemainingRetries;
  331. };
  332. #endif // _FTPINST_HXX_