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.

1634 lines
42 KiB

  1. /*--
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. ssptest.c
  5. Abstract:
  6. Test program for the NtLmSsp service.
  7. Author:
  8. 28-Jun-1993 (cliffv)
  9. Environment:
  10. User mode only.
  11. Contains NT-specific code.
  12. Requires ANSI C extensions: slash-slash comments, long external names.
  13. Revision History:
  14. --*/
  15. //
  16. // Common include files.
  17. //
  18. #define UNICODE 1
  19. #define SECURITY_WIN32 1
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <windef.h>
  24. #include <winbase.h>
  25. #include <winsvc.h> // Needed for service controller APIs
  26. #include <wincred.h>
  27. #include <credp.h>
  28. #include <lmcons.h>
  29. #include <lmerr.h>
  30. #include <lmsname.h>
  31. #include <rpc.h>
  32. #include <stdio.h> // printf
  33. #include <stdlib.h> // strtoul
  34. #include <tstring.h> // NetpAllocWStrFromWStr
  35. #include <security.h> // General definition of a Security Support Provider
  36. #include <ntmsv1_0.h>
  37. // #include <ntlmsspd.h> // Common definitions between client and server
  38. // #include <ntlmssp.h> // External definition of the NtLmSsp service
  39. // #include <ntlmcomn.h>
  40. BOOLEAN QuietMode = FALSE; // Don't be verbose
  41. VOID
  42. DumpBuffer(
  43. PVOID Buffer,
  44. DWORD BufferSize
  45. )
  46. /*++
  47. Routine Description:
  48. Dumps the buffer content on to the debugger output.
  49. Arguments:
  50. Buffer: buffer pointer.
  51. BufferSize: size of the buffer.
  52. Return Value:
  53. none
  54. --*/
  55. {
  56. #define NUM_CHARS 16
  57. DWORD i, limit;
  58. CHAR TextBuffer[NUM_CHARS + 1];
  59. LPBYTE BufferPtr = Buffer;
  60. printf("------------------------------------\n");
  61. //
  62. // Hex dump of the bytes
  63. //
  64. limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
  65. for (i = 0; i < limit; i++) {
  66. if (i < BufferSize) {
  67. printf("%02x ", BufferPtr[i]);
  68. if (BufferPtr[i] < 31 ) {
  69. TextBuffer[i % NUM_CHARS] = '.';
  70. } else if (BufferPtr[i] == '\0') {
  71. TextBuffer[i % NUM_CHARS] = ' ';
  72. } else {
  73. TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i];
  74. }
  75. } else {
  76. printf(" ");
  77. TextBuffer[i % NUM_CHARS] = ' ';
  78. }
  79. if ((i + 1) % NUM_CHARS == 0) {
  80. TextBuffer[NUM_CHARS] = 0;
  81. printf(" %s\n", TextBuffer);
  82. }
  83. }
  84. printf("------------------------------------\n");
  85. }
  86. VOID
  87. PrintTime(
  88. LPSTR Comment,
  89. TimeStamp ConvertTime
  90. )
  91. /*++
  92. Routine Description:
  93. Print the specified time
  94. Arguments:
  95. Comment - Comment to print in front of the time
  96. Time - Local time to print
  97. Return Value:
  98. None
  99. --*/
  100. {
  101. LARGE_INTEGER LocalTime;
  102. LocalTime.HighPart = ConvertTime.HighPart;
  103. LocalTime.LowPart = ConvertTime.LowPart;
  104. printf( "%s", Comment );
  105. //
  106. // If the time is infinite,
  107. // just say so.
  108. //
  109. if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
  110. printf( "Infinite\n" );
  111. //
  112. // Otherwise print it more clearly
  113. //
  114. } else {
  115. TIME_FIELDS TimeFields;
  116. RtlTimeToTimeFields( &LocalTime, &TimeFields );
  117. printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
  118. TimeFields.Month,
  119. TimeFields.Day,
  120. TimeFields.Year,
  121. TimeFields.Hour,
  122. TimeFields.Minute,
  123. TimeFields.Second );
  124. }
  125. }
  126. VOID
  127. PrintStatus(
  128. NET_API_STATUS NetStatus
  129. )
  130. /*++
  131. Routine Description:
  132. Print a net status code.
  133. Arguments:
  134. NetStatus - The net status code to print.
  135. Return Value:
  136. None
  137. --*/
  138. {
  139. printf( "Status = %lu 0x%lx", NetStatus, NetStatus );
  140. switch (NetStatus) {
  141. case NERR_Success:
  142. printf( " NERR_Success" );
  143. break;
  144. case NERR_DCNotFound:
  145. printf( " NERR_DCNotFound" );
  146. break;
  147. case ERROR_LOGON_FAILURE:
  148. printf( " ERROR_LOGON_FAILURE" );
  149. break;
  150. case ERROR_ACCESS_DENIED:
  151. printf( " ERROR_ACCESS_DENIED" );
  152. break;
  153. case ERROR_NOT_SUPPORTED:
  154. printf( " ERROR_NOT_SUPPORTED" );
  155. break;
  156. case ERROR_NO_LOGON_SERVERS:
  157. printf( " ERROR_NO_LOGON_SERVERS" );
  158. break;
  159. case ERROR_NO_SUCH_DOMAIN:
  160. printf( " ERROR_NO_SUCH_DOMAIN" );
  161. break;
  162. case ERROR_NO_TRUST_LSA_SECRET:
  163. printf( " ERROR_NO_TRUST_LSA_SECRET" );
  164. break;
  165. case ERROR_NO_TRUST_SAM_ACCOUNT:
  166. printf( " ERROR_NO_TRUST_SAM_ACCOUNT" );
  167. break;
  168. case ERROR_DOMAIN_TRUST_INCONSISTENT:
  169. printf( " ERROR_DOMAIN_TRUST_INCONSISTENT" );
  170. break;
  171. case ERROR_BAD_NETPATH:
  172. printf( " ERROR_BAD_NETPATH" );
  173. break;
  174. case ERROR_FILE_NOT_FOUND:
  175. printf( " ERROR_FILE_NOT_FOUND" );
  176. break;
  177. case NERR_NetNotStarted:
  178. printf( " NERR_NetNotStarted" );
  179. break;
  180. case NERR_WkstaNotStarted:
  181. printf( " NERR_WkstaNotStarted" );
  182. break;
  183. case NERR_ServerNotStarted:
  184. printf( " NERR_ServerNotStarted" );
  185. break;
  186. case NERR_BrowserNotStarted:
  187. printf( " NERR_BrowserNotStarted" );
  188. break;
  189. case NERR_ServiceNotInstalled:
  190. printf( " NERR_ServiceNotInstalled" );
  191. break;
  192. case NERR_BadTransactConfig:
  193. printf( " NERR_BadTransactConfig" );
  194. break;
  195. case SEC_E_NO_SPM:
  196. printf( " SEC_E_NO_SPM" );
  197. break;
  198. case SEC_E_BAD_PKGID:
  199. printf( " SEC_E_BAD_PKGID" ); break;
  200. case SEC_E_NOT_OWNER:
  201. printf( " SEC_E_NOT_OWNER" ); break;
  202. case SEC_E_CANNOT_INSTALL:
  203. printf( " SEC_E_CANNOT_INSTALL" ); break;
  204. case SEC_E_INVALID_TOKEN:
  205. printf( " SEC_E_INVALID_TOKEN" ); break;
  206. case SEC_E_CANNOT_PACK:
  207. printf( " SEC_E_CANNOT_PACK" ); break;
  208. case SEC_E_QOP_NOT_SUPPORTED:
  209. printf( " SEC_E_QOP_NOT_SUPPORTED" ); break;
  210. case SEC_E_NO_IMPERSONATION:
  211. printf( " SEC_E_NO_IMPERSONATION" ); break;
  212. case SEC_E_LOGON_DENIED:
  213. printf( " SEC_E_LOGON_DENIED" ); break;
  214. case SEC_E_UNKNOWN_CREDENTIALS:
  215. printf( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
  216. case SEC_E_NO_CREDENTIALS:
  217. printf( " SEC_E_NO_CREDENTIALS" ); break;
  218. case SEC_E_MESSAGE_ALTERED:
  219. printf( " SEC_E_MESSAGE_ALTERED" ); break;
  220. case SEC_E_OUT_OF_SEQUENCE:
  221. printf( " SEC_E_OUT_OF_SEQUENCE" ); break;
  222. case SEC_E_INSUFFICIENT_MEMORY:
  223. printf( " SEC_E_INSUFFICIENT_MEMORY" ); break;
  224. case SEC_E_INVALID_HANDLE:
  225. printf( " SEC_E_INVALID_HANDLE" ); break;
  226. case SEC_E_NOT_SUPPORTED:
  227. printf( " SEC_E_NOT_SUPPORTED" ); break;
  228. }
  229. printf( "\n" );
  230. }
  231. //
  232. // Entries in this list must have offsets that match the corresponding values
  233. // of the CRED_TYPE_* defines in wincred.h
  234. //
  235. LPWSTR TypeArray[] = {
  236. L"Generic",
  237. L"Password",
  238. L"Certificate",
  239. NULL
  240. };
  241. #define TYPE_COUNT (sizeof(TypeArray)/sizeof(TypeArray[0]))
  242. VOID
  243. PrintTargetInfo(
  244. PCREDENTIAL_TARGET_INFORMATION TargetInformation
  245. )
  246. /*++
  247. Routine Description:
  248. Print a Target Info
  249. Arguments:
  250. TargetInfo to print
  251. Return Value:
  252. None
  253. --*/
  254. {
  255. ULONG i;
  256. printf( "TargetInformation:\n" );
  257. if ( TargetInformation->TargetName != NULL ) {
  258. printf( " TargetName: %ls\n", TargetInformation->TargetName );
  259. }
  260. if ( TargetInformation->NetbiosServerName != NULL ) {
  261. printf( " NetbiosServerName: %ls\n", TargetInformation->NetbiosServerName );
  262. }
  263. if ( TargetInformation->DnsServerName != NULL ) {
  264. printf( " DnsServerName: %ls\n", TargetInformation->DnsServerName );
  265. }
  266. if ( TargetInformation->NetbiosDomainName != NULL ) {
  267. printf( " NetbiosDomainName: %ls\n", TargetInformation->NetbiosDomainName );
  268. }
  269. if ( TargetInformation->DnsDomainName != NULL ) {
  270. printf( " DnsDomainName: %ls\n", TargetInformation->DnsDomainName );
  271. }
  272. if ( TargetInformation->DnsTreeName != NULL ) {
  273. printf( " DnsTreeName: %ls\n", TargetInformation->DnsTreeName );
  274. }
  275. if ( TargetInformation->PackageName != NULL ) {
  276. printf( " PackageName: %ls\n", TargetInformation->PackageName );
  277. }
  278. if ( TargetInformation->Flags != 0 ) {
  279. DWORD LocalFlags = TargetInformation->Flags;
  280. printf( " Flags:" );
  281. if ( LocalFlags & CRED_TI_SERVER_FORMAT_UNKNOWN ) {
  282. printf(" ServerFormatUnknown");
  283. LocalFlags &= ~CRED_TI_SERVER_FORMAT_UNKNOWN;
  284. }
  285. if ( LocalFlags & CRED_TI_DOMAIN_FORMAT_UNKNOWN ) {
  286. printf(" DomainFormatUnknown");
  287. LocalFlags &= ~CRED_TI_DOMAIN_FORMAT_UNKNOWN;
  288. }
  289. if ( LocalFlags != 0 ) {
  290. printf( " 0x%lx", LocalFlags );
  291. }
  292. printf( "\n" );
  293. }
  294. if ( TargetInformation->CredTypeCount != 0 ) {
  295. printf( " Types:" );
  296. for ( i=0; i<TargetInformation->CredTypeCount; i++ ) {
  297. if ( TargetInformation->CredTypes[i] >= 1 && TargetInformation->CredTypes[i] <= TYPE_COUNT ) {
  298. printf(" %ls", TypeArray[TargetInformation->CredTypes[i]-1]);
  299. } else {
  300. printf("<Unknown>");
  301. }
  302. }
  303. printf( "\n" );
  304. }
  305. }
  306. VOID
  307. TestLpcRoutine(
  308. LPWSTR DomainName,
  309. LPWSTR UserName,
  310. LPWSTR Password
  311. )
  312. /*++
  313. Routine Description:
  314. Test base LPC functionality
  315. Arguments:
  316. None
  317. Return Value:
  318. None
  319. --*/
  320. {
  321. SECURITY_STATUS SecStatus;
  322. DWORD WinStatus;
  323. CredHandle CredentialHandle1;
  324. CredHandle CredentialHandle2;
  325. CtxtHandle ClientContextHandle;
  326. CtxtHandle ServerContextHandle;
  327. TimeStamp Lifetime;
  328. ULONG ContextAttributes;
  329. ULONG PackageCount;
  330. PSecPkgInfo PackageInfo = NULL;
  331. HANDLE Token = NULL;
  332. ULONG i;
  333. ULONG UseValidated;
  334. SEC_WINNT_AUTH_IDENTITY AuthIdentity;
  335. SecBufferDesc NegotiateDesc;
  336. SecBuffer NegotiateBuffer;
  337. SecBufferDesc ChallengeDesc;
  338. SecBuffer ChallengeBuffer;
  339. SecBufferDesc AuthenticateDesc;
  340. SecBuffer AuthenticateBuffer;
  341. SecPkgContext_Sizes ContextSizes;
  342. SecPkgContext_Lifespan ContextLifespan;
  343. UCHAR ContextNamesBuffer[sizeof(SecPkgContext_Names)+UNLEN*sizeof(WCHAR)];
  344. PSecPkgContext_Names ContextNames = (PSecPkgContext_Names) ContextNamesBuffer;
  345. SecPkgContext_CredentialName ContextCredentialName;
  346. UCHAR ContextCredNameBuffer[sizeof(SecPkgContext_CredentialName)+1024];
  347. PSecPkgContext_CredentialName ContextCredNamePtr = (PSecPkgContext_CredentialName) ContextCredNameBuffer;
  348. SecPkgContext_CredentialNameA ContextCredentialNameA;
  349. PSecPkgContext_CredentialNameA ContextCredNamePtrA = (PSecPkgContext_CredentialNameA) ContextCredNameBuffer;
  350. SecPkgContext_TargetInformation ContextTargetInfo;
  351. SecPkgContext_TargetInformationA ContextTargetInfoA;
  352. SecBufferDesc SignMessage;
  353. SecBuffer SigBuffers[2];
  354. BYTE bDataBuffer[20];
  355. BYTE bSigBuffer[100];
  356. NegotiateBuffer.pvBuffer = NULL;
  357. ChallengeBuffer.pvBuffer = NULL;
  358. AuthenticateBuffer.pvBuffer = NULL;
  359. SigBuffers[1].pvBuffer = bSigBuffer;
  360. SigBuffers[1].cbBuffer = sizeof(bSigBuffer);
  361. SigBuffers[1].BufferType = SECBUFFER_TOKEN;
  362. SigBuffers[0].pvBuffer = bDataBuffer;
  363. SigBuffers[0].cbBuffer = sizeof(bDataBuffer);
  364. SigBuffers[0].BufferType = SECBUFFER_DATA;
  365. memset(bDataBuffer,0xeb,sizeof(bDataBuffer));
  366. SignMessage.pBuffers = SigBuffers;
  367. SignMessage.cBuffers = 2;
  368. SignMessage.ulVersion = 0;
  369. //
  370. // Get info about the security packages.
  371. //
  372. SecStatus = EnumerateSecurityPackages( &PackageCount, &PackageInfo );
  373. if ( SecStatus != STATUS_SUCCESS ) {
  374. printf( "EnumerateSecurityPackages failed:" );
  375. PrintStatus( SecStatus );
  376. return;
  377. }
  378. if ( !QuietMode ) {
  379. printf( "PackageCount: %ld\n", PackageCount );
  380. for ( i=0; i<PackageCount; i++ ) {
  381. printf( "%ld: \"%ws\" \"%ws\"\n", i, PackageInfo[i].Name, PackageInfo[i].Comment );
  382. printf( " Cap: 0x%lx Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  383. PackageInfo[i].fCapabilities,
  384. PackageInfo[i].wVersion,
  385. PackageInfo[i].wRPCID,
  386. PackageInfo[i].cbMaxToken );
  387. }
  388. }
  389. //
  390. // Get info about the security packages.
  391. //
  392. SecStatus = QuerySecurityPackageInfo( NTLMSP_NAME, &PackageInfo );
  393. if ( SecStatus != STATUS_SUCCESS ) {
  394. printf( "QuerySecurityPackageInfo failed:" );
  395. PrintStatus( SecStatus );
  396. return;
  397. }
  398. if ( !QuietMode ) {
  399. printf( "Name: %ws Comment: %ws\n", PackageInfo->Name, PackageInfo->Comment );
  400. printf( "Cap: 0x%lx Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  401. PackageInfo->fCapabilities,
  402. PackageInfo->wVersion,
  403. PackageInfo->wRPCID,
  404. PackageInfo->cbMaxToken );
  405. }
  406. //
  407. // Acquire a credential handle for the server side
  408. //
  409. SecStatus = AcquireCredentialsHandle(
  410. NULL, // New principal
  411. NTLMSP_NAME, // Package Name
  412. SECPKG_CRED_INBOUND,
  413. NULL,
  414. NULL,
  415. NULL,
  416. NULL,
  417. &CredentialHandle1,
  418. &Lifetime );
  419. if ( SecStatus != STATUS_SUCCESS ) {
  420. printf( "AcquireCredentialsHandle failed: ");
  421. PrintStatus( SecStatus );
  422. return;
  423. }
  424. if ( !QuietMode ) {
  425. printf( "CredentialHandle1: 0x%lx 0x%lx ",
  426. CredentialHandle1.dwLower, CredentialHandle1.dwUpper );
  427. PrintTime( "Lifetime: ", Lifetime );
  428. }
  429. //
  430. // Acquire a credential handle for the client side
  431. //
  432. RtlZeroMemory( &AuthIdentity, sizeof(AuthIdentity) );
  433. // #define DO_OEM 1
  434. #ifndef DO_OEM
  435. if ( DomainName != NULL ) {
  436. AuthIdentity.Domain = DomainName;
  437. AuthIdentity.DomainLength = wcslen(DomainName);
  438. }
  439. if ( UserName != NULL ) {
  440. AuthIdentity.User = UserName;
  441. AuthIdentity.UserLength = wcslen(UserName);
  442. }
  443. if ( Password != NULL ) {
  444. AuthIdentity.Password = Password;
  445. AuthIdentity.PasswordLength = wcslen(Password);
  446. }
  447. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  448. #else
  449. //
  450. // BUGBUG: memory leak here
  451. //
  452. if ( DomainName != NULL ) {
  453. AuthIdentity.Domain = (LPWSTR) NetpAllocStrFromWStr(DomainName);
  454. AuthIdentity.DomainLength = wcslen(DomainName);
  455. }
  456. if ( UserName != NULL ) {
  457. AuthIdentity.User = (LPWSTR) NetpAllocStrFromWStr(UserName);
  458. AuthIdentity.UserLength = wcslen(UserName);
  459. }
  460. if ( Password != NULL ) {
  461. AuthIdentity.Password = (LPWSTR) NetpAllocStrFromWStr(Password);
  462. AuthIdentity.PasswordLength = wcslen(Password);
  463. }
  464. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  465. #endif
  466. SecStatus = AcquireCredentialsHandle(
  467. NULL, // New principal
  468. NTLMSP_NAME, // Package Name
  469. SECPKG_CRED_OUTBOUND,
  470. NULL,
  471. (DomainName == NULL && UserName == NULL && Password == NULL) ?
  472. NULL : &AuthIdentity,
  473. NULL,
  474. NULL,
  475. &CredentialHandle2,
  476. &Lifetime );
  477. if ( SecStatus != STATUS_SUCCESS ) {
  478. printf( "AcquireCredentialsHandle failed: " );
  479. PrintStatus( SecStatus );
  480. return;
  481. }
  482. if ( !QuietMode ) {
  483. printf( "CredentialHandle2: 0x%lx 0x%lx ",
  484. CredentialHandle2.dwLower, CredentialHandle2.dwUpper );
  485. PrintTime( "Lifetime: ", Lifetime );
  486. }
  487. //
  488. // Get the NegotiateMessage (ClientSide)
  489. //
  490. NegotiateDesc.ulVersion = 0;
  491. NegotiateDesc.cBuffers = 1;
  492. NegotiateDesc.pBuffers = &NegotiateBuffer;
  493. NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  494. NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
  495. NegotiateBuffer.pvBuffer = LocalAlloc( 0, NegotiateBuffer.cbBuffer );
  496. if ( NegotiateBuffer.pvBuffer == NULL ) {
  497. printf( "Allocate NegotiateMessage failed: 0x%ld\n", GetLastError() );
  498. return;
  499. }
  500. SecStatus = InitializeSecurityContext(
  501. &CredentialHandle2,
  502. NULL, // No Client context yet
  503. L"\\\\Frank\\IPC$", // Faked target name
  504. ISC_REQ_SEQUENCE_DETECT,
  505. 0, // Reserved 1
  506. SECURITY_NATIVE_DREP,
  507. NULL, // No initial input token
  508. 0, // Reserved 2
  509. &ClientContextHandle,
  510. &NegotiateDesc,
  511. &ContextAttributes,
  512. &Lifetime );
  513. if ( SecStatus != STATUS_SUCCESS ) {
  514. if ( !QuietMode || !NT_SUCCESS(SecStatus) ) {
  515. printf( "InitializeSecurityContext (negotiate): " );
  516. PrintStatus( SecStatus );
  517. }
  518. if ( !NT_SUCCESS(SecStatus) ) {
  519. return;
  520. }
  521. }
  522. if ( !QuietMode ) {
  523. printf( "\n\nNegotiate Message:\n" );
  524. printf( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  525. ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
  526. ContextAttributes );
  527. PrintTime( "Lifetime: ", Lifetime );
  528. DumpBuffer( NegotiateBuffer.pvBuffer, NegotiateBuffer.cbBuffer );
  529. }
  530. //
  531. // Get the ChallengeMessage (ServerSide)
  532. //
  533. NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
  534. ChallengeDesc.ulVersion = 0;
  535. ChallengeDesc.cBuffers = 1;
  536. ChallengeDesc.pBuffers = &ChallengeBuffer;
  537. ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
  538. ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
  539. ChallengeBuffer.pvBuffer = LocalAlloc( 0, ChallengeBuffer.cbBuffer );
  540. if ( ChallengeBuffer.pvBuffer == NULL ) {
  541. printf( "Allocate ChallengeMessage failed: 0x%ld\n", GetLastError() );
  542. return;
  543. }
  544. SecStatus = AcceptSecurityContext(
  545. &CredentialHandle1,
  546. NULL, // No Server context yet
  547. &NegotiateDesc,
  548. ISC_REQ_SEQUENCE_DETECT,
  549. SECURITY_NATIVE_DREP,
  550. &ServerContextHandle,
  551. &ChallengeDesc,
  552. &ContextAttributes,
  553. &Lifetime );
  554. if ( SecStatus != STATUS_SUCCESS ) {
  555. if ( !QuietMode || !NT_SUCCESS(SecStatus) ) {
  556. printf( "AcceptSecurityContext (Challenge): " );
  557. PrintStatus( SecStatus );
  558. }
  559. if ( !NT_SUCCESS(SecStatus) ) {
  560. return;
  561. }
  562. }
  563. if ( !QuietMode ) {
  564. printf( "\n\nChallenge Message:\n" );
  565. printf( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  566. ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
  567. ContextAttributes );
  568. PrintTime( "Lifetime: ", Lifetime );
  569. DumpBuffer( ChallengeBuffer.pvBuffer, ChallengeBuffer.cbBuffer );
  570. }
  571. //
  572. // Get the AuthenticateMessage (ClientSide)
  573. //
  574. ChallengeBuffer.BufferType |= SECBUFFER_READONLY;
  575. AuthenticateDesc.ulVersion = 0;
  576. AuthenticateDesc.cBuffers = 1;
  577. AuthenticateDesc.pBuffers = &AuthenticateBuffer;
  578. AuthenticateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  579. AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
  580. AuthenticateBuffer.pvBuffer = LocalAlloc( 0, AuthenticateBuffer.cbBuffer );
  581. if ( AuthenticateBuffer.pvBuffer == NULL ) {
  582. printf( "Allocate AuthenticateMessage failed: 0x%ld\n", GetLastError() );
  583. return;
  584. }
  585. SecStatus = InitializeSecurityContext(
  586. NULL,
  587. &ClientContextHandle,
  588. L"\\\\Frank\\IPC$", // Faked target name
  589. 0,
  590. 0, // Reserved 1
  591. SECURITY_NATIVE_DREP,
  592. &ChallengeDesc,
  593. 0, // Reserved 2
  594. &ClientContextHandle,
  595. &AuthenticateDesc,
  596. &ContextAttributes,
  597. &Lifetime );
  598. if ( SecStatus != STATUS_SUCCESS ) {
  599. printf( "InitializeSecurityContext (Authenticate): " );
  600. PrintStatus( SecStatus );
  601. if ( !NT_SUCCESS(SecStatus) ) {
  602. return;
  603. }
  604. }
  605. if ( !QuietMode ) {
  606. printf( "\n\nAuthenticate Message:\n" );
  607. printf( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  608. ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
  609. ContextAttributes );
  610. PrintTime( "Lifetime: ", Lifetime );
  611. DumpBuffer( AuthenticateBuffer.pvBuffer, AuthenticateBuffer.cbBuffer );
  612. }
  613. // #if 0
  614. //
  615. // Query as many attributes as possible
  616. //
  617. SecStatus = QueryContextAttributes(
  618. &ClientContextHandle,
  619. SECPKG_ATTR_SIZES,
  620. &ContextSizes );
  621. if ( SecStatus != STATUS_SUCCESS ) {
  622. printf( "QueryContextAttributes (sizes): " );
  623. PrintStatus( SecStatus );
  624. if ( !NT_SUCCESS(SecStatus) ) {
  625. return;
  626. }
  627. }
  628. if ( !QuietMode ) {
  629. printf( "QuerySizes: %ld %ld %ld %ld\n",
  630. ContextSizes.cbMaxToken,
  631. ContextSizes.cbMaxSignature,
  632. ContextSizes.cbBlockSize,
  633. ContextSizes.cbSecurityTrailer );
  634. }
  635. SecStatus = QueryContextAttributes(
  636. &ClientContextHandle,
  637. SECPKG_ATTR_NAMES,
  638. ContextNamesBuffer );
  639. if ( SecStatus != STATUS_SUCCESS ) {
  640. printf( "QueryContextAttributes (names): " );
  641. PrintStatus( SecStatus );
  642. if ( !NT_SUCCESS(SecStatus) ) {
  643. return;
  644. }
  645. }
  646. if ( !QuietMode ) {
  647. printf( "QueryNames: %ws\n", ContextNames->sUserName );
  648. }
  649. //
  650. // Try getting the built in credential name
  651. //
  652. SecStatus = QueryContextAttributes(
  653. &ClientContextHandle,
  654. SECPKG_ATTR_CREDENTIAL_NAME,
  655. &ContextCredentialName );
  656. if ( SecStatus != STATUS_SUCCESS ) {
  657. printf( "QueryContextAttributes (credentialname): " );
  658. PrintStatus( SecStatus );
  659. if ( !NT_SUCCESS(SecStatus) ) {
  660. return;
  661. }
  662. }
  663. if ( !QuietMode ) {
  664. printf( "QueryCredentialName: %ld %ws\n",
  665. ContextCredentialName.CredentialType,
  666. ContextCredentialName.sCredentialName );
  667. }
  668. //
  669. // Set UseValidated
  670. //
  671. UseValidated = 5;
  672. SecStatus = SetContextAttributes(
  673. &ClientContextHandle,
  674. SECPKG_ATTR_USE_VALIDATED,
  675. &UseValidated,
  676. sizeof(UseValidated) );
  677. if ( SecStatus != STATUS_SUCCESS ) {
  678. printf( "SetContextAttributes (usevalidated): " );
  679. PrintStatus( SecStatus );
  680. if ( !NT_SUCCESS(SecStatus) ) {
  681. return;
  682. }
  683. }
  684. if ( !QuietMode ) {
  685. printf( "Setting use validate to %ld worked\n", UseValidated );
  686. }
  687. //
  688. // Set CredentialName
  689. //
  690. ContextCredNamePtr->CredentialType = 0x15;
  691. ContextCredNamePtr->sCredentialName = (LPWSTR)(ContextCredNamePtr+1);
  692. wcscpy( ContextCredNamePtr->sCredentialName, L"Frederick" );
  693. SecStatus = SetContextAttributes(
  694. &ClientContextHandle,
  695. SECPKG_ATTR_CREDENTIAL_NAME,
  696. ContextCredNamePtr,
  697. sizeof(*ContextCredNamePtr) +
  698. (wcslen(ContextCredNamePtr->sCredentialName) + 1) * sizeof(WCHAR) );
  699. if ( SecStatus != STATUS_SUCCESS ) {
  700. printf( "SetContextAttributes (credentialname): " );
  701. PrintStatus( SecStatus );
  702. if ( !NT_SUCCESS(SecStatus) ) {
  703. return;
  704. }
  705. }
  706. if ( !QuietMode ) {
  707. printf( "Setting credentialname to %ld %ls worked\n", ContextCredNamePtr->CredentialType, ContextCredNamePtr->sCredentialName );
  708. }
  709. //
  710. // Try getting the credential name we just wrote
  711. //
  712. SecStatus = QueryContextAttributes(
  713. &ClientContextHandle,
  714. SECPKG_ATTR_CREDENTIAL_NAME,
  715. &ContextCredentialName );
  716. if ( SecStatus != STATUS_SUCCESS ) {
  717. printf( "QueryContextAttributes (credentialname): " );
  718. PrintStatus( SecStatus );
  719. if ( !NT_SUCCESS(SecStatus) ) {
  720. return;
  721. }
  722. }
  723. if ( !QuietMode ) {
  724. printf( "QueryCredentialName: %ld %ws\n",
  725. ContextCredentialName.CredentialType,
  726. ContextCredentialName.sCredentialName );
  727. }
  728. //
  729. // Try getting the target info
  730. //
  731. SecStatus = QueryContextAttributes(
  732. &ClientContextHandle,
  733. SECPKG_ATTR_TARGET_INFORMATION,
  734. &ContextTargetInfo );
  735. if ( SecStatus != STATUS_SUCCESS ) {
  736. printf( "QueryContextAttributes (targetinformation): " );
  737. PrintStatus( SecStatus );
  738. if ( !NT_SUCCESS(SecStatus) ) {
  739. return;
  740. }
  741. }
  742. if ( !QuietMode ) {
  743. printf( "QueryCredentialName:\n" );
  744. PrintTargetInfo( ContextTargetInfo.TargetInformation );
  745. }
  746. //
  747. // Set UseValidated
  748. //
  749. UseValidated = 34;
  750. SecStatus = SetContextAttributesA(
  751. &ClientContextHandle,
  752. SECPKG_ATTR_USE_VALIDATED,
  753. &UseValidated,
  754. sizeof(UseValidated) );
  755. if ( SecStatus != STATUS_SUCCESS ) {
  756. printf( "SetContextAttributes (usevalidated ANSI): " );
  757. PrintStatus( SecStatus );
  758. if ( !NT_SUCCESS(SecStatus) ) {
  759. return;
  760. }
  761. }
  762. if ( !QuietMode ) {
  763. printf( "Setting use validate ANSI to %ld worked\n", UseValidated );
  764. }
  765. //
  766. // Set CredentialName
  767. //
  768. ContextCredNamePtrA->CredentialType = 0x18;
  769. ContextCredNamePtrA->sCredentialName = (LPSTR)(ContextCredNamePtrA+1);
  770. strcpy( ContextCredNamePtrA->sCredentialName, "Waldo" );
  771. SecStatus = SetContextAttributesA(
  772. &ClientContextHandle,
  773. SECPKG_ATTR_CREDENTIAL_NAME,
  774. ContextCredNamePtrA,
  775. sizeof(*ContextCredNamePtrA) +
  776. (strlen(ContextCredNamePtrA->sCredentialName) + 1) );
  777. if ( SecStatus != STATUS_SUCCESS ) {
  778. printf( "SetContextAttributes (credentialname ANSI): " );
  779. PrintStatus( SecStatus );
  780. if ( !NT_SUCCESS(SecStatus) ) {
  781. return;
  782. }
  783. }
  784. if ( !QuietMode ) {
  785. printf( "Setting credentialname ANSI to %ld %s worked\n", ContextCredNamePtrA->CredentialType, ContextCredNamePtrA->sCredentialName );
  786. }
  787. //
  788. // Try getting the credential name we just wrote
  789. //
  790. SecStatus = QueryContextAttributesA(
  791. &ClientContextHandle,
  792. SECPKG_ATTR_CREDENTIAL_NAME,
  793. &ContextCredentialNameA );
  794. if ( SecStatus != STATUS_SUCCESS ) {
  795. printf( "QueryContextAttributes (credentialname ANSI): " );
  796. PrintStatus( SecStatus );
  797. if ( !NT_SUCCESS(SecStatus) ) {
  798. return;
  799. }
  800. }
  801. if ( !QuietMode ) {
  802. printf( "QueryCredentialName ANSI: %ld %s\n",
  803. ContextCredentialNameA.CredentialType,
  804. ContextCredentialNameA.sCredentialName );
  805. }
  806. //
  807. // Try getting the target info
  808. //
  809. SecStatus = QueryContextAttributesA(
  810. &ClientContextHandle,
  811. SECPKG_ATTR_TARGET_INFORMATION,
  812. &ContextTargetInfoA );
  813. if ( SecStatus != STATUS_SUCCESS ) {
  814. printf( "QueryContextAttributes (targetinformation ANSI): " );
  815. PrintStatus( SecStatus );
  816. if ( !NT_SUCCESS(SecStatus) ) {
  817. return;
  818. }
  819. }
  820. if ( !QuietMode ) {
  821. PCREDENTIAL_TARGET_INFORMATION TargetInformation;
  822. WinStatus = CredpConvertTargetInfo( DoAtoW,
  823. (PCREDENTIAL_TARGET_INFORMATIONW)ContextTargetInfoA.TargetInformation,
  824. &TargetInformation,
  825. NULL );
  826. if ( WinStatus != NO_ERROR ) {
  827. printf( "QueryContextAttributes (targetinformation ANSI): cannot convert to unicode" );
  828. PrintStatus( WinStatus );
  829. return;
  830. }
  831. printf( "QueryCredentialName ANSI:\n" );
  832. PrintTargetInfo( TargetInformation );
  833. }
  834. // #endif
  835. //
  836. // Finally authenticate the user (ServerSide)
  837. //
  838. AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
  839. SecStatus = AcceptSecurityContext(
  840. NULL,
  841. &ServerContextHandle,
  842. &AuthenticateDesc,
  843. 0,
  844. SECURITY_NATIVE_DREP,
  845. &ServerContextHandle,
  846. NULL,
  847. &ContextAttributes,
  848. &Lifetime );
  849. if (STATUS_SUCCESS == QueryContextAttributes(
  850. &ClientContextHandle,
  851. SECPKG_ATTR_NAMES,
  852. ContextNamesBuffer )) {
  853. printf( "QueryNames: %ws\n", ContextNames->sUserName );
  854. }
  855. if ( SecStatus != STATUS_SUCCESS ) {
  856. printf( "AcceptSecurityContext (Challenge): " );
  857. PrintStatus( SecStatus );
  858. if ( !NT_SUCCESS(SecStatus) ) {
  859. return;
  860. }
  861. }
  862. if ( !QuietMode ) {
  863. printf( "\n\nFinal Authentication:\n" );
  864. printf( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  865. ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
  866. ContextAttributes );
  867. PrintTime( "Lifetime: ", Lifetime );
  868. printf(" \n" );
  869. }
  870. //
  871. // Now make a third call to Initialize to check that RPC can
  872. // reauthenticate.
  873. //
  874. AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
  875. SecStatus = InitializeSecurityContext(
  876. NULL,
  877. &ClientContextHandle,
  878. L"\\\\Frank\\IPC$", // Faked target name
  879. 0,
  880. 0, // Reserved 1
  881. SECURITY_NATIVE_DREP,
  882. NULL,
  883. 0, // Reserved 2
  884. &ClientContextHandle,
  885. &AuthenticateDesc,
  886. &ContextAttributes,
  887. &Lifetime );
  888. if ( SecStatus != STATUS_SUCCESS ) {
  889. printf( "InitializeSecurityContext (Re-Authenticate): " );
  890. PrintStatus( SecStatus );
  891. if ( !NT_SUCCESS(SecStatus) ) {
  892. return;
  893. }
  894. }
  895. //
  896. // Now try to re-authenticate the user (ServerSide)
  897. //
  898. AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
  899. SecStatus = AcceptSecurityContext(
  900. NULL,
  901. &ServerContextHandle,
  902. &AuthenticateDesc,
  903. 0,
  904. SECURITY_NATIVE_DREP,
  905. &ServerContextHandle,
  906. NULL,
  907. &ContextAttributes,
  908. &Lifetime );
  909. if ( SecStatus != STATUS_SUCCESS ) {
  910. printf( "AcceptSecurityContext (Re-authenticate): " );
  911. PrintStatus( SecStatus );
  912. if ( !NT_SUCCESS(SecStatus) ) {
  913. return;
  914. }
  915. }
  916. //
  917. // Impersonate the client (ServerSide)
  918. //
  919. SecStatus = ImpersonateSecurityContext( &ServerContextHandle );
  920. if ( SecStatus != STATUS_SUCCESS ) {
  921. printf( "ImpersonateSecurityContext: " );
  922. PrintStatus( SecStatus );
  923. if ( !NT_SUCCESS(SecStatus) ) {
  924. return;
  925. }
  926. }
  927. //
  928. // Do something while impersonating (Access the token)
  929. //
  930. {
  931. NTSTATUS Status;
  932. HANDLE TokenHandle = NULL;
  933. //
  934. // Open the token,
  935. //
  936. Status = NtOpenThreadToken(
  937. NtCurrentThread(),
  938. TOKEN_QUERY,
  939. (BOOLEAN) TRUE, // Not really using the impersonation token
  940. &TokenHandle );
  941. if ( !NT_SUCCESS(Status) ) {
  942. printf( "Access Thread token while impersonating: " );
  943. PrintStatus( Status );
  944. return;
  945. } else {
  946. (VOID) NtClose( TokenHandle );
  947. }
  948. }
  949. //
  950. // RevertToSelf (ServerSide)
  951. //
  952. SecStatus = RevertSecurityContext( &ServerContextHandle );
  953. if ( SecStatus != STATUS_SUCCESS ) {
  954. printf( "RevertSecurityContext: " );
  955. PrintStatus( SecStatus );
  956. if ( !NT_SUCCESS(SecStatus) ) {
  957. return;
  958. }
  959. }
  960. //
  961. // Impersonate the client manually
  962. //
  963. SecStatus = QuerySecurityContextToken( &ServerContextHandle,&Token );
  964. if ( SecStatus != STATUS_SUCCESS ) {
  965. printf( "QuerySecurityContextToken: " );
  966. PrintStatus( SecStatus );
  967. if ( !NT_SUCCESS(SecStatus) ) {
  968. return;
  969. }
  970. }
  971. if (!ImpersonateLoggedOnUser(Token))
  972. {
  973. printf("Impersonate logged on user failed: %d\n",GetLastError());
  974. return;
  975. }
  976. //
  977. // Do something while impersonating (Access the token)
  978. //
  979. {
  980. NTSTATUS Status;
  981. HANDLE TokenHandle = NULL;
  982. WCHAR UserName[100];
  983. ULONG NameLength = 100;
  984. //
  985. // Open the token,
  986. //
  987. Status = NtOpenThreadToken(
  988. NtCurrentThread(),
  989. TOKEN_QUERY,
  990. (BOOLEAN) TRUE, // Not really using the impersonation token
  991. &TokenHandle );
  992. if ( !NT_SUCCESS(Status) ) {
  993. printf( "Access Thread token while impersonating: " );
  994. PrintStatus( Status );
  995. return;
  996. } else {
  997. (VOID) NtClose( TokenHandle );
  998. }
  999. if (!GetUserName(UserName, &NameLength))
  1000. {
  1001. printf("Failed to get username: %d\n",GetLastError());
  1002. return;
  1003. }
  1004. else
  1005. {
  1006. printf("Username = %ws\n",UserName);
  1007. }
  1008. }
  1009. //
  1010. // RevertToSelf (ServerSide)
  1011. //
  1012. if (!RevertToSelf())
  1013. {
  1014. printf( "RevertToSelf failed: %d\n ",GetLastError() );
  1015. return;
  1016. }
  1017. CloseHandle(Token);
  1018. //
  1019. // Check password expiry
  1020. //
  1021. #ifdef notdef
  1022. SecStatus = SspQueryPasswordExpiry(
  1023. &ServerContextHandle,
  1024. &Lifetime
  1025. );
  1026. if (!NT_SUCCESS(SecStatus))
  1027. {
  1028. printf("Failed to query password expiry: 0x%x\n",SecStatus);
  1029. }
  1030. else
  1031. {
  1032. TIME_FIELDS TimeFields;
  1033. RtlTimeToTimeFields(
  1034. &Lifetime,
  1035. &TimeFields
  1036. );
  1037. printf("Password expires %d-%d-%d %d:%d:%d\n",
  1038. TimeFields.Day,
  1039. TimeFields.Month,
  1040. TimeFields.Year,
  1041. TimeFields.Hour,
  1042. TimeFields.Minute,
  1043. TimeFields.Second
  1044. );
  1045. }
  1046. #endif
  1047. //
  1048. // Sign a message
  1049. //
  1050. SecStatus = MakeSignature(
  1051. &ClientContextHandle,
  1052. 0,
  1053. &SignMessage,
  1054. 0 );
  1055. if ( SecStatus != STATUS_SUCCESS ) {
  1056. printf( "MakeSignature: " );
  1057. PrintStatus( SecStatus );
  1058. if ( !NT_SUCCESS(SecStatus) ) {
  1059. return;
  1060. }
  1061. }
  1062. if ( !QuietMode ) {
  1063. printf("\n Signature: \n");
  1064. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  1065. }
  1066. //
  1067. // Verify the signature
  1068. //
  1069. SecStatus = VerifySignature(
  1070. &ServerContextHandle,
  1071. &SignMessage,
  1072. 0,
  1073. 0 );
  1074. if ( SecStatus != STATUS_SUCCESS ) {
  1075. printf( "VerifySignature: " );
  1076. PrintStatus( SecStatus );
  1077. if ( !NT_SUCCESS(SecStatus) ) {
  1078. return;
  1079. }
  1080. }
  1081. //
  1082. // Sign a message, this time to check if it can detect a change in the
  1083. // message
  1084. //
  1085. SecStatus = MakeSignature(
  1086. &ClientContextHandle,
  1087. 0,
  1088. &SignMessage,
  1089. 0 );
  1090. if ( SecStatus != STATUS_SUCCESS ) {
  1091. printf( "MakeSignature: " );
  1092. PrintStatus( SecStatus );
  1093. if ( !NT_SUCCESS(SecStatus) ) {
  1094. return;
  1095. }
  1096. }
  1097. if ( !QuietMode ) {
  1098. printf("\n Signature: \n");
  1099. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  1100. }
  1101. //
  1102. // Mess up the message to see if VerifySignature works
  1103. //
  1104. bDataBuffer[10] = 0xec;
  1105. //
  1106. // Verify the signature
  1107. //
  1108. SecStatus = VerifySignature(
  1109. &ServerContextHandle,
  1110. &SignMessage,
  1111. 0,
  1112. 0 );
  1113. if ( SecStatus != SEC_E_MESSAGE_ALTERED ) {
  1114. printf( "VerifySignature: " );
  1115. PrintStatus( SecStatus );
  1116. if ( !NT_SUCCESS(SecStatus) ) {
  1117. return;
  1118. }
  1119. }
  1120. //
  1121. // Delete both contexts.
  1122. //
  1123. SecStatus = DeleteSecurityContext( &ClientContextHandle );
  1124. if ( SecStatus != STATUS_SUCCESS ) {
  1125. printf( "DeleteSecurityContext failed: " );
  1126. PrintStatus( SecStatus );
  1127. return;
  1128. }
  1129. SecStatus = DeleteSecurityContext( &ServerContextHandle );
  1130. if ( SecStatus != STATUS_SUCCESS ) {
  1131. printf( "DeleteSecurityContext failed: " );
  1132. PrintStatus( SecStatus );
  1133. return;
  1134. }
  1135. //
  1136. // Free both credential handles
  1137. //
  1138. SecStatus = FreeCredentialsHandle( &CredentialHandle1 );
  1139. if ( SecStatus != STATUS_SUCCESS ) {
  1140. printf( "FreeCredentialsHandle failed: " );
  1141. PrintStatus( SecStatus );
  1142. return;
  1143. }
  1144. SecStatus = FreeCredentialsHandle( &CredentialHandle2 );
  1145. if ( SecStatus != STATUS_SUCCESS ) {
  1146. printf( "FreeCredentialsHandle failed: " );
  1147. PrintStatus( SecStatus );
  1148. return;
  1149. }
  1150. //
  1151. // Final Cleanup
  1152. //
  1153. if ( NegotiateBuffer.pvBuffer != NULL ) {
  1154. (VOID) LocalFree( NegotiateBuffer.pvBuffer );
  1155. }
  1156. if ( ChallengeBuffer.pvBuffer != NULL ) {
  1157. (VOID) LocalFree( ChallengeBuffer.pvBuffer );
  1158. }
  1159. if ( AuthenticateBuffer.pvBuffer != NULL ) {
  1160. (VOID) LocalFree( AuthenticateBuffer.pvBuffer );
  1161. }
  1162. }
  1163. int __cdecl
  1164. main(
  1165. IN int argc,
  1166. IN char ** argv
  1167. )
  1168. /*++
  1169. Routine Description:
  1170. Drive the NtLmSsp service
  1171. Arguments:
  1172. argc - the number of command-line arguments.
  1173. argv - an array of pointers to the arguments.
  1174. Return Value:
  1175. Exit status
  1176. --*/
  1177. {
  1178. LPSTR argument;
  1179. int i;
  1180. ULONG j;
  1181. ULONG Iterations = 0;
  1182. LPWSTR DomainName = NULL;
  1183. LPWSTR UserName = NULL;
  1184. LPWSTR Password = NULL;
  1185. #if DBG
  1186. ULONG FunctionCode;
  1187. ULONG Data;
  1188. #endif // DBG
  1189. enum {
  1190. NoAction,
  1191. TestLpc,
  1192. #define TESTLPC_PARAM "/TestLpc"
  1193. #define TESTLPC2_PARAM "/TestLpc:"
  1194. } Action = NoAction;
  1195. #define QUIET_PARAM "/Q"
  1196. //
  1197. // Loop through the arguments handle each in turn
  1198. //
  1199. for ( i=1; i<argc; i++ ) {
  1200. argument = argv[i];
  1201. //
  1202. // Handle /TestLpc
  1203. //
  1204. if ( _stricmp( argument, TESTLPC_PARAM ) == 0 ) {
  1205. if ( Action != NoAction ) {
  1206. goto Usage;
  1207. }
  1208. Action = TestLpc;
  1209. Iterations = 1;
  1210. //
  1211. // Handle /TestLpc:
  1212. //
  1213. } else if ( _strnicmp( argument,
  1214. TESTLPC2_PARAM,
  1215. sizeof(TESTLPC2_PARAM)-1 ) == 0 ){
  1216. char *end;
  1217. if ( Action != NoAction ) {
  1218. goto Usage;
  1219. }
  1220. Action = TestLpc;
  1221. Iterations = strtoul( &argument[sizeof(TESTLPC2_PARAM)-1], &end, 10 );
  1222. i++;
  1223. if ( i < argc ) {
  1224. argument = argv[i];
  1225. DomainName = NetpAllocWStrFromStr( argument );
  1226. i++;
  1227. if ( i < argc ) {
  1228. argument = argv[i];
  1229. UserName = NetpAllocWStrFromStr( argument );
  1230. i++;
  1231. if ( i < argc ) {
  1232. argument = argv[i];
  1233. Password = NetpAllocWStrFromStr( argument );
  1234. }
  1235. }
  1236. }
  1237. //
  1238. // Handle /Quiet
  1239. //
  1240. } else if ( _stricmp( argument, QUIET_PARAM ) == 0 ) {
  1241. QuietMode = TRUE;
  1242. //
  1243. // Handle all other parameters
  1244. //
  1245. } else {
  1246. Usage:
  1247. fprintf( stderr, "Usage: ssptest [/OPTIONS]\n\n" );
  1248. fprintf(
  1249. stderr,
  1250. "\n"
  1251. " " TESTLPC_PARAM "[:<iterations> <DomainName> <UserName> <Password>] - Test basic LPC to NtLmSsp service.\n"
  1252. " " QUIET_PARAM " - Don't be so verbose\n"
  1253. "\n"
  1254. "\n" );
  1255. return(1);
  1256. }
  1257. }
  1258. //
  1259. // Perform the action requested
  1260. //
  1261. switch ( Action ) {
  1262. case TestLpc: {
  1263. for ( j=0; j<Iterations ; j++ ) {
  1264. TestLpcRoutine( DomainName, UserName, Password );
  1265. }
  1266. break;
  1267. }
  1268. }
  1269. return 0;
  1270. }