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.

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