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.

546 lines
13 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <winsock2.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <time.h>
  9. #include <lm.h>
  10. #include <inetcom.h>
  11. #include <iisinfo.h>
  12. #include <lmapibuf.h>
  13. /*****************************************************************************
  14. globals
  15. *****************************************************************************/
  16. UINT _cchNumberPadding;
  17. /*****************************************************************************
  18. prototypes
  19. *****************************************************************************/
  20. INT __cdecl main( INT cArgs,
  21. char * pArgs[] );
  22. VOID Usage();
  23. VOID DoEnum( WCHAR * pszServer );
  24. VOID DoQuery( WCHAR * pszServer );
  25. VOID DoSet( WCHAR * pszServer,
  26. CHAR * pszPassword );
  27. VOID DoNuke( WCHAR * pszServer,
  28. CHAR * pszUserId );
  29. VOID DoStats( WCHAR * pszServer );
  30. VOID DoClear( WCHAR * pszServer );
  31. CHAR * MakeCommaString( CHAR * pszNumber );
  32. CHAR * MakeCommaNumber( DWORD dwNumber );
  33. /*****************************************************************************
  34. main
  35. *****************************************************************************/
  36. INT __cdecl main( INT cArgs,
  37. char * pArgs[] )
  38. {
  39. WCHAR szServer[MAX_PATH];
  40. WCHAR * pszServer = NULL;
  41. INT iArg;
  42. if( cArgs < 2 )
  43. {
  44. Usage();
  45. return 1;
  46. }
  47. iArg = 1;
  48. if( *pArgs[iArg] == '\\' )
  49. {
  50. wsprintfW( szServer, L"%S", pArgs[iArg++] );
  51. pszServer = szServer;
  52. cArgs--;
  53. }
  54. if( _stricmp( pArgs[iArg], "stats" ) == 0 )
  55. {
  56. if( cArgs != 2 )
  57. {
  58. printf( "use: ftpt stats\n" );
  59. return 1;
  60. }
  61. DoStats( pszServer );
  62. }
  63. else
  64. if( _stricmp( pArgs[iArg], "clear" ) == 0 )
  65. {
  66. if( cArgs != 2 )
  67. {
  68. printf( "use: ftpt clear\n" );
  69. return 1;
  70. }
  71. DoClear( pszServer );
  72. }
  73. else
  74. if( _stricmp( pArgs[iArg], "enum" ) == 0 )
  75. {
  76. if( cArgs != 2 )
  77. {
  78. printf( "use: ftpt enum\n" );
  79. return 1;
  80. }
  81. DoEnum( pszServer );
  82. }
  83. else
  84. if( _stricmp( pArgs[iArg], "query" ) == 0 )
  85. {
  86. if( cArgs != 2 )
  87. {
  88. printf( "use: ftpt query\n" );
  89. return 1;
  90. }
  91. DoQuery( pszServer );
  92. }
  93. else
  94. if( _stricmp( pArgs[iArg], "set" ) == 0 )
  95. {
  96. CHAR * pszPassword;
  97. if ( cArgs == 3 )
  98. {
  99. pszPassword = pArgs[++iArg];
  100. }
  101. else
  102. pszPassword = NULL;
  103. DoSet( pszServer,
  104. pszPassword );
  105. }
  106. else
  107. if( _stricmp( pArgs[iArg], "nuke" ) == 0 )
  108. {
  109. CHAR * pszUserId;
  110. if( cArgs != 3 )
  111. {
  112. printf( "use: ftpt nuke user_id\n" );
  113. return 1;
  114. }
  115. pszUserId = pArgs[++iArg];
  116. DoNuke( pszServer,
  117. pszUserId );
  118. }
  119. else
  120. {
  121. Usage();
  122. return 1;
  123. }
  124. return 0;
  125. } // main
  126. /*****************************************************************************
  127. Usage
  128. *****************************************************************************/
  129. VOID Usage( VOID )
  130. {
  131. printf( "use: ftpt [\\\\server] command [options]\n" );
  132. printf( "Valid commands are:\n" );
  133. printf( " enum - Enumerates connected users.\n" );
  134. printf( " query - Queries volume security masks.\n" );
  135. printf( " set [Catapult user password] - Sets admin info.\n" );
  136. printf( " nuke - Disconnect a user.\n" );
  137. printf( " stats - Display server statistics.\n" );
  138. printf( " clear - Clear server statistics.\n" );
  139. } // Usage
  140. /*****************************************************************************
  141. DoEnum
  142. *****************************************************************************/
  143. VOID DoEnum( WCHAR * pszServer )
  144. {
  145. NET_API_STATUS err;
  146. LPIIS_USER_INFO_1 pUserInfo;
  147. DWORD cEntries;
  148. printf( "Invoking FtpEnumerateUsers..." );
  149. err = IISEnumerateUsers(
  150. pszServer,
  151. 1,
  152. INET_FTP_SVC_ID,
  153. 1,
  154. &cEntries,
  155. (LPBYTE*)&pUserInfo );
  156. if( err != NERR_Success )
  157. {
  158. printf( "ERROR %lu (%08lX)\n", err, err );
  159. }
  160. else
  161. {
  162. printf( "done\n" );
  163. printf( "read %lu connected users\n", cEntries );
  164. while( cEntries-- )
  165. {
  166. IN_ADDR addr;
  167. addr.s_addr = (u_long)pUserInfo->inetHost;
  168. printf( "idUser = %lu\n", pUserInfo->idUser );
  169. printf( "pszUser = %S\n", pUserInfo->pszUser );
  170. printf( "fAnonymous = %lu\n", pUserInfo->fAnonymous );
  171. printf( "inetHost = %s\n", inet_ntoa( addr ) );
  172. printf( "tConnect = %lu\n", pUserInfo->tConnect );
  173. printf( "\n" );
  174. pUserInfo++;
  175. }
  176. }
  177. } // DoEnum
  178. /*****************************************************************************
  179. DoQuery
  180. *****************************************************************************/
  181. VOID DoQuery( WCHAR * pszServer )
  182. {
  183. NET_API_STATUS err;
  184. LPFTP_CONFIG_INFO_1 pConfig;
  185. DWORD i;
  186. printf( "Invoking FtpGetAdminInformation..." );
  187. err = FtpGetAdminInformation2(
  188. pszServer,
  189. 1,
  190. 1,
  191. (LPBYTE*)&pConfig
  192. );
  193. if( err != NERR_Success )
  194. {
  195. printf( "ERROR %lu (%08lX)\n", err, err );
  196. return;
  197. }
  198. printf("fAllowAnonymous = %d\n", pConfig->fAllowAnonymous );
  199. printf("fAllowGuestAccess = %d\n", pConfig->fAllowGuestAccess );
  200. printf("fAnnotateDirectories = %d\n", pConfig->fAnnotateDirectories );
  201. printf("fAnonymous only = %d\n", pConfig->fAnonymousOnly );
  202. printf("lpszExitMessage = %S\n", pConfig->lpszExitMessage );
  203. printf("lpszGreetingMessage = %S\n", pConfig->lpszGreetingMessage );
  204. printf("lpszHomeDirectory = %S\n", pConfig->lpszHomeDirectory );
  205. printf("lpszMaxClientsMessage = %S\n", pConfig->lpszMaxClientsMessage );
  206. printf("dwListenBacklog = %d\n", pConfig->dwListenBacklog );
  207. printf("fLowerCaseFiles = %d\n", pConfig->fLowercaseFiles );
  208. printf("fMsdosDirOutput = %d\n", pConfig->fMsdosDirOutput );
  209. } // DoQuery
  210. /*****************************************************************************
  211. DoSet
  212. *****************************************************************************/
  213. VOID DoSet( WCHAR * pszServer, CHAR * pszPassword )
  214. {
  215. NET_API_STATUS err;
  216. FTP_CONFIG_INFO_1 * pConfig;
  217. WCHAR achPassword[PWLEN+1];
  218. printf( "Invoking FtpGetAdminInformation..." );
  219. err = FtpGetAdminInformation2(
  220. pszServer,
  221. 1,
  222. 1,
  223. (LPBYTE*)&pConfig );
  224. if( err != NERR_Success )
  225. {
  226. printf( "ERROR %lu (%08lX)\n", err, err );
  227. return;
  228. }
  229. printf( "Invoking FtpSetAdminInformation..." );
  230. err = FtpSetAdminInformation2(
  231. pszServer,
  232. 1,
  233. 1,
  234. (LPBYTE)pConfig
  235. );
  236. if( err != NERR_Success )
  237. {
  238. printf( "ERROR %lu (%08lX)\n", err, err );
  239. return;
  240. }
  241. printf( "done!\n" );
  242. NetApiBufferFree( pConfig );
  243. } // DoSet
  244. /*****************************************************************************
  245. DoNuke
  246. *****************************************************************************/
  247. VOID DoNuke( WCHAR * pszServer,
  248. CHAR * pszUserId )
  249. {
  250. NET_API_STATUS err;
  251. DWORD idUser;
  252. idUser = (DWORD)strtoul( pszUserId, NULL, 0 );
  253. printf( "Invoking FtpDisconnectUser..." );
  254. err = IISDisconnectUser(
  255. pszServer,
  256. INET_FTP_SVC_ID,
  257. 1,
  258. idUser
  259. );
  260. if( err != NERR_Success )
  261. {
  262. printf( "ERROR %lu (%08lX)\n", err, err );
  263. }
  264. else
  265. {
  266. printf( "done\n" );
  267. }
  268. } // DoNuke
  269. /*****************************************************************************
  270. DoStats
  271. *****************************************************************************/
  272. VOID DoStats( WCHAR * pszServer )
  273. {
  274. NET_API_STATUS err;
  275. FTP_STATISTICS_0 * pstats;
  276. printf( "Invoking FtpQueryStatistics..." );
  277. err = FtpQueryStatistics2( pszServer,
  278. 0,
  279. INET_INSTANCE_GLOBAL,
  280. 0,
  281. (LPBYTE *)&pstats
  282. );
  283. if( err != NERR_Success )
  284. {
  285. printf( "ERROR %lu (%08lX)\n", err, err );
  286. }
  287. else
  288. {
  289. CHAR szLargeInt[64];
  290. printf( "done\n" );
  291. _cchNumberPadding = 13;
  292. if( ( pstats->TotalBytesSent.HighPart != 0 ) ||
  293. ( pstats->TotalBytesReceived.HighPart != 0 ) )
  294. {
  295. _cchNumberPadding = 26;
  296. }
  297. RtlLargeIntegerToChar( &pstats->TotalBytesSent,
  298. 10,
  299. sizeof(szLargeInt),
  300. szLargeInt );
  301. printf( "TotalBytesSent = %s\n",
  302. MakeCommaString( szLargeInt ) );
  303. RtlLargeIntegerToChar( &pstats->TotalBytesReceived,
  304. 10,
  305. sizeof(szLargeInt),
  306. szLargeInt );
  307. printf( "TotalBytesReceived = %s\n",
  308. MakeCommaString( szLargeInt ) );
  309. printf( "TotalFilesSent = %s\n",
  310. MakeCommaNumber( pstats->TotalFilesSent ) );
  311. printf( "TotalFilesReceived = %s\n",
  312. MakeCommaNumber( pstats->TotalFilesReceived ) );
  313. printf( "CurrentAnonymousUsers = %s\n",
  314. MakeCommaNumber( pstats->CurrentAnonymousUsers ) );
  315. printf( "CurrentNonAnonymousUsers = %s\n",
  316. MakeCommaNumber( pstats->CurrentNonAnonymousUsers ) );
  317. printf( "TotalAnonymousUsers = %s\n",
  318. MakeCommaNumber( pstats->TotalAnonymousUsers ) );
  319. printf( "TotalNonAnonymousUsers = %s\n",
  320. MakeCommaNumber( pstats->TotalNonAnonymousUsers ) );
  321. printf( "MaxAnonymousUsers = %s\n",
  322. MakeCommaNumber( pstats->MaxAnonymousUsers ) );
  323. printf( "MaxNonAnonymousUsers = %s\n",
  324. MakeCommaNumber( pstats->MaxNonAnonymousUsers ) );
  325. printf( "CurrentConnections = %s\n",
  326. MakeCommaNumber( pstats->CurrentConnections ) );
  327. printf( "MaxConnections = %s\n",
  328. MakeCommaNumber( pstats->MaxConnections ) );
  329. printf( "ConnectionAttempts = %s\n",
  330. MakeCommaNumber( pstats->ConnectionAttempts ) );
  331. printf( "LogonAttempts = %s\n",
  332. MakeCommaNumber( pstats->LogonAttempts ) );
  333. printf( "TimeOfLastClear = %s\n",
  334. asctime( localtime( (time_t *)&pstats->TimeOfLastClear ) ) );
  335. }
  336. } // DoStats
  337. /*****************************************************************************
  338. DoClear
  339. *****************************************************************************/
  340. VOID DoClear( WCHAR * pszServer )
  341. {
  342. NET_API_STATUS err;
  343. printf( "Invoking FtpClearStatistics..." );
  344. err = FtpClearStatistics2( pszServer, 0 );
  345. if( err != NERR_Success )
  346. {
  347. printf( "ERROR %lu (%08lX)\n", err, err );
  348. }
  349. else
  350. {
  351. printf( "done\n" );
  352. }
  353. } // DoClear
  354. /*****************************************************************************
  355. MakeCommaString
  356. *****************************************************************************/
  357. CHAR * MakeCommaString( CHAR * pszNumber )
  358. {
  359. static CHAR szBuffer[26];
  360. CHAR * psz;
  361. UINT cchNumber;
  362. UINT cchNextComma;
  363. cchNumber = strlen( pszNumber );
  364. pszNumber += cchNumber - 1;
  365. psz = szBuffer + _cchNumberPadding;
  366. *psz-- = '\0';
  367. cchNextComma = 3;
  368. while( cchNumber-- )
  369. {
  370. if( cchNextComma-- == 0 )
  371. {
  372. *psz-- = ',';
  373. cchNextComma = 2;
  374. }
  375. *psz-- = *pszNumber--;
  376. }
  377. while( psz >= szBuffer )
  378. {
  379. *psz-- = ' ';
  380. }
  381. return szBuffer;
  382. } // MakeCommaString
  383. /*****************************************************************************
  384. MakeCommaNumber
  385. *****************************************************************************/
  386. CHAR * MakeCommaNumber( DWORD dwNumber )
  387. {
  388. CHAR szBuffer[32];
  389. wsprintf( szBuffer, "%lu", dwNumber );
  390. return MakeCommaString( szBuffer );
  391. } // MakeCommaNumber