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.

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