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.

996 lines
23 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. extern "C"
  19. {
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <ntseapi.h>
  24. #include <ntlsa.h>
  25. #include <windef.h>
  26. #include <winbase.h>
  27. #include <winsvc.h> // Needed for service controller APIs
  28. #include <lmcons.h>
  29. #include <lmerr.h>
  30. #include <lmaccess.h>
  31. #include <lmsname.h>
  32. #include <rpc.h>
  33. #include <stdio.h> // printf
  34. #include <stdlib.h> // strtoul
  35. }
  36. #include <wchar.h>
  37. extern "C" {
  38. #include <netlib.h> // NetpGetLocalDomainId
  39. #include <tstring.h> // NetpAllocWStrFromWStr
  40. #define SECURITY_KERBEROS
  41. #define SECURITY_PACKAGE
  42. #include <security.h> // General definition of a Security Support Provider
  43. #include <secint.h>
  44. #include <kerbcomm.h>
  45. #include <negossp.h>
  46. #include <wincrypt.h>
  47. #include <cryptui.h>
  48. }
  49. #include <sclogon.h>
  50. BOOLEAN QuietMode = FALSE; // Don't be verbose
  51. BOOLEAN DoAnsi = FALSE;
  52. ULONG RecursionDepth = 0;
  53. CredHandle ServerCredHandleStorage;
  54. PCredHandle ServerCredHandle = NULL;
  55. #define MAX_RECURSION_DEPTH 1
  56. VOID
  57. DumpBuffer(
  58. PVOID Buffer,
  59. DWORD BufferSize
  60. )
  61. /*++
  62. Routine Description:
  63. Dumps the buffer content on to the debugger output.
  64. Arguments:
  65. Buffer: buffer pointer.
  66. BufferSize: size of the buffer.
  67. Return Value:
  68. none
  69. --*/
  70. {
  71. #define NUM_CHARS 16
  72. DWORD i, limit;
  73. CHAR TextBuffer[NUM_CHARS + 1];
  74. LPBYTE BufferPtr = (PBYTE) Buffer;
  75. printf("------------------------------------\n");
  76. //
  77. // Hex dump of the bytes
  78. //
  79. limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
  80. for (i = 0; i < limit; i++) {
  81. if (i < BufferSize) {
  82. printf("%02x ", BufferPtr[i]);
  83. if (BufferPtr[i] < 31 ) {
  84. TextBuffer[i % NUM_CHARS] = '.';
  85. } else if (BufferPtr[i] == '\0') {
  86. TextBuffer[i % NUM_CHARS] = ' ';
  87. } else {
  88. TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i];
  89. }
  90. } else {
  91. printf(" ");
  92. TextBuffer[i % NUM_CHARS] = ' ';
  93. }
  94. if ((i + 1) % NUM_CHARS == 0) {
  95. TextBuffer[NUM_CHARS] = 0;
  96. printf(" %s\n", TextBuffer);
  97. }
  98. }
  99. printf("------------------------------------\n");
  100. }
  101. VOID
  102. PrintTime(
  103. LPSTR Comment,
  104. TimeStamp ConvertTime
  105. )
  106. /*++
  107. Routine Description:
  108. Print the specified time
  109. Arguments:
  110. Comment - Comment to print in front of the time
  111. Time - Local time to print
  112. Return Value:
  113. None
  114. --*/
  115. {
  116. LARGE_INTEGER LocalTime;
  117. LocalTime.HighPart = ConvertTime.HighPart;
  118. LocalTime.LowPart = ConvertTime.LowPart;
  119. printf( "%s", Comment );
  120. //
  121. // If the time is infinite,
  122. // just say so.
  123. //
  124. if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
  125. printf( "Infinite\n" );
  126. //
  127. // Otherwise print it more clearly
  128. //
  129. } else {
  130. TIME_FIELDS TimeFields;
  131. RtlTimeToTimeFields( &LocalTime, &TimeFields );
  132. printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
  133. TimeFields.Month,
  134. TimeFields.Day,
  135. TimeFields.Year,
  136. TimeFields.Hour,
  137. TimeFields.Minute,
  138. TimeFields.Second );
  139. }
  140. }
  141. VOID
  142. PrintStatus(
  143. NET_API_STATUS NetStatus
  144. )
  145. /*++
  146. Routine Description:
  147. Print a net status code.
  148. Arguments:
  149. NetStatus - The net status code to print.
  150. Return Value:
  151. None
  152. --*/
  153. {
  154. printf( "Status = %lu 0x%lx", NetStatus, NetStatus );
  155. switch (NetStatus) {
  156. case NERR_Success:
  157. printf( " NERR_Success" );
  158. break;
  159. case NERR_DCNotFound:
  160. printf( " NERR_DCNotFound" );
  161. break;
  162. case ERROR_LOGON_FAILURE:
  163. printf( " ERROR_LOGON_FAILURE" );
  164. break;
  165. case ERROR_ACCESS_DENIED:
  166. printf( " ERROR_ACCESS_DENIED" );
  167. break;
  168. case ERROR_NOT_SUPPORTED:
  169. printf( " ERROR_NOT_SUPPORTED" );
  170. break;
  171. case ERROR_NO_LOGON_SERVERS:
  172. printf( " ERROR_NO_LOGON_SERVERS" );
  173. break;
  174. case ERROR_NO_SUCH_DOMAIN:
  175. printf( " ERROR_NO_SUCH_DOMAIN" );
  176. break;
  177. case ERROR_NO_TRUST_LSA_SECRET:
  178. printf( " ERROR_NO_TRUST_LSA_SECRET" );
  179. break;
  180. case ERROR_NO_TRUST_SAM_ACCOUNT:
  181. printf( " ERROR_NO_TRUST_SAM_ACCOUNT" );
  182. break;
  183. case ERROR_DOMAIN_TRUST_INCONSISTENT:
  184. printf( " ERROR_DOMAIN_TRUST_INCONSISTENT" );
  185. break;
  186. case ERROR_BAD_NETPATH:
  187. printf( " ERROR_BAD_NETPATH" );
  188. break;
  189. case ERROR_FILE_NOT_FOUND:
  190. printf( " ERROR_FILE_NOT_FOUND" );
  191. break;
  192. case NERR_NetNotStarted:
  193. printf( " NERR_NetNotStarted" );
  194. break;
  195. case NERR_WkstaNotStarted:
  196. printf( " NERR_WkstaNotStarted" );
  197. break;
  198. case NERR_ServerNotStarted:
  199. printf( " NERR_ServerNotStarted" );
  200. break;
  201. case NERR_BrowserNotStarted:
  202. printf( " NERR_BrowserNotStarted" );
  203. break;
  204. case NERR_ServiceNotInstalled:
  205. printf( " NERR_ServiceNotInstalled" );
  206. break;
  207. case NERR_BadTransactConfig:
  208. printf( " NERR_BadTransactConfig" );
  209. break;
  210. case SEC_E_NO_SPM:
  211. printf( " SEC_E_NO_SPM" );
  212. break;
  213. case SEC_E_BAD_PKGID:
  214. printf( " SEC_E_BAD_PKGID" ); break;
  215. case SEC_E_NOT_OWNER:
  216. printf( " SEC_E_NOT_OWNER" ); break;
  217. case SEC_E_CANNOT_INSTALL:
  218. printf( " SEC_E_CANNOT_INSTALL" ); break;
  219. case SEC_E_INVALID_TOKEN:
  220. printf( " SEC_E_INVALID_TOKEN" ); break;
  221. case SEC_E_CANNOT_PACK:
  222. printf( " SEC_E_CANNOT_PACK" ); break;
  223. case SEC_E_QOP_NOT_SUPPORTED:
  224. printf( " SEC_E_QOP_NOT_SUPPORTED" ); break;
  225. case SEC_E_NO_IMPERSONATION:
  226. printf( " SEC_E_NO_IMPERSONATION" ); break;
  227. case SEC_E_LOGON_DENIED:
  228. printf( " SEC_E_LOGON_DENIED" ); break;
  229. case SEC_E_UNKNOWN_CREDENTIALS:
  230. printf( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
  231. case SEC_E_NO_CREDENTIALS:
  232. printf( " SEC_E_NO_CREDENTIALS" ); break;
  233. case SEC_E_MESSAGE_ALTERED:
  234. printf( " SEC_E_MESSAGE_ALTERED" ); break;
  235. case SEC_E_OUT_OF_SEQUENCE:
  236. printf( " SEC_E_OUT_OF_SEQUENCE" ); break;
  237. case SEC_E_INSUFFICIENT_MEMORY:
  238. printf( " SEC_E_INSUFFICIENT_MEMORY" ); break;
  239. case SEC_E_INVALID_HANDLE:
  240. printf( " SEC_E_INVALID_HANDLE" ); break;
  241. case SEC_E_NOT_SUPPORTED:
  242. printf( " SEC_E_NOT_SUPPORTED" ); break;
  243. }
  244. printf( "\n" );
  245. }
  246. VOID
  247. TestGetKdcCert(
  248. IN LPWSTR ServiceName,
  249. IN LPWSTR ContainerName,
  250. IN LPWSTR CaLocation,
  251. IN LPWSTR CaName
  252. )
  253. {
  254. PCCERT_CONTEXT CertContext = NULL;
  255. DWORD Status = 0;
  256. WCHAR UsageOid[100];
  257. WCHAR ComputerName[100];
  258. ULONG ComputerNameLength = 100;
  259. LPSTR UsageString;
  260. CERT_ENHKEY_USAGE KeyUsage;
  261. CRYPTUI_WIZ_CERT_REQUEST_INFO CertInfo;
  262. CRYPTUI_WIZ_CERT_REQUEST_PVK_NEW PvkNew;
  263. RtlZeroMemory(
  264. &CertInfo,
  265. sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO)
  266. );
  267. RtlZeroMemory(
  268. &PvkNew,
  269. sizeof(CRYPTUI_WIZ_CERT_REQUEST_PVK_NEW)
  270. );
  271. GetComputerName(
  272. ComputerName,
  273. &ComputerNameLength
  274. );
  275. CertInfo.dwSize = sizeof(CertInfo);
  276. CertInfo.dwPurpose = CRYPTUI_WIZ_CERT_ENROLL;
  277. CertInfo.pwszMachineName = ComputerName; // local computer
  278. CertInfo.pwszAccountName = NULL; // ServiceName;
  279. CertInfo.pAuthentication = NULL; // MBZ
  280. CertInfo.pCertRequestString = NULL; // ??
  281. CertInfo.pwszDesStore = ContainerName;
  282. CertInfo.dwCertOpenStoreFlag = CERT_SYSTEM_STORE_SERVICES;
  283. CertInfo.pRenewCertContext = NULL; // we aren't renewing
  284. CertInfo.dwPvkChoice = CRYPTUI_WIZ_CERT_REQUEST_PVK_CHOICE_NEW;
  285. // generate new key
  286. CertInfo.pPvkNew = &PvkNew;
  287. PvkNew.dwSize = sizeof(PvkNew);
  288. PvkNew.pKeyProvInfo = NULL; // use default provider
  289. PvkNew.dwGenKeyFlags = 0; // CRYPT_MACHINE_KEYSET; // no flags
  290. CertInfo.pwszCALocation = CaLocation; // ignore for no-ui enrollment
  291. CertInfo.pwszCAName = CaName;
  292. CertInfo.dwPostOption = 0; // CRYPTUI_WIZ_CERT_REQUEST_POST_ON_CSP;
  293. KeyUsage.cUsageIdentifier = 1;
  294. UsageString = szOID_PKIX_KP_SERVER_AUTH;
  295. KeyUsage.rgpszUsageIdentifier = &UsageString;
  296. CertInfo.pKeyUsage = &KeyUsage;
  297. CertInfo.pwszFriendlyName = NULL; // friendly name is optional
  298. CertInfo.pwszDescription = NULL; // description is optional
  299. //
  300. // Request a certificate
  301. //
  302. if (!CryptUIWizCertRequest(
  303. CRYPTUI_WIZ_NO_UI,
  304. NULL, // no window
  305. NULL, // no title
  306. &CertInfo,
  307. &CertContext,
  308. &Status
  309. ))
  310. {
  311. printf("CryptUIWizCertRequest failed: 0x%x\n",GetLastError());
  312. return;
  313. }
  314. //
  315. // Check the real status
  316. //
  317. if (Status == CRYPTUI_WIZ_CERT_REQUEST_STATUS_SUCCEEDED)
  318. {
  319. printf("Cert request succeeded!\n");
  320. }
  321. if (Status == CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_ERROR)
  322. {
  323. printf("Cert request failed: request error\n");
  324. }
  325. if (Status == CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_DENIED)
  326. {
  327. printf("Cert request denied\n");
  328. }
  329. if (Status == CRYPTUI_WIZ_CERT_REQUEST_STATUS_ISSUED_SEPARATELY)
  330. {
  331. printf("Cert request issued seperately\n");
  332. }
  333. if (Status == CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNDER_SUBMISSION)
  334. {
  335. printf("Cert request under submission\n");
  336. }
  337. return;
  338. }
  339. VOID
  340. TestScLogonRoutine(
  341. IN ULONG Count,
  342. IN LPSTR Pin
  343. )
  344. {
  345. NTSTATUS Status;
  346. PKERB_SMART_CARD_LOGON LogonInfo;
  347. ULONG LogonInfoSize = sizeof(KERB_SMART_CARD_LOGON);
  348. BOOLEAN WasEnabled;
  349. STRING PinString;
  350. STRING Name;
  351. ULONG Dummy;
  352. HANDLE LogonHandle = NULL;
  353. ULONG PackageId;
  354. TOKEN_SOURCE SourceContext;
  355. PKERB_SMART_CARD_PROFILE Profile = NULL;
  356. ULONG ProfileSize;
  357. LUID LogonId;
  358. HANDLE TokenHandle = NULL;
  359. QUOTA_LIMITS Quotas;
  360. NTSTATUS SubStatus;
  361. WCHAR UserNameString[100];
  362. ULONG NameLength = 100;
  363. PUCHAR Where;
  364. ULONG Index;
  365. HANDLE ScHandle = NULL;
  366. PBYTE ScLogonInfo = NULL;
  367. ULONG ScLogonInfoSize;
  368. ULONG WaitResult = 0;
  369. PCCERT_CONTEXT CertContext = NULL;
  370. printf("Waiting for smart card insertion\n");
  371. //
  372. // First register for insertion notification
  373. //
  374. Status = ScHelperInitialize();
  375. if (!NT_SUCCESS(Status))
  376. {
  377. printf("Failed to initialize schelper: 0x%x\n",Status);
  378. return;
  379. }
  380. ScHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
  381. if (ScHandle == NULL)
  382. {
  383. printf("Failed to create event: %d\n",GetLastError());
  384. return;
  385. }
  386. Status = ScHelperWatchForSas(
  387. ScHandle,
  388. &ScLogonInfo
  389. );
  390. if (!NT_SUCCESS(Status))
  391. {
  392. printf("Failed to watch for SAS: 0x%x\n",Status);
  393. return;
  394. }
  395. WaitResult = WaitForSingleObject(ScHandle,INFINITE);
  396. if (WaitResult != WAIT_OBJECT_0)
  397. {
  398. printf("Failed to wait for single object: %d\n",GetLastError());
  399. return;
  400. }
  401. //
  402. // We should now have logon info.
  403. //
  404. if (ScLogonInfo == NULL)
  405. {
  406. printf("Failed to get logon info!\n");
  407. return;
  408. }
  409. ScLogonInfoSize = ((struct LogonInfo *) ScLogonInfo)->dwLogonInfoLen;
  410. Status = ScHelperInitializeContext(
  411. ScLogonInfo,
  412. ScLogonInfoSize
  413. );
  414. if (!NT_SUCCESS(Status))
  415. {
  416. printf("Failed to initialize context: 0x%x\n",Status);
  417. return;
  418. }
  419. ScHelperRelease(ScLogonInfo);
  420. RtlInitString(
  421. &PinString,
  422. Pin
  423. );
  424. LogonInfoSize += (PinString.Length+1 ) * sizeof(WCHAR) + ScLogonInfoSize;
  425. LogonInfo = (PKERB_SMART_CARD_LOGON) LocalAlloc(LMEM_ZEROINIT, LogonInfoSize);
  426. LogonInfo->MessageType = KerbSmartCardLogon;
  427. Where = (PUCHAR) (LogonInfo + 1);
  428. LogonInfo->Pin.Buffer = (LPWSTR) Where;
  429. LogonInfo->Pin.MaximumLength = (USHORT) LogonInfoSize;
  430. RtlAnsiStringToUnicodeString(
  431. &LogonInfo->Pin,
  432. &PinString,
  433. FALSE
  434. );
  435. Where += LogonInfo->Pin.Length + sizeof(WCHAR);
  436. LogonInfo->CspDataLength = ScLogonInfoSize;
  437. LogonInfo->CspData = Where;
  438. RtlCopyMemory(
  439. LogonInfo->CspData,
  440. ScLogonInfo,
  441. ScLogonInfoSize
  442. );
  443. Where += ScLogonInfoSize;
  444. //
  445. // Turn on the TCB privilege
  446. //
  447. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  448. if (!NT_SUCCESS(Status))
  449. {
  450. printf("Failed to adjust privilege: 0x%x\n",Status);
  451. return;
  452. }
  453. RtlInitString(
  454. &Name,
  455. "SspTest"
  456. );
  457. Status = LsaRegisterLogonProcess(
  458. &Name,
  459. &LogonHandle,
  460. &Dummy
  461. );
  462. if (!NT_SUCCESS(Status))
  463. {
  464. printf("Failed to register as a logon process: 0x%x\n",Status);
  465. return;
  466. }
  467. strncpy(
  468. SourceContext.SourceName,
  469. "ssptest ",sizeof(SourceContext.SourceName)
  470. );
  471. NtAllocateLocallyUniqueId(
  472. &SourceContext.SourceIdentifier
  473. );
  474. RtlInitString(
  475. &Name,
  476. MICROSOFT_KERBEROS_NAME_A
  477. );
  478. Status = LsaLookupAuthenticationPackage(
  479. LogonHandle,
  480. &Name,
  481. &PackageId
  482. );
  483. if (!NT_SUCCESS(Status))
  484. {
  485. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  486. return;
  487. }
  488. //
  489. // Now call LsaLogonUser
  490. //
  491. RtlInitString(
  492. &Name,
  493. "ssptest"
  494. );
  495. for (Index = 0; Index < Count ; Index++ )
  496. {
  497. printf("Logging on with PIN %s\n",Pin);
  498. Status = LsaLogonUser(
  499. LogonHandle,
  500. &Name,
  501. Interactive,
  502. PackageId,
  503. LogonInfo,
  504. LogonInfoSize,
  505. NULL, // no token groups
  506. &SourceContext,
  507. (PVOID *) &Profile,
  508. &ProfileSize,
  509. &LogonId,
  510. &TokenHandle,
  511. &Quotas,
  512. &SubStatus
  513. );
  514. if (!NT_SUCCESS(Status))
  515. {
  516. printf("lsalogonuser failed: 0x%x\n",Status);
  517. return;
  518. }
  519. if (!NT_SUCCESS(SubStatus))
  520. {
  521. printf("LsalogonUser failed: substatus = 0x%x\n",SubStatus);
  522. return;
  523. }
  524. ImpersonateLoggedOnUser( TokenHandle );
  525. GetUserName(UserNameString,&NameLength);
  526. printf("Username = %ws\n",UserNameString);
  527. RevertToSelf();
  528. NtClose(TokenHandle);
  529. if (Profile->Profile.MessageType = MsV1_0SmartCardProfile)
  530. {
  531. CertContext = CertCreateCertificateContext(
  532. X509_ASN_ENCODING,
  533. Profile->CertificateData,
  534. Profile->CertificateSize
  535. );
  536. if (CertContext == NULL)
  537. {
  538. printf("Failed to create cert context: 0x%x\n",GetLastError());
  539. }
  540. else
  541. {
  542. printf("Built certificate context\n");
  543. CertFreeCertificateContext( CertContext );
  544. CertContext = NULL;
  545. }
  546. }
  547. else
  548. {
  549. printf("No certificate in profile\n");
  550. }
  551. LsaFreeReturnBuffer(Profile);
  552. Profile = NULL;
  553. }
  554. }
  555. VOID
  556. PrintKdcName(
  557. IN PKERB_INTERNAL_NAME Name
  558. )
  559. {
  560. ULONG Index;
  561. for (Index = 0; Index < Name->NameCount ; Index++ )
  562. {
  563. printf(" %wZ ",&Name->Names[Index]);
  564. }
  565. printf("\n");
  566. }
  567. VOID
  568. TestCallPackageRoutine(
  569. IN LPWSTR Function
  570. )
  571. {
  572. NTSTATUS Status;
  573. BOOLEAN WasEnabled;
  574. STRING Name;
  575. ULONG Dummy;
  576. HANDLE LogonHandle = NULL;
  577. ULONG PackageId;
  578. KERB_DEBUG_REQUEST DebugRequest;
  579. KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
  580. PKERB_QUERY_TKT_CACHE_RESPONSE CacheResponse = NULL;
  581. ULONG Index;
  582. PVOID Response;
  583. ULONG ResponseSize;
  584. NTSTATUS SubStatus;
  585. BOOLEAN Trusted = TRUE;
  586. //
  587. // Turn on the TCB privilege
  588. //
  589. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  590. if (!NT_SUCCESS(Status))
  591. {
  592. printf("Failed to adjust privilege: 0x%x\n",Status);
  593. Trusted = FALSE;
  594. }
  595. RtlInitString(
  596. &Name,
  597. "SspTest"
  598. );
  599. if (Trusted)
  600. {
  601. Status = LsaRegisterLogonProcess(
  602. &Name,
  603. &LogonHandle,
  604. &Dummy
  605. );
  606. }
  607. else
  608. {
  609. Status = LsaConnectUntrusted(
  610. &LogonHandle
  611. );
  612. }
  613. if (!NT_SUCCESS(Status))
  614. {
  615. printf("Failed to register as a logon process: 0x%x\n",Status);
  616. return;
  617. }
  618. RtlInitString(
  619. &Name,
  620. MICROSOFT_KERBEROS_NAME_A
  621. );
  622. Status = LsaLookupAuthenticationPackage(
  623. LogonHandle,
  624. &Name,
  625. &PackageId
  626. );
  627. if (!NT_SUCCESS(Status))
  628. {
  629. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  630. return;
  631. }
  632. if (_wcsicmp(Function,L"bp") == 0)
  633. {
  634. DebugRequest.MessageType = KerbDebugRequestMessage;
  635. DebugRequest.DebugRequest = KERB_DEBUG_REQ_BREAKPOINT;
  636. Status = LsaCallAuthenticationPackage(
  637. LogonHandle,
  638. PackageId,
  639. &DebugRequest,
  640. sizeof(DebugRequest),
  641. &Response,
  642. &ResponseSize,
  643. &SubStatus
  644. );
  645. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  646. {
  647. printf("bp failed: 0x%x, 0x %x\n",Status, SubStatus);
  648. }
  649. }
  650. else if (_wcsicmp(Function,L"tickets") == 0)
  651. {
  652. CacheRequest.MessageType = KerbQueryTicketCacheMessage;
  653. CacheRequest.LogonId.LowPart = 0;
  654. CacheRequest.LogonId.HighPart = 0;
  655. Status = LsaCallAuthenticationPackage(
  656. LogonHandle,
  657. PackageId,
  658. &CacheRequest,
  659. sizeof(CacheRequest),
  660. (PVOID *) &CacheResponse,
  661. &ResponseSize,
  662. &SubStatus
  663. );
  664. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  665. {
  666. printf("bp failed: 0x%x, 0x %x\n",Status, SubStatus);
  667. }
  668. else
  669. {
  670. printf("Cached Tickets:\n");
  671. for (Index = 0; Index < CacheResponse->CountOfTickets ; Index++ )
  672. {
  673. printf("\tServer: %wZ\n",&CacheResponse->Tickets[Index].ServerName);
  674. PrintTime("\t\tEnd Time: ",CacheResponse->Tickets[Index].EndTime);
  675. PrintTime("\t\tRenew Time: ",CacheResponse->Tickets[Index].RenewTime);
  676. }
  677. }
  678. }
  679. if (LogonHandle != NULL)
  680. {
  681. LsaDeregisterLogonProcess(LogonHandle);
  682. }
  683. if (CacheResponse != NULL)
  684. {
  685. LsaFreeReturnBuffer(CacheResponse);
  686. }
  687. }
  688. int __cdecl
  689. main(
  690. IN int argc,
  691. IN char ** argv
  692. )
  693. /*++
  694. Routine Description:
  695. Drive the NtLmSsp service
  696. Arguments:
  697. argc - the number of command-line arguments.
  698. argv - an array of pointers to the arguments.
  699. Return Value:
  700. Exit status
  701. --*/
  702. {
  703. LPSTR argument;
  704. int i;
  705. ULONG j;
  706. ULONG Iterations;
  707. LPSTR Pin;
  708. LPWSTR PackageFunction;
  709. ULONG ContextReq = 0;
  710. WCHAR ContainerName[100];
  711. WCHAR CaName[100];
  712. WCHAR CaLocation[100];
  713. WCHAR ServiceName[100];
  714. enum {
  715. NoAction,
  716. #define LOGON_PARAM "/Logon"
  717. #define LOGON_PARAM2 "/Logon:"
  718. TestLogon,
  719. #define PACKAGE_PARAM "/callpackage:"
  720. TestPackage,
  721. #define CERT_PARAM "/getcert"
  722. GetCert,
  723. } Action = NoAction;
  724. //
  725. // Loop through the arguments handle each in turn
  726. //
  727. for ( i=1; i<argc; i++ ) {
  728. argument = argv[i];
  729. //
  730. // Handle /ConfigureService
  731. //
  732. if ( _strnicmp( argument, LOGON_PARAM, sizeof(LOGON_PARAM)-1 ) == 0 ) {
  733. if ( Action != NoAction ) {
  734. goto Usage;
  735. }
  736. Iterations = 1;
  737. if ( _strnicmp( argument, LOGON_PARAM2, sizeof(LOGON_PARAM2)-1 ) == 0 ) {
  738. sscanf(&argument[sizeof(LOGON_PARAM2)-1], "%d",&Iterations);
  739. }
  740. Action = TestLogon;
  741. if (argc < i + 1)
  742. {
  743. goto Usage;
  744. }
  745. Pin = argv[++i];
  746. } else if ( _strnicmp( argument, PACKAGE_PARAM, sizeof(PACKAGE_PARAM) - 1 ) == 0 ) {
  747. if ( Action != NoAction ) {
  748. goto Usage;
  749. }
  750. argument = &argument[sizeof(PACKAGE_PARAM)-1];
  751. PackageFunction = NetpAllocWStrFromStr( argument );
  752. Action = TestPackage;
  753. } else if ( _stricmp( argument, CERT_PARAM) == 0 ) {
  754. if ( Action != NoAction ) {
  755. goto Usage;
  756. }
  757. if (argc < i + 4)
  758. {
  759. goto Usage;
  760. }
  761. mbstowcs(ServiceName,argv[++i],100);
  762. mbstowcs(ContainerName,argv[++i],100);
  763. mbstowcs(CaLocation,argv[++i],100);
  764. mbstowcs(CaName,argv[++i],100);
  765. Action = GetCert;
  766. } else {
  767. printf("Invalid parameter : %s\n",argument);
  768. goto Usage;
  769. }
  770. }
  771. //
  772. // Perform the action requested
  773. //
  774. switch ( Action ) {
  775. case TestPackage:
  776. TestCallPackageRoutine(PackageFunction);
  777. break;
  778. case TestLogon :
  779. TestScLogonRoutine(
  780. Iterations,
  781. Pin
  782. );
  783. break;
  784. case GetCert:
  785. TestGetKdcCert(
  786. ServiceName,
  787. ContainerName,
  788. CaLocation,
  789. CaName
  790. );
  791. }
  792. return 0;
  793. Usage:
  794. printf("%s /logon username password [domainname]\n",argv[0]);
  795. printf("%s /testssp [/package:pacakgename] [/target:targetname] [/user:username] [/serveruser:username]\n",
  796. argv[0]);
  797. printf("%s /getcert service-name container-name ca-location ca-name\n",
  798. argv[0]);
  799. return 0;
  800. }