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.

5846 lines
164 KiB

  1. /*--
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. ssptest.c
  5. Abstract:
  6. Test program for the NtLmSsp service.
  7. Author:
  8. 28-Jun-1993 (cliffv)
  9. Environment:
  10. User mode only.
  11. Contains NT-specific code.
  12. Requires ANSI C extensions: slash-slash comments, long external names.
  13. Revision History:
  14. --*/
  15. //
  16. // Common include files.
  17. //
  18. #define SECURITY_KERBEROS
  19. #define SECURITY_PACKAGE
  20. #include "krbprgma.h"
  21. #include <nt.h>
  22. #include <ntrtl.h>
  23. #include <nturtl.h>
  24. #include <ntseapi.h>
  25. #include <ntlsa.h>
  26. #include <windef.h>
  27. #include <winbase.h>
  28. #include <winsvc.h> // Needed for service controller APIs
  29. #include <lmcons.h>
  30. #include <lmerr.h>
  31. #include <lmaccess.h>
  32. #include <lmsname.h>
  33. #include <rpc.h>
  34. #include <stdio.h> // printf
  35. #include <stdlib.h> // strtoul
  36. #include <netlib.h> // NetpGetLocalDomainId
  37. #include <tstring.h> // NetpAllocWStrFromWStr
  38. #include <security.h> // General definition of a Security Support Provider
  39. #include <secint.h>
  40. #include <kerbcomm.h>
  41. #include <wincrypt.h>
  42. #include <kerbdefs.h>
  43. #include <kerblist.h>
  44. #include <negossp.h>
  45. #include <kerbcli.h>
  46. #include <lm.h>
  47. #include <malloc.h>
  48. #include <alloca.h>
  49. BOOLEAN QuietMode = FALSE; // Don't be verbose
  50. BOOLEAN DumpToken = FALSE;
  51. BOOLEAN DoAnsi = FALSE;
  52. ULONG RecursionDepth = 0;
  53. CredHandle ServerCredHandleStorage;
  54. PCredHandle ServerCredHandle = NULL;
  55. ULONG MaxRecursionDepth = 1;
  56. #define STRING_OR_NULL(_x_) (((_x_) != NULL) ? (_x_) : L"<null>")
  57. #define STRING_OR_NULLA(_x_) (((_x_) != NULL) ? (_x_) : "<null>")
  58. #define RTN_ERROR 13
  59. char * ImpLevels[] = {"Anonymous", "Identification", "Impersonation", "Delegation"};
  60. #define ImpLevel(x) ((x < (sizeof(ImpLevels) / sizeof(char *))) ? ImpLevels[x] : "Illegal!")
  61. #define SATYPE_USER 1
  62. #define SATYPE_GROUP 2
  63. #define SATYPE_PRIV 3
  64. WCHAR * GetPrivName(PLUID pPriv)
  65. {
  66. switch (pPriv->LowPart)
  67. {
  68. case SE_CREATE_TOKEN_PRIVILEGE:
  69. return(SE_CREATE_TOKEN_NAME);
  70. case SE_ASSIGNPRIMARYTOKEN_PRIVILEGE:
  71. return(SE_ASSIGNPRIMARYTOKEN_NAME);
  72. case SE_LOCK_MEMORY_PRIVILEGE:
  73. return(SE_LOCK_MEMORY_NAME);
  74. case SE_INCREASE_QUOTA_PRIVILEGE:
  75. return(SE_INCREASE_QUOTA_NAME);
  76. case SE_UNSOLICITED_INPUT_PRIVILEGE:
  77. return(SE_UNSOLICITED_INPUT_NAME);
  78. case SE_TCB_PRIVILEGE:
  79. return(SE_TCB_NAME);
  80. case SE_SECURITY_PRIVILEGE:
  81. return(SE_SECURITY_NAME);
  82. case SE_TAKE_OWNERSHIP_PRIVILEGE:
  83. return(SE_TAKE_OWNERSHIP_NAME);
  84. case SE_LOAD_DRIVER_PRIVILEGE:
  85. return(SE_LOAD_DRIVER_NAME);
  86. case SE_SYSTEM_PROFILE_PRIVILEGE:
  87. return(SE_SYSTEM_PROFILE_NAME);
  88. case SE_SYSTEMTIME_PRIVILEGE:
  89. return(SE_SYSTEMTIME_NAME);
  90. case SE_PROF_SINGLE_PROCESS_PRIVILEGE:
  91. return(SE_PROF_SINGLE_PROCESS_NAME);
  92. case SE_INC_BASE_PRIORITY_PRIVILEGE:
  93. return(SE_INC_BASE_PRIORITY_NAME);
  94. case SE_CREATE_PAGEFILE_PRIVILEGE:
  95. return(SE_CREATE_PAGEFILE_NAME);
  96. case SE_CREATE_PERMANENT_PRIVILEGE:
  97. return(SE_CREATE_PERMANENT_NAME);
  98. case SE_BACKUP_PRIVILEGE:
  99. return(SE_BACKUP_NAME);
  100. case SE_RESTORE_PRIVILEGE:
  101. return(SE_RESTORE_NAME);
  102. case SE_SHUTDOWN_PRIVILEGE:
  103. return(SE_SHUTDOWN_NAME);
  104. case SE_DEBUG_PRIVILEGE:
  105. return(SE_DEBUG_NAME);
  106. case SE_AUDIT_PRIVILEGE:
  107. return(SE_AUDIT_NAME);
  108. case SE_SYSTEM_ENVIRONMENT_PRIVILEGE:
  109. return(SE_SYSTEM_ENVIRONMENT_NAME);
  110. case SE_CHANGE_NOTIFY_PRIVILEGE:
  111. return(SE_CHANGE_NOTIFY_NAME);
  112. case SE_REMOTE_SHUTDOWN_PRIVILEGE:
  113. return(SE_REMOTE_SHUTDOWN_NAME);
  114. case SE_UNDOCK_PRIVILEGE:
  115. return(SE_UNDOCK_NAME);
  116. case SE_SYNC_AGENT_PRIVILEGE:
  117. return(SE_SYNC_AGENT_NAME);
  118. case SE_ENABLE_DELEGATION_PRIVILEGE:
  119. return(SE_ENABLE_DELEGATION_NAME);
  120. default:
  121. return(L"Unknown Privilege");
  122. }
  123. }
  124. void
  125. DumpLuidAttr(PLUID_AND_ATTRIBUTES pLA,
  126. int LAType)
  127. {
  128. printf("0x%x%08x", pLA->Luid.HighPart, pLA->Luid.LowPart);
  129. printf(" %-32ws", GetPrivName(&pLA->Luid));
  130. if (LAType == SATYPE_PRIV)
  131. {
  132. printf(" Attributes - ");
  133. if (pLA->Attributes & SE_PRIVILEGE_ENABLED)
  134. {
  135. printf("Enabled ");
  136. }
  137. if (pLA->Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT)
  138. {
  139. printf("Default ");
  140. }
  141. }
  142. }
  143. void
  144. LocalDumpSid(PSID pxSid)
  145. {
  146. UNICODE_STRING ucsSid;
  147. RtlConvertSidToUnicodeString(&ucsSid, pxSid, TRUE);
  148. printf(" %wZ", &ucsSid);
  149. RtlFreeUnicodeString(&ucsSid);
  150. }
  151. void
  152. DumpSidAttr(PSID_AND_ATTRIBUTES pSA,
  153. int SAType)
  154. {
  155. LocalDumpSid(pSA->Sid);
  156. if (SAType == SATYPE_GROUP)
  157. {
  158. printf("\tAttributes - ");
  159. if (pSA->Attributes & SE_GROUP_MANDATORY)
  160. {
  161. printf("Mandatory ");
  162. }
  163. if (pSA->Attributes & SE_GROUP_ENABLED_BY_DEFAULT)
  164. {
  165. printf("Default ");
  166. }
  167. if (pSA->Attributes & SE_GROUP_ENABLED)
  168. {
  169. printf("Enabled ");
  170. }
  171. if (pSA->Attributes & SE_GROUP_OWNER)
  172. {
  173. printf("Owner ");
  174. }
  175. if (pSA->Attributes & SE_GROUP_LOGON_ID)
  176. {
  177. printf("LogonId ");
  178. }
  179. }
  180. }
  181. void
  182. PrintToken(HANDLE hToken)
  183. {
  184. PTOKEN_USER pTUser;
  185. PTOKEN_GROUPS pTGroups;
  186. PTOKEN_PRIVILEGES pTPrivs;
  187. PTOKEN_PRIMARY_GROUP pTPrimaryGroup;
  188. TOKEN_STATISTICS TStats;
  189. ULONG cbRetInfo;
  190. NTSTATUS status;
  191. DWORD i;
  192. DWORD dwSessionId;
  193. pTUser = (PTOKEN_USER) alloca (256);
  194. pTGroups = (PTOKEN_GROUPS) alloca (4096);
  195. pTPrivs = (PTOKEN_PRIVILEGES) alloca (1024);
  196. pTPrimaryGroup = (PTOKEN_PRIMARY_GROUP) alloca (128);
  197. if ( pTUser == NULL ||
  198. pTGroups == NULL ||
  199. pTPrivs == NULL ||
  200. pTPrimaryGroup == NULL ) {
  201. printf( "Failed to allocate memory\n" );
  202. return;
  203. }
  204. status = NtQueryInformationToken( hToken,
  205. TokenSessionId,
  206. &dwSessionId,
  207. sizeof(dwSessionId),
  208. &cbRetInfo);
  209. if (!NT_SUCCESS(status))
  210. {
  211. printf("Failed to query token: %#x\n", status);
  212. return;
  213. }
  214. printf("TS Session ID: %x\n", dwSessionId);
  215. status = NtQueryInformationToken( hToken,
  216. TokenUser,
  217. pTUser,
  218. 256,
  219. &cbRetInfo);
  220. if (!NT_SUCCESS(status))
  221. {
  222. printf("Failed to query token: %#x\n", status);
  223. return;
  224. }
  225. printf("User\n ");
  226. DumpSidAttr(&pTUser->User, SATYPE_USER);
  227. printf("\nGroups");
  228. status = NtQueryInformationToken( hToken,
  229. TokenGroups,
  230. pTGroups,
  231. 4096,
  232. &cbRetInfo);
  233. for (i = 0; i < pTGroups->GroupCount ; i++ )
  234. {
  235. printf("\n %02d ", i);
  236. DumpSidAttr(&pTGroups->Groups[i], SATYPE_GROUP);
  237. }
  238. status = NtQueryInformationToken( hToken,
  239. TokenPrimaryGroup,
  240. pTPrimaryGroup,
  241. 128,
  242. &cbRetInfo);
  243. printf("\nPrimary Group:\n ");
  244. LocalDumpSid(pTPrimaryGroup->PrimaryGroup);
  245. printf("\nPrivs\n");
  246. status = NtQueryInformationToken( hToken,
  247. TokenPrivileges,
  248. pTPrivs,
  249. 1024,
  250. &cbRetInfo);
  251. if (!NT_SUCCESS(status))
  252. {
  253. printf("NtQueryInformationToken returned %#x\n", status);
  254. return;
  255. }
  256. for (i = 0; i < pTPrivs->PrivilegeCount ; i++ )
  257. {
  258. printf("\n %02d ", i);
  259. DumpLuidAttr(&pTPrivs->Privileges[i], SATYPE_PRIV);
  260. }
  261. status = NtQueryInformationToken( hToken,
  262. TokenStatistics,
  263. &TStats,
  264. sizeof(TStats),
  265. &cbRetInfo);
  266. printf("\n\nAuth ID %x:%x\n", TStats.AuthenticationId.HighPart, TStats.AuthenticationId.LowPart);
  267. printf("Impersonation Level: %s\n", ImpLevel(TStats.ImpersonationLevel));
  268. printf("TokenType %s\n", TStats.TokenType == TokenPrimary ? "Primary" : "Impersonation");
  269. }
  270. VOID
  271. DumpBuffer(
  272. PVOID Buffer,
  273. DWORD BufferSize
  274. )
  275. /*++
  276. Routine Description:
  277. Dumps the buffer content on to the debugger output.
  278. Arguments:
  279. Buffer: buffer pointer.
  280. BufferSize: size of the buffer.
  281. Return Value:
  282. none
  283. --*/
  284. {
  285. #define NUM_CHARS 16
  286. DWORD i, limit;
  287. CHAR TextBuffer[NUM_CHARS + 1];
  288. LPBYTE BufferPtr = Buffer;
  289. printf("------------------------------------\n");
  290. //
  291. // Hex dump of the bytes
  292. //
  293. limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
  294. for (i = 0; i < limit; i++) {
  295. if (i < BufferSize) {
  296. printf("%02x ", BufferPtr[i]);
  297. if (BufferPtr[i] < 31 ) {
  298. TextBuffer[i % NUM_CHARS] = '.';
  299. } else if (BufferPtr[i] == '\0') {
  300. TextBuffer[i % NUM_CHARS] = ' ';
  301. } else {
  302. TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i];
  303. }
  304. } else {
  305. printf(" ");
  306. TextBuffer[i % NUM_CHARS] = ' ';
  307. }
  308. if ((i + 1) % NUM_CHARS == 0) {
  309. TextBuffer[NUM_CHARS] = 0;
  310. printf(" %s\n", TextBuffer);
  311. }
  312. }
  313. printf("------------------------------------\n");
  314. }
  315. VOID
  316. PrintTime(
  317. LPSTR Comment,
  318. TimeStamp ConvertTime
  319. )
  320. /*++
  321. Routine Description:
  322. Print the specified time
  323. Arguments:
  324. Comment - Comment to print in front of the time
  325. Time - Local time to print
  326. Return Value:
  327. None
  328. --*/
  329. {
  330. LARGE_INTEGER LocalTime;
  331. NTSTATUS Status;
  332. LocalTime.HighPart = ConvertTime.HighPart;
  333. LocalTime.LowPart = ConvertTime.LowPart;
  334. Status = RtlSystemTimeToLocalTime( &ConvertTime, &LocalTime );
  335. if (!NT_SUCCESS( Status )) {
  336. printf( "Can't convert time from GMT to Local time\n" );
  337. LocalTime = ConvertTime;
  338. }
  339. printf( "%s", Comment );
  340. //
  341. // If the time is infinite,
  342. // just say so.
  343. //
  344. if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
  345. printf( "Infinite\n" );
  346. //
  347. // Otherwise print it more clearly
  348. //
  349. } else {
  350. TIME_FIELDS TimeFields;
  351. RtlTimeToTimeFields( &LocalTime, &TimeFields );
  352. printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
  353. TimeFields.Month,
  354. TimeFields.Day,
  355. TimeFields.Year,
  356. TimeFields.Hour,
  357. TimeFields.Minute,
  358. TimeFields.Second );
  359. }
  360. }
  361. VOID
  362. PrintStatus(
  363. NET_API_STATUS NetStatus
  364. )
  365. /*++
  366. Routine Description:
  367. Print a net status code.
  368. Arguments:
  369. NetStatus - The net status code to print.
  370. Return Value:
  371. None
  372. --*/
  373. {
  374. printf( "Status = %lu 0x%lx", NetStatus, NetStatus );
  375. switch (NetStatus) {
  376. case NERR_Success:
  377. printf( " NERR_Success" );
  378. break;
  379. case NERR_DCNotFound:
  380. printf( " NERR_DCNotFound" );
  381. break;
  382. case ERROR_LOGON_FAILURE:
  383. printf( " ERROR_LOGON_FAILURE" );
  384. break;
  385. case ERROR_ACCESS_DENIED:
  386. printf( " ERROR_ACCESS_DENIED" );
  387. break;
  388. case ERROR_NOT_SUPPORTED:
  389. printf( " ERROR_NOT_SUPPORTED" );
  390. break;
  391. case ERROR_NO_LOGON_SERVERS:
  392. printf( " ERROR_NO_LOGON_SERVERS" );
  393. break;
  394. case ERROR_NO_SUCH_DOMAIN:
  395. printf( " ERROR_NO_SUCH_DOMAIN" );
  396. break;
  397. case ERROR_NO_TRUST_LSA_SECRET:
  398. printf( " ERROR_NO_TRUST_LSA_SECRET" );
  399. break;
  400. case ERROR_NO_TRUST_SAM_ACCOUNT:
  401. printf( " ERROR_NO_TRUST_SAM_ACCOUNT" );
  402. break;
  403. case ERROR_DOMAIN_TRUST_INCONSISTENT:
  404. printf( " ERROR_DOMAIN_TRUST_INCONSISTENT" );
  405. break;
  406. case ERROR_BAD_NETPATH:
  407. printf( " ERROR_BAD_NETPATH" );
  408. break;
  409. case ERROR_FILE_NOT_FOUND:
  410. printf( " ERROR_FILE_NOT_FOUND" );
  411. break;
  412. case NERR_NetNotStarted:
  413. printf( " NERR_NetNotStarted" );
  414. break;
  415. case NERR_WkstaNotStarted:
  416. printf( " NERR_WkstaNotStarted" );
  417. break;
  418. case NERR_ServerNotStarted:
  419. printf( " NERR_ServerNotStarted" );
  420. break;
  421. case NERR_BrowserNotStarted:
  422. printf( " NERR_BrowserNotStarted" );
  423. break;
  424. case NERR_ServiceNotInstalled:
  425. printf( " NERR_ServiceNotInstalled" );
  426. break;
  427. case NERR_BadTransactConfig:
  428. printf( " NERR_BadTransactConfig" );
  429. break;
  430. case SEC_E_NO_SPM:
  431. printf( " SEC_E_NO_SPM" );
  432. break;
  433. case SEC_E_BAD_PKGID:
  434. printf( " SEC_E_BAD_PKGID" ); break;
  435. case SEC_E_NOT_OWNER:
  436. printf( " SEC_E_NOT_OWNER" ); break;
  437. case SEC_E_CANNOT_INSTALL:
  438. printf( " SEC_E_CANNOT_INSTALL" ); break;
  439. case SEC_E_INVALID_TOKEN:
  440. printf( " SEC_E_INVALID_TOKEN" ); break;
  441. case SEC_E_CANNOT_PACK:
  442. printf( " SEC_E_CANNOT_PACK" ); break;
  443. case SEC_E_QOP_NOT_SUPPORTED:
  444. printf( " SEC_E_QOP_NOT_SUPPORTED" ); break;
  445. case SEC_E_NO_IMPERSONATION:
  446. printf( " SEC_E_NO_IMPERSONATION" ); break;
  447. case SEC_E_LOGON_DENIED:
  448. printf( " SEC_E_LOGON_DENIED" ); break;
  449. case SEC_E_UNKNOWN_CREDENTIALS:
  450. printf( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
  451. case SEC_E_NO_CREDENTIALS:
  452. printf( " SEC_E_NO_CREDENTIALS" ); break;
  453. case SEC_E_MESSAGE_ALTERED:
  454. printf( " SEC_E_MESSAGE_ALTERED" ); break;
  455. case SEC_E_OUT_OF_SEQUENCE:
  456. printf( " SEC_E_OUT_OF_SEQUENCE" ); break;
  457. case SEC_E_INSUFFICIENT_MEMORY:
  458. printf( " SEC_E_INSUFFICIENT_MEMORY" ); break;
  459. case SEC_E_INVALID_HANDLE:
  460. printf( " SEC_E_INVALID_HANDLE" ); break;
  461. case SEC_E_NOT_SUPPORTED:
  462. printf( " SEC_E_NOT_SUPPORTED" ); break;
  463. }
  464. printf( "\n" );
  465. }
  466. HANDLE
  467. FindAndOpenWinlogon(
  468. VOID
  469. )
  470. {
  471. PSYSTEM_PROCESS_INFORMATION SystemInfo ;
  472. PSYSTEM_PROCESS_INFORMATION Walk ;
  473. NTSTATUS Status ;
  474. UNICODE_STRING Winlogon ;
  475. HANDLE Process ;
  476. SystemInfo = LocalAlloc( LMEM_FIXED, sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024 );
  477. if ( !SystemInfo )
  478. {
  479. return NULL ;
  480. }
  481. Status = NtQuerySystemInformation(
  482. SystemProcessInformation,
  483. SystemInfo,
  484. sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024,
  485. NULL );
  486. if ( !NT_SUCCESS( Status ) )
  487. {
  488. return NULL ;
  489. }
  490. RtlInitUnicodeString( &Winlogon, L"winlogon.exe" );
  491. Walk = SystemInfo ;
  492. while ( RtlCompareUnicodeString( &Walk->ImageName, &Winlogon, TRUE ) != 0 )
  493. {
  494. if ( Walk->NextEntryOffset == 0 )
  495. {
  496. Walk = NULL ;
  497. break;
  498. }
  499. Walk = (PSYSTEM_PROCESS_INFORMATION) ((PUCHAR) Walk + Walk->NextEntryOffset );
  500. }
  501. if ( !Walk )
  502. {
  503. LocalFree( SystemInfo );
  504. return NULL ;
  505. }
  506. Process = OpenProcess( PROCESS_QUERY_INFORMATION,
  507. FALSE,
  508. HandleToUlong(Walk->UniqueProcessId) );
  509. LocalFree( SystemInfo );
  510. return Process ;
  511. }
  512. BOOLEAN
  513. GetCredentialsHandle(
  514. OUT PCredHandle CredentialsHandle,
  515. IN LPWSTR PackageName,
  516. IN LPWSTR UserName,
  517. IN LPWSTR DomainName,
  518. IN LPWSTR Password,
  519. IN ULONG Flags
  520. )
  521. {
  522. TimeStamp Lifetime;
  523. NTSTATUS SecStatus;
  524. SEC_WINNT_AUTH_IDENTITY_W Identity = {0};
  525. PSEC_WINNT_AUTH_IDENTITY_W AuthIdentity = NULL;
  526. if ((UserName != NULL) ||
  527. (DomainName != NULL) ||
  528. (Password != NULL))
  529. {
  530. Identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  531. if (UserName != NULL)
  532. {
  533. Identity.UserLength = (ULONG) wcslen(UserName);
  534. Identity.User = UserName;
  535. }
  536. if (DomainName != NULL)
  537. {
  538. Identity.DomainLength = (ULONG) wcslen(DomainName);
  539. Identity.Domain = DomainName;
  540. }
  541. if (Password != NULL)
  542. {
  543. Identity.PasswordLength = (ULONG) wcslen(Password);
  544. Identity.Password = Password;
  545. }
  546. AuthIdentity = &Identity;
  547. }
  548. SecStatus = AcquireCredentialsHandle(
  549. NULL, // New principal
  550. PackageName,
  551. Flags,
  552. NULL,
  553. AuthIdentity,
  554. NULL,
  555. NULL,
  556. CredentialsHandle,
  557. &Lifetime );
  558. if (!NT_SUCCESS(SecStatus))
  559. {
  560. printf("Failed to acquire credentials: 0x%x\n",SecStatus);
  561. return(FALSE);
  562. }
  563. else
  564. {
  565. return(TRUE);
  566. }
  567. }
  568. VOID
  569. TestQuickISC(
  570. IN LPWSTR TargetNameU
  571. )
  572. /*++
  573. Routine Description:
  574. Test base SSP functionality
  575. Arguments:
  576. None
  577. Return Value:
  578. None
  579. --*/
  580. {
  581. SECURITY_STATUS SecStatus;
  582. SECURITY_STATUS InitStatus;
  583. CredHandle CredentialHandle2;
  584. CtxtHandle ClientContextHandle;
  585. TimeStamp Lifetime;
  586. TimeStamp CurrentTime;
  587. TimeStamp stLocal;
  588. ULONG ContextAttributes;
  589. ULONG PackageCount, Index;
  590. PSecPkgInfo PackageInfo = NULL;
  591. static int Calls;
  592. ULONG ClientFlags;
  593. LPWSTR DomainName = NULL;
  594. LPWSTR UserName = NULL;
  595. SecBufferDesc NegotiateDesc;
  596. SecBuffer NegotiateBuffer;
  597. SecBuffer ChallengeBuffer;
  598. SecBuffer AuthenticateBuffer;
  599. SecPkgCredentials_Names CredNames;
  600. LPWSTR PackageName = NEGOSSP_NAME_W;
  601. CredNames.sUserName = NULL;
  602. NegotiateBuffer.pvBuffer = NULL;
  603. ChallengeBuffer.pvBuffer = NULL;
  604. AuthenticateBuffer.pvBuffer = NULL;
  605. DomainName = _wgetenv(L"USERDOMAIN");
  606. UserName = _wgetenv(L"USERNAME");
  607. printf("Recursion depth = %d\n",RecursionDepth);
  608. //
  609. // Get info about the security packages.
  610. //
  611. SecStatus = EnumerateSecurityPackages( &PackageCount, &PackageInfo );
  612. if ( SecStatus != STATUS_SUCCESS ) {
  613. printf( "EnumerateSecurityPackages failed:" );
  614. PrintStatus( SecStatus );
  615. return;
  616. }
  617. if ( !QuietMode ) {
  618. printf( "PackageCount: %ld\n", PackageCount );
  619. for (Index = 0; Index < PackageCount ; Index++ )
  620. {
  621. printf( "Package %d:\n",Index);
  622. printf( "Name: %ws Comment: %ws\n", PackageInfo[Index].Name, PackageInfo[Index].Comment );
  623. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  624. PackageInfo[Index].fCapabilities,
  625. PackageInfo[Index].wVersion,
  626. PackageInfo[Index].wRPCID,
  627. PackageInfo[Index].cbMaxToken );
  628. }
  629. }
  630. //
  631. // Get info about the security packages.
  632. //
  633. SecStatus = QuerySecurityPackageInfo( PackageName, &PackageInfo );
  634. if ( SecStatus != STATUS_SUCCESS ) {
  635. printf( "QuerySecurityPackageInfo failed:" );
  636. PrintStatus( SecStatus );
  637. return;
  638. }
  639. if ( !QuietMode ) {
  640. printf( "Name: %ws Comment: %ws\n", PackageInfo->Name, PackageInfo->Comment );
  641. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  642. PackageInfo->fCapabilities,
  643. PackageInfo->wVersion,
  644. PackageInfo->wRPCID,
  645. PackageInfo->cbMaxToken );
  646. }
  647. SecStatus = AcquireCredentialsHandle(
  648. NULL, // New principal
  649. PackageName,
  650. SECPKG_CRED_OUTBOUND,
  651. NULL,
  652. NULL,
  653. NULL,
  654. NULL,
  655. &CredentialHandle2,
  656. &Lifetime );
  657. if ( SecStatus != STATUS_SUCCESS ) {
  658. printf( "AcquireCredentialsHandle failed: " );
  659. PrintStatus( SecStatus );
  660. return;
  661. }
  662. if ( !QuietMode ) {
  663. printf( "CredentialHandle2: 0x%lx 0x%lx ",
  664. CredentialHandle2.dwLower, CredentialHandle2.dwUpper );
  665. PrintTime( "Lifetime: ", Lifetime );
  666. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  667. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  668. PrintTime( "Current Time: ", stLocal);
  669. }
  670. //
  671. // Get the NegotiateMessage (ClientSide)
  672. //
  673. NegotiateDesc.ulVersion = 0;
  674. NegotiateDesc.cBuffers = 1;
  675. NegotiateDesc.pBuffers = &NegotiateBuffer;
  676. NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  677. NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
  678. NegotiateBuffer.pvBuffer = LocalAlloc( 0, NegotiateBuffer.cbBuffer );
  679. if ( NegotiateBuffer.pvBuffer == NULL ) {
  680. printf( "Allocate NegotiateMessage failed: 0x%ld\n", GetLastError() );
  681. return;
  682. }
  683. ClientFlags = ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY; // USE_DCE_STYLE | ISC_REQ_MUTUAL_AUTH | ISC_REQ_USE_SESSION_KEY; // | ISC_REQ_DATAGRAM;
  684. InitStatus = InitializeSecurityContext(
  685. &CredentialHandle2,
  686. NULL, // No Client context yet
  687. TargetNameU, // Faked target name
  688. ClientFlags,
  689. 0, // Reserved 1
  690. SECURITY_NATIVE_DREP,
  691. NULL, // No initial input token
  692. 0, // Reserved 2
  693. &ClientContextHandle,
  694. &NegotiateDesc,
  695. &ContextAttributes,
  696. &Lifetime );
  697. if ( InitStatus != STATUS_SUCCESS ) {
  698. if ( !QuietMode || !NT_SUCCESS(InitStatus) ) {
  699. printf( "InitializeSecurityContext (negotiate): " );
  700. PrintStatus( InitStatus );
  701. }
  702. if ( !NT_SUCCESS(InitStatus) ) {
  703. return;
  704. }
  705. }
  706. SecStatus = FreeCredentialsHandle( &CredentialHandle2 );
  707. if ( SecStatus != STATUS_SUCCESS ) {
  708. printf( "FreeCredentialsHandle failed: " );
  709. PrintStatus( SecStatus );
  710. return;
  711. }
  712. }
  713. VOID
  714. TestSspRoutine(
  715. IN LPWSTR PackageName,
  716. IN LPWSTR UserNameU,
  717. IN LPWSTR DomainNameU,
  718. IN LPWSTR PasswordU,
  719. IN LPWSTR ServerUserNameU,
  720. IN LPWSTR ServerDomainNameU,
  721. IN LPWSTR ServerPasswordU,
  722. IN LPWSTR TargetNameU,
  723. IN LPWSTR PackageListU,
  724. IN ULONG ContextReq,
  725. IN ULONG CredFlags
  726. )
  727. /*++
  728. Routine Description:
  729. Test base SSP functionality
  730. Arguments:
  731. None
  732. Return Value:
  733. None
  734. --*/
  735. {
  736. SECURITY_STATUS SecStatus;
  737. SECURITY_STATUS AcceptStatus;
  738. SECURITY_STATUS InitStatus;
  739. CredHandle CredentialHandle2;
  740. CtxtHandle ClientContextHandle;
  741. CtxtHandle ServerContextHandle;
  742. TimeStamp Lifetime;
  743. TimeStamp CurrentTime;
  744. TimeStamp stLocal;
  745. ULONG ContextAttributes;
  746. ULONG PackageCount, Index;
  747. PSecPkgInfo PackageInfo = NULL;
  748. static int Calls;
  749. ULONG ClientFlags;
  750. ULONG ServerFlags;
  751. BOOLEAN AcquiredServerCred = FALSE;
  752. LPWSTR DomainName = NULL;
  753. LPWSTR UserName = NULL;
  754. WCHAR TargetName[100];
  755. PSEC_WINNT_AUTH_IDENTITY_EXW AuthIdentity = NULL;
  756. PSEC_WINNT_AUTH_IDENTITY_W ServerAuthIdentity = NULL;
  757. PUCHAR Where;
  758. HANDLE TokenHandle = NULL;
  759. ULONG CredSize;
  760. SecBuffer MarshalledContext;
  761. SecBufferDesc NegotiateDesc;
  762. SecBuffer NegotiateBuffer;
  763. SecBufferDesc ChallengeDesc;
  764. SecBuffer ChallengeBuffer;
  765. SecBufferDesc AuthenticateDesc;
  766. SecBuffer AuthenticateBuffer;
  767. PBYTE pbWholeBuffer;
  768. ULONG cbWholeBuffer;
  769. SecPkgContext_Sizes ContextSizes;
  770. SecPkgContext_Flags ContextFlags;
  771. SecPkgContext_Lifespan ContextLifespan;
  772. SecPkgContext_DceInfo ContextDceInfo;
  773. UCHAR ContextNamesBuffer[sizeof(SecPkgContext_Names)+UNLEN*sizeof(WCHAR)];
  774. PSecPkgContext_Names ContextNames = (PSecPkgContext_Names) ContextNamesBuffer;
  775. SecPkgContext_NativeNames NativeNames;
  776. SecPkgContext_NativeNamesA NativeNamesA;
  777. SecPkgCredentials_Names CredNames;
  778. SecPkgContext_PackageInfo ContextPackageInfo;
  779. SecPkgContext_KeyInfo KeyInfo = {0};
  780. SecBufferDesc SignMessage;
  781. SecBuffer SigBuffers[8];
  782. BYTE bDataBuffer[20];
  783. BYTE bSigBuffer[100];
  784. PBYTE pbSealBuffer;
  785. CHAR UserNameA[100];
  786. CHAR DomainNameA[100];
  787. CHAR PasswordA[100];
  788. if (PackageName == NULL)
  789. {
  790. PackageName = MICROSOFT_KERBEROS_NAME_W;
  791. }
  792. if (!DoAnsi)
  793. {
  794. if ((UserNameU != NULL) || (DomainNameU != NULL) || (PasswordU != NULL) || (PackageListU != NULL) || (CredFlags != 0))
  795. {
  796. CredSize = (((ULONG) ((UserNameU != NULL) ? wcslen(UserNameU) + 1 : 0) +
  797. (ULONG) ((DomainNameU != NULL) ? wcslen(DomainNameU) + 1 : 0) +
  798. (ULONG) ((PackageListU != NULL) ? wcslen(PackageListU) + 1 : 0) +
  799. (ULONG) ((PasswordU != NULL) ? wcslen(PasswordU) + 1 : 0)) * sizeof(WCHAR)) +
  800. (ULONG) sizeof(SEC_WINNT_AUTH_IDENTITY_EXW);
  801. AuthIdentity = (PSEC_WINNT_AUTH_IDENTITY_EXW) LocalAlloc(LMEM_ZEROINIT,CredSize);
  802. if (NULL == AuthIdentity)
  803. {
  804. printf( "Failed : Allocation of AuthIdentity\n" );
  805. return;
  806. }
  807. AuthIdentity->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
  808. Where = (PUCHAR) (AuthIdentity + 1);
  809. if (UserNameU != NULL)
  810. {
  811. AuthIdentity->UserLength = (ULONG) wcslen(UserNameU);
  812. AuthIdentity->User = (LPWSTR) Where;
  813. wcscpy(
  814. (LPWSTR) Where,
  815. UserNameU
  816. );
  817. Where += (wcslen(UserNameU) + 1) * sizeof(WCHAR);
  818. }
  819. if (DomainNameU != NULL)
  820. {
  821. AuthIdentity->DomainLength = (ULONG) wcslen(DomainNameU);
  822. AuthIdentity->Domain = (LPWSTR) Where;
  823. wcscpy(
  824. (LPWSTR) Where,
  825. DomainNameU
  826. );
  827. Where += (wcslen(DomainNameU) + 1) * sizeof(WCHAR);
  828. }
  829. if (PasswordU != NULL)
  830. {
  831. AuthIdentity->PasswordLength = (ULONG) wcslen(PasswordU);
  832. AuthIdentity->Password = (LPWSTR) Where;
  833. wcscpy(
  834. (LPWSTR) Where,
  835. PasswordU
  836. );
  837. Where += (wcslen(PasswordU) + 1) * sizeof(WCHAR);
  838. }
  839. AuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE | CredFlags;
  840. if (PackageListU != NULL)
  841. {
  842. AuthIdentity->PackageListLength = (ULONG) wcslen(PackageListU);
  843. AuthIdentity->PackageList = (LPWSTR) Where;
  844. wcscpy(
  845. (LPWSTR) Where,
  846. PackageListU
  847. );
  848. Where += (wcslen(PackageListU) + 1) * sizeof(WCHAR);
  849. AuthIdentity->Length = sizeof(SEC_WINNT_AUTH_IDENTITY_EXW);
  850. }
  851. }
  852. }
  853. else
  854. {
  855. if ((UserNameU != NULL) || (DomainNameU != NULL) || (PasswordU != NULL) || (PackageListU != NULL))
  856. {
  857. PSEC_WINNT_AUTH_IDENTITY_A Identity;
  858. CredSize = sizeof(SEC_WINNT_AUTH_IDENTITY_A);
  859. Identity = (PSEC_WINNT_AUTH_IDENTITY_A) LocalAlloc(LMEM_ZEROINIT,CredSize);
  860. if (NULL == Identity)
  861. {
  862. printf( "Failed : Allocation of Identity\n" );
  863. return;
  864. }
  865. if (UserNameU != NULL)
  866. {
  867. Identity->UserLength = (ULONG) wcslen(UserNameU);
  868. Identity->User = (unsigned char *) UserNameA;
  869. wcstombs(UserNameA,UserNameU,100);
  870. }
  871. if (DomainNameU != NULL)
  872. {
  873. Identity->DomainLength = (ULONG) wcslen(DomainNameU);
  874. Identity->Domain = (unsigned char *) DomainNameA;
  875. wcstombs(DomainNameA,DomainNameU,100);
  876. }
  877. if (PasswordU != NULL)
  878. {
  879. Identity->PasswordLength = (ULONG) wcslen(PasswordU);
  880. Identity->Password = (unsigned char *) PasswordA;
  881. wcstombs(PasswordA,PasswordU,100);
  882. }
  883. Identity->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  884. AuthIdentity = (PSEC_WINNT_AUTH_IDENTITY_EXW) Identity;
  885. }
  886. }
  887. if ((ServerUserNameU != NULL) || (ServerDomainNameU != NULL) || (ServerPasswordU != NULL))
  888. {
  889. CredSize = ((ULONG) ((ServerUserNameU != NULL) ? wcslen(ServerUserNameU) + 1 : 0) +
  890. (ULONG) ((ServerDomainNameU != NULL) ? wcslen(ServerDomainNameU) + 1 : 0) +
  891. (ULONG) (((ServerPasswordU != NULL) ? wcslen(ServerPasswordU) + 1 : 0))) * sizeof(WCHAR) +
  892. (ULONG) sizeof(SEC_WINNT_AUTH_IDENTITY);
  893. ServerAuthIdentity = (PSEC_WINNT_AUTH_IDENTITY_W) LocalAlloc(LMEM_ZEROINIT,CredSize);
  894. if (NULL == ServerAuthIdentity)
  895. {
  896. printf( "Failed : Allocation of ServerAuthIdentity\n" );
  897. return;
  898. }
  899. Where = (PUCHAR) (ServerAuthIdentity + 1);
  900. if (ServerUserNameU != NULL)
  901. {
  902. ServerAuthIdentity->UserLength = (ULONG) wcslen(ServerUserNameU);
  903. ServerAuthIdentity->User = (LPWSTR) Where;
  904. wcscpy(
  905. (LPWSTR) Where,
  906. ServerUserNameU
  907. );
  908. Where += (wcslen(ServerUserNameU) + 1) * sizeof(WCHAR);
  909. }
  910. if (ServerDomainNameU != NULL)
  911. {
  912. ServerAuthIdentity->DomainLength = (ULONG) wcslen(ServerDomainNameU);
  913. ServerAuthIdentity->Domain = (LPWSTR) Where;
  914. wcscpy(
  915. (LPWSTR) Where,
  916. ServerDomainNameU
  917. );
  918. Where += (wcslen(ServerDomainNameU) + 1) * sizeof(WCHAR);
  919. }
  920. if (ServerPasswordU != NULL)
  921. {
  922. ServerAuthIdentity->PasswordLength = (ULONG) wcslen(ServerPasswordU);
  923. ServerAuthIdentity->Password = (LPWSTR) Where;
  924. wcscpy(
  925. (LPWSTR) Where,
  926. ServerPasswordU
  927. );
  928. Where += (wcslen(ServerPasswordU) + 1) * sizeof(WCHAR);
  929. }
  930. ServerAuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE | SEC_WINNT_AUTH_IDENTITY_MARSHALLED;
  931. }
  932. CredNames.sUserName = NULL;
  933. NegotiateBuffer.pvBuffer = NULL;
  934. ChallengeBuffer.pvBuffer = NULL;
  935. AuthenticateBuffer.pvBuffer = NULL;
  936. DomainName = _wgetenv(L"USERDOMAIN");
  937. UserName = _wgetenv(L"USERNAME");
  938. printf("Recursion depth = %d\n",RecursionDepth);
  939. //
  940. // Get info about the security packages.
  941. //
  942. SecStatus = EnumerateSecurityPackages( &PackageCount, &PackageInfo );
  943. if ( SecStatus != STATUS_SUCCESS ) {
  944. printf( "EnumerateSecurityPackages failed:" );
  945. PrintStatus( SecStatus );
  946. return;
  947. }
  948. if ( !QuietMode ) {
  949. printf( "PackageCount: %ld\n", PackageCount );
  950. for (Index = 0; Index < PackageCount ; Index++ )
  951. {
  952. printf( "Package %d:\n",Index);
  953. printf( "Name: %ws Comment: %ws\n", PackageInfo[Index].Name, PackageInfo[Index].Comment );
  954. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  955. PackageInfo[Index].fCapabilities,
  956. PackageInfo[Index].wVersion,
  957. PackageInfo[Index].wRPCID,
  958. PackageInfo[Index].cbMaxToken );
  959. }
  960. }
  961. //
  962. // Get info about the security packages.
  963. //
  964. SecStatus = QuerySecurityPackageInfo( PackageName, &PackageInfo );
  965. if ( SecStatus != STATUS_SUCCESS ) {
  966. printf( "QuerySecurityPackageInfo failed:" );
  967. PrintStatus( SecStatus );
  968. return;
  969. }
  970. if ( !QuietMode ) {
  971. printf( "Name: %ws Comment: %ws\n", PackageInfo->Name, PackageInfo->Comment );
  972. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  973. PackageInfo->fCapabilities,
  974. PackageInfo->wVersion,
  975. PackageInfo->wRPCID,
  976. PackageInfo->cbMaxToken );
  977. }
  978. //
  979. // Acquire a credential handle for the server side
  980. //
  981. if (ServerCredHandle == NULL)
  982. {
  983. ServerCredHandle = &ServerCredHandleStorage;
  984. AcquiredServerCred = TRUE;
  985. SecStatus = AcquireCredentialsHandle(
  986. NULL,
  987. PackageName,
  988. SECPKG_CRED_INBOUND,
  989. NULL,
  990. ServerAuthIdentity,
  991. NULL,
  992. NULL,
  993. ServerCredHandle,
  994. &Lifetime );
  995. if ( SecStatus != STATUS_SUCCESS ) {
  996. printf( "AcquireCredentialsHandle failed: ");
  997. PrintStatus( SecStatus );
  998. return;
  999. }
  1000. if ( !QuietMode ) {
  1001. printf( "ServerCredHandle: 0x%lx 0x%lx ",
  1002. ServerCredHandle->dwLower, ServerCredHandle->dwUpper );
  1003. PrintTime( "Lifetime: ", Lifetime );
  1004. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  1005. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  1006. PrintTime( "Current Time: ", stLocal);
  1007. }
  1008. }
  1009. //
  1010. // Acquire a credential handle for the client side
  1011. //
  1012. if (!DoAnsi)
  1013. {
  1014. SecStatus = AcquireCredentialsHandle(
  1015. NULL, // New principal
  1016. PackageName,
  1017. SECPKG_CRED_OUTBOUND,
  1018. NULL,
  1019. AuthIdentity,
  1020. NULL,
  1021. NULL,
  1022. &CredentialHandle2,
  1023. &Lifetime );
  1024. }
  1025. else
  1026. {
  1027. CHAR AnsiPackageName[100];
  1028. wcstombs(AnsiPackageName, PackageName, 100);
  1029. SecStatus = AcquireCredentialsHandleA(
  1030. NULL, // New principal
  1031. AnsiPackageName,
  1032. SECPKG_CRED_OUTBOUND,
  1033. NULL,
  1034. AuthIdentity,
  1035. NULL,
  1036. NULL,
  1037. &CredentialHandle2,
  1038. &Lifetime );
  1039. }
  1040. if ( SecStatus != STATUS_SUCCESS ) {
  1041. printf( "AcquireCredentialsHandle failed: " );
  1042. PrintStatus( SecStatus );
  1043. return;
  1044. }
  1045. if ( !QuietMode ) {
  1046. printf( "CredentialHandle2: 0x%lx 0x%lx ",
  1047. CredentialHandle2.dwLower, CredentialHandle2.dwUpper );
  1048. PrintTime( "Lifetime: ", Lifetime );
  1049. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  1050. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  1051. PrintTime( "Current Time: ", stLocal);
  1052. }
  1053. //
  1054. // Query some cred attributes
  1055. //
  1056. SecStatus = QueryCredentialsAttributes(
  1057. &CredentialHandle2,
  1058. SECPKG_CRED_ATTR_NAMES,
  1059. &CredNames );
  1060. if ( SecStatus != STATUS_SUCCESS ) {
  1061. printf( "QueryCredentialsAttributes (Client) (names): " );
  1062. PrintStatus( SecStatus );
  1063. // if ( !NT_SUCCESS(SecStatus) ) {
  1064. // return;
  1065. // }
  1066. }
  1067. else
  1068. {
  1069. printf("Client credential names: %ws\n",CredNames.sUserName);
  1070. FreeContextBuffer(CredNames.sUserName);
  1071. }
  1072. //
  1073. // Do the same for the client
  1074. //
  1075. SecStatus = QueryCredentialsAttributes(
  1076. ServerCredHandle,
  1077. SECPKG_CRED_ATTR_NAMES,
  1078. &CredNames );
  1079. if ( SecStatus != STATUS_SUCCESS ) {
  1080. printf( "QueryCredentialsAttributes (Server) (names): " );
  1081. PrintStatus( SecStatus );
  1082. // if ( !NT_SUCCESS(SecStatus) ) {
  1083. // return;
  1084. // }
  1085. } else {
  1086. printf("Server credential names: %ws\n",CredNames.sUserName);
  1087. FreeContextBuffer(CredNames.sUserName);
  1088. }
  1089. //
  1090. // Get the NegotiateMessage (ClientSide)
  1091. //
  1092. NegotiateDesc.ulVersion = 0;
  1093. NegotiateDesc.cBuffers = 1;
  1094. NegotiateDesc.pBuffers = &NegotiateBuffer;
  1095. NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  1096. NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
  1097. NegotiateBuffer.pvBuffer = LocalAlloc( 0, NegotiateBuffer.cbBuffer );
  1098. if ( NegotiateBuffer.pvBuffer == NULL ) {
  1099. printf( "Allocate NegotiateMessage failed: 0x%ld\n", GetLastError() );
  1100. return;
  1101. }
  1102. if (ContextReq == 0)
  1103. {
  1104. ClientFlags = ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_MUTUAL_AUTH ; //ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY; // USE_DCE_STYLE | ISC_REQ_MUTUAL_AUTH | ISC_REQ_USE_SESSION_KEY; // | ISC_REQ_DATAGRAM;
  1105. }
  1106. else
  1107. {
  1108. ClientFlags = ContextReq;
  1109. }
  1110. Calls++;
  1111. if (ARGUMENT_PRESENT(TargetNameU))
  1112. {
  1113. wcscpy(TargetName, TargetNameU);
  1114. }
  1115. else if (ARGUMENT_PRESENT(ServerUserNameU) && ARGUMENT_PRESENT(ServerDomainNameU))
  1116. {
  1117. wcscpy(
  1118. TargetName,
  1119. ServerDomainNameU
  1120. );
  1121. wcscat(
  1122. TargetName,
  1123. L"\\"
  1124. );
  1125. wcscat(
  1126. TargetName,
  1127. ServerUserNameU
  1128. );
  1129. }
  1130. else
  1131. {
  1132. wcscpy(
  1133. TargetName,
  1134. DomainName
  1135. );
  1136. wcscat(
  1137. TargetName,
  1138. L"\\"
  1139. );
  1140. wcscat(
  1141. TargetName,
  1142. UserName
  1143. );
  1144. }
  1145. InitStatus = InitializeSecurityContext(
  1146. &CredentialHandle2,
  1147. NULL, // No Client context yet
  1148. TargetName, // Faked target name
  1149. ClientFlags,
  1150. 0, // Reserved 1
  1151. SECURITY_NATIVE_DREP,
  1152. NULL, // No initial input token
  1153. 0, // Reserved 2
  1154. &ClientContextHandle,
  1155. &NegotiateDesc,
  1156. &ContextAttributes,
  1157. &Lifetime );
  1158. if ( InitStatus != STATUS_SUCCESS ) {
  1159. if ( !QuietMode || !NT_SUCCESS(InitStatus) ) {
  1160. printf( "InitializeSecurityContext (negotiate): " );
  1161. PrintStatus( InitStatus );
  1162. }
  1163. if ( !NT_SUCCESS(InitStatus) ) {
  1164. return;
  1165. }
  1166. }
  1167. if ( !QuietMode ) {
  1168. printf( "\n\nNegotiate Message:\n" );
  1169. printf( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  1170. ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
  1171. ContextAttributes );
  1172. PrintTime( "Lifetime: ", Lifetime );
  1173. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  1174. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  1175. PrintTime( "Current Time: ", stLocal);
  1176. DumpBuffer( NegotiateBuffer.pvBuffer, NegotiateBuffer.cbBuffer );
  1177. }
  1178. //
  1179. // Get the ChallengeMessage (ServerSide)
  1180. //
  1181. NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
  1182. ChallengeDesc.ulVersion = 0;
  1183. ChallengeDesc.cBuffers = 1;
  1184. ChallengeDesc.pBuffers = &ChallengeBuffer;
  1185. ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
  1186. ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
  1187. ChallengeBuffer.pvBuffer = LocalAlloc( 0, ChallengeBuffer.cbBuffer );
  1188. if ( ChallengeBuffer.pvBuffer == NULL ) {
  1189. printf( "Allocate ChallengeMessage failed: 0x%ld\n", GetLastError() );
  1190. return;
  1191. }
  1192. ServerFlags = ASC_REQ_EXTENDED_ERROR;
  1193. AcceptStatus = AcceptSecurityContext(
  1194. ServerCredHandle,
  1195. NULL, // No Server context yet
  1196. &NegotiateDesc,
  1197. ServerFlags,
  1198. SECURITY_NATIVE_DREP,
  1199. &ServerContextHandle,
  1200. &ChallengeDesc,
  1201. &ContextAttributes,
  1202. &Lifetime );
  1203. if ( AcceptStatus != STATUS_SUCCESS ) {
  1204. if ( !QuietMode || !NT_SUCCESS(AcceptStatus) ) {
  1205. printf( "AcceptSecurityContext (Challenge): " );
  1206. PrintStatus( AcceptStatus );
  1207. }
  1208. if ( !NT_SUCCESS(AcceptStatus) ) {
  1209. return;
  1210. }
  1211. }
  1212. if ( !QuietMode ) {
  1213. printf( "\n\nChallenge Message:\n" );
  1214. printf( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  1215. ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
  1216. ContextAttributes );
  1217. PrintTime( "Lifetime: ", Lifetime );
  1218. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  1219. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  1220. PrintTime( "Current Time: ", stLocal);
  1221. DumpBuffer( ChallengeBuffer.pvBuffer, ChallengeBuffer.cbBuffer );
  1222. }
  1223. Redo:
  1224. if (InitStatus != STATUS_SUCCESS)
  1225. {
  1226. //
  1227. // Get the AuthenticateMessage (ClientSide)
  1228. //
  1229. ChallengeBuffer.BufferType |= SECBUFFER_READONLY;
  1230. AuthenticateDesc.ulVersion = 0;
  1231. AuthenticateDesc.cBuffers = 1;
  1232. AuthenticateDesc.pBuffers = &AuthenticateBuffer;
  1233. AuthenticateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  1234. AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
  1235. if (AuthenticateBuffer.pvBuffer == NULL) {
  1236. AuthenticateBuffer.pvBuffer = LocalAlloc( 0, AuthenticateBuffer.cbBuffer );
  1237. if ( AuthenticateBuffer.pvBuffer == NULL ) {
  1238. printf( "Allocate AuthenticateMessage failed: 0x%ld\n", GetLastError() );
  1239. return;
  1240. }
  1241. }
  1242. InitStatus = InitializeSecurityContext(
  1243. NULL,
  1244. &ClientContextHandle,
  1245. TargetName,
  1246. ClientFlags,
  1247. 0, // Reserved 1
  1248. SECURITY_NATIVE_DREP,
  1249. &ChallengeDesc,
  1250. 0, // Reserved 2
  1251. &ClientContextHandle,
  1252. &AuthenticateDesc,
  1253. &ContextAttributes,
  1254. &Lifetime );
  1255. if ( InitStatus != STATUS_SUCCESS ) {
  1256. printf( "InitializeSecurityContext (Authenticate): " );
  1257. PrintStatus( InitStatus );
  1258. if ( !NT_SUCCESS(InitStatus) ) {
  1259. return;
  1260. }
  1261. }
  1262. if ( !QuietMode ) {
  1263. printf( "\n\nAuthenticate Message:\n" );
  1264. printf( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  1265. ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
  1266. ContextAttributes );
  1267. PrintTime( "Lifetime: ", Lifetime );
  1268. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  1269. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  1270. PrintTime( "Current Time: ", stLocal);
  1271. DumpBuffer( AuthenticateBuffer.pvBuffer, AuthenticateBuffer.cbBuffer );
  1272. }
  1273. if (AcceptStatus != STATUS_SUCCESS)
  1274. {
  1275. //
  1276. // Finally authenticate the user (ServerSide)
  1277. //
  1278. AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
  1279. ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
  1280. ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
  1281. AcceptStatus = AcceptSecurityContext(
  1282. NULL,
  1283. &ServerContextHandle,
  1284. &AuthenticateDesc,
  1285. ServerFlags,
  1286. SECURITY_NATIVE_DREP,
  1287. &ServerContextHandle,
  1288. &ChallengeDesc,
  1289. &ContextAttributes,
  1290. &Lifetime );
  1291. if ( AcceptStatus != STATUS_SUCCESS ) {
  1292. printf( "AcceptSecurityContext (Challenge): " );
  1293. PrintStatus( AcceptStatus );
  1294. if ( !NT_SUCCESS(AcceptStatus) ) {
  1295. return;
  1296. }
  1297. }
  1298. if ( !QuietMode ) {
  1299. printf( "\n\nFinal Authentication:\n" );
  1300. printf( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  1301. ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
  1302. ContextAttributes );
  1303. PrintTime( "Lifetime: ", Lifetime );
  1304. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  1305. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  1306. PrintTime( "Current Time: ", stLocal);
  1307. printf(" \n" );
  1308. DumpBuffer( ChallengeBuffer.pvBuffer, ChallengeBuffer.cbBuffer );
  1309. }
  1310. if (InitStatus != STATUS_SUCCESS)
  1311. {
  1312. goto Redo;
  1313. }
  1314. }
  1315. }
  1316. #ifdef notdef
  1317. //
  1318. // Now make a third call to Initialize to check that RPC can
  1319. // reauthenticate.
  1320. //
  1321. AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
  1322. SecStatus = InitializeSecurityContext(
  1323. NULL,
  1324. &ClientContextHandle,
  1325. L"\\\\Frank\\IPC$", // Faked target name
  1326. 0,
  1327. 0, // Reserved 1
  1328. SECURITY_NATIVE_DREP,
  1329. NULL,
  1330. 0, // Reserved 2
  1331. &ClientContextHandle,
  1332. &AuthenticateDesc,
  1333. &ContextAttributes,
  1334. &Lifetime );
  1335. if ( SecStatus != STATUS_SUCCESS ) {
  1336. printf( "InitializeSecurityContext (Re-Authenticate): " );
  1337. PrintStatus( SecStatus );
  1338. if ( !NT_SUCCESS(SecStatus) ) {
  1339. return;
  1340. }
  1341. }
  1342. //
  1343. // Now try to re-authenticate the user (ServerSide)
  1344. //
  1345. AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
  1346. SecStatus = AcceptSecurityContext(
  1347. NULL,
  1348. &ServerContextHandle,
  1349. &AuthenticateDesc,
  1350. ServerFlags,
  1351. SECURITY_NATIVE_DREP,
  1352. &ServerContextHandle,
  1353. NULL,
  1354. &ContextAttributes,
  1355. &Lifetime );
  1356. if ( SecStatus != STATUS_SUCCESS ) {
  1357. printf( "AcceptSecurityContext (Re-authenticate): " );
  1358. PrintStatus( SecStatus );
  1359. if ( !NT_SUCCESS(SecStatus) ) {
  1360. return;
  1361. }
  1362. }
  1363. #endif
  1364. //
  1365. // Query as many attributes as possible
  1366. //
  1367. SecStatus = QueryContextAttributes(
  1368. &ServerContextHandle,
  1369. SECPKG_ATTR_SIZES,
  1370. &ContextSizes );
  1371. if ( SecStatus != STATUS_SUCCESS ) {
  1372. printf( "QueryContextAttributes (sizes): " );
  1373. PrintStatus( SecStatus );
  1374. if ( !NT_SUCCESS(SecStatus) ) {
  1375. return;
  1376. }
  1377. }
  1378. SecStatus = QueryContextAttributes(
  1379. &ServerContextHandle,
  1380. SECPKG_ATTR_FLAGS,
  1381. &ContextFlags );
  1382. if ( SecStatus != STATUS_SUCCESS ) {
  1383. printf( "QueryContextAttributes (flags): " );
  1384. PrintStatus( SecStatus );
  1385. if ( !NT_SUCCESS(SecStatus) ) {
  1386. return;
  1387. }
  1388. }
  1389. if ( !QuietMode ) {
  1390. printf( "QueryFlags: 0x%x\n",
  1391. ContextFlags.Flags );
  1392. }
  1393. SecStatus = QueryContextAttributes(
  1394. &ServerContextHandle,
  1395. SECPKG_ATTR_KEY_INFO,
  1396. &KeyInfo );
  1397. if ( SecStatus != STATUS_SUCCESS ) {
  1398. printf( "QueryContextAttributes (KeyInfo): " );
  1399. PrintStatus( SecStatus );
  1400. if ( !NT_SUCCESS(SecStatus) ) {
  1401. return;
  1402. }
  1403. }
  1404. if ( !QuietMode ) {
  1405. printf( "QueryKeyInfo:\n");
  1406. printf("Signature algorithm = %ws\n",KeyInfo.sSignatureAlgorithmName);
  1407. printf("Encrypt algorithm = %ws\n",KeyInfo.sEncryptAlgorithmName);
  1408. printf("KeySize = %d\n",KeyInfo.KeySize);
  1409. printf("Signature Algorithm = %d\n",KeyInfo.SignatureAlgorithm);
  1410. printf("Encrypt Algorithm = %d\n",KeyInfo.EncryptAlgorithm);
  1411. FreeContextBuffer(
  1412. KeyInfo.sSignatureAlgorithmName
  1413. );
  1414. FreeContextBuffer(
  1415. KeyInfo.sEncryptAlgorithmName
  1416. );
  1417. }
  1418. SecStatus = QueryContextAttributes(
  1419. &ServerContextHandle,
  1420. SECPKG_ATTR_NAMES,
  1421. ContextNamesBuffer );
  1422. if ( SecStatus != STATUS_SUCCESS ) {
  1423. printf( "QueryContextAttributes (names): " );
  1424. PrintStatus( SecStatus );
  1425. if ( !NT_SUCCESS(SecStatus) ) {
  1426. return;
  1427. }
  1428. }
  1429. if ( !QuietMode ) {
  1430. printf( "QueryNames for ServerContextHandle: %ws\n", ContextNames->sUserName );
  1431. }
  1432. SecStatus = QueryContextAttributes(
  1433. &ClientContextHandle,
  1434. SECPKG_ATTR_NAMES,
  1435. ContextNamesBuffer );
  1436. if ( SecStatus != STATUS_SUCCESS ) {
  1437. printf( "QueryContextAttributes for client context (names): " );
  1438. PrintStatus( SecStatus );
  1439. if ( !NT_SUCCESS(SecStatus) ) {
  1440. return;
  1441. }
  1442. }
  1443. if ( !QuietMode ) {
  1444. printf( "QueryNames for ClientContextHandle: %ws\n", ContextNames->sUserName );
  1445. }
  1446. SecStatus = QueryContextAttributes(
  1447. &ServerContextHandle,
  1448. SECPKG_ATTR_NATIVE_NAMES,
  1449. &NativeNames );
  1450. if ( SecStatus != STATUS_SUCCESS ) {
  1451. printf( "QueryContextAttributes (Nativenames): " );
  1452. PrintStatus( SecStatus );
  1453. if ( !NT_SUCCESS(SecStatus) ) {
  1454. return;
  1455. }
  1456. }
  1457. if ( !QuietMode ) {
  1458. printf( "QueryNativeNames for ServerContextHandle: %ws, %ws\n",
  1459. STRING_OR_NULL(NativeNames.sClientName),
  1460. STRING_OR_NULL(NativeNames.sServerName) );
  1461. }
  1462. if (NativeNames.sClientName != NULL)
  1463. {
  1464. FreeContextBuffer(NativeNames.sClientName);
  1465. }
  1466. if (NativeNames.sServerName != NULL)
  1467. {
  1468. FreeContextBuffer(NativeNames.sServerName);
  1469. }
  1470. if (!DoAnsi)
  1471. {
  1472. SecStatus = QueryContextAttributes(
  1473. &ClientContextHandle,
  1474. SECPKG_ATTR_NATIVE_NAMES,
  1475. &NativeNames );
  1476. if ( SecStatus != STATUS_SUCCESS ) {
  1477. printf( "QueryContextAttributes (Nativenames): " );
  1478. PrintStatus( SecStatus );
  1479. if ( !NT_SUCCESS(SecStatus) ) {
  1480. return;
  1481. }
  1482. }
  1483. if ( !QuietMode ) {
  1484. printf( "QueryNativeNames for ClientContextHandle: %ws, %ws\n",
  1485. STRING_OR_NULL(NativeNames.sClientName),
  1486. STRING_OR_NULL(NativeNames.sServerName) );
  1487. }
  1488. }
  1489. else
  1490. {
  1491. SecStatus = QueryContextAttributesA(
  1492. &ClientContextHandle,
  1493. SECPKG_ATTR_NATIVE_NAMES,
  1494. &NativeNamesA );
  1495. if ( SecStatus != STATUS_SUCCESS ) {
  1496. printf( "QueryContextAttributes (Nativenames): " );
  1497. PrintStatus( SecStatus );
  1498. if ( !NT_SUCCESS(SecStatus) ) {
  1499. return;
  1500. }
  1501. }
  1502. NativeNames = *(PSecPkgContext_NativeNames) &NativeNamesA;
  1503. if ( !QuietMode ) {
  1504. printf( "QueryNativeNames for ClientContextHandle: %s, %s\n",
  1505. STRING_OR_NULLA(NativeNamesA.sClientName),
  1506. STRING_OR_NULLA(NativeNamesA.sServerName) );
  1507. }
  1508. }
  1509. if (NativeNames.sClientName != NULL)
  1510. {
  1511. FreeContextBuffer(NativeNames.sClientName);
  1512. }
  1513. if (NativeNames.sServerName != NULL)
  1514. {
  1515. FreeContextBuffer(NativeNames.sServerName);
  1516. }
  1517. SecStatus = QueryContextAttributes(
  1518. &ServerContextHandle,
  1519. SECPKG_ATTR_DCE_INFO,
  1520. &ContextDceInfo );
  1521. if ( SecStatus != STATUS_SUCCESS ) {
  1522. printf( "QueryContextAttributes (names): " );
  1523. PrintStatus( SecStatus );
  1524. if ( !NT_SUCCESS(SecStatus) ) {
  1525. return;
  1526. }
  1527. }
  1528. if ( !QuietMode ) {
  1529. printf( "QueryDceInfo: %ws\n", ContextDceInfo.pPac );
  1530. }
  1531. SecStatus = QueryContextAttributes(
  1532. &ServerContextHandle,
  1533. SECPKG_ATTR_LIFESPAN,
  1534. &ContextLifespan );
  1535. if ( SecStatus != STATUS_SUCCESS ) {
  1536. printf( "QueryContextAttributes (lifespan): " );
  1537. PrintStatus( SecStatus );
  1538. if ( !NT_SUCCESS(SecStatus) ) {
  1539. return;
  1540. }
  1541. }
  1542. if ( !QuietMode ) {
  1543. PrintTime(" Start:", ContextLifespan.tsStart );
  1544. PrintTime(" Expiry:", ContextLifespan.tsExpiry );
  1545. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  1546. FileTimeToLocalFileTime ((PFILETIME)&CurrentTime, (PFILETIME)&stLocal );
  1547. PrintTime( "Current Time: ", stLocal);
  1548. }
  1549. SecStatus = QueryContextAttributes(
  1550. &ServerContextHandle,
  1551. SECPKG_ATTR_PACKAGE_INFO,
  1552. &ContextPackageInfo );
  1553. if ( SecStatus != STATUS_SUCCESS ) {
  1554. printf( "QueryContextAttributes (PackageInfo): " );
  1555. PrintStatus( SecStatus );
  1556. if ( !NT_SUCCESS(SecStatus) ) {
  1557. return;
  1558. }
  1559. }
  1560. if ( !QuietMode ) {
  1561. printf( "PackageInfo: %ws %ws %d\n",
  1562. ContextPackageInfo.PackageInfo->Name,
  1563. ContextPackageInfo.PackageInfo->Comment,
  1564. ContextPackageInfo.PackageInfo->wRPCID
  1565. );
  1566. }
  1567. FreeContextBuffer(ContextPackageInfo.PackageInfo);
  1568. //
  1569. // Impersonate the client (ServerSide)
  1570. //
  1571. SecStatus = ImpersonateSecurityContext( &ServerContextHandle );
  1572. if ( SecStatus != STATUS_SUCCESS ) {
  1573. printf( "ImpersonateSecurityContext: " );
  1574. PrintStatus( SecStatus );
  1575. if ( !NT_SUCCESS(SecStatus) ) {
  1576. return;
  1577. }
  1578. }
  1579. //
  1580. // Get the UserName
  1581. //
  1582. {
  1583. PUNICODE_STRING UserNameLsa;
  1584. PUNICODE_STRING DomainNameLsa;
  1585. NTSTATUS Status;
  1586. Status = LsaGetUserName( &UserNameLsa, &DomainNameLsa );
  1587. if (NT_SUCCESS(Status))
  1588. {
  1589. printf("Lsa username = %wZ\\%wZ\n",DomainNameLsa, UserNameLsa );
  1590. LsaFreeMemory(
  1591. UserNameLsa->Buffer);
  1592. LsaFreeMemory(UserNameLsa);
  1593. LsaFreeMemory(DomainNameLsa->Buffer);
  1594. LsaFreeMemory(DomainNameLsa);
  1595. }
  1596. else
  1597. {
  1598. printf("Failed LsaGetUserName: 0x%x\n",Status);
  1599. }
  1600. }
  1601. //
  1602. // Do something while impersonating (Access the token)
  1603. //
  1604. {
  1605. NTSTATUS Status;
  1606. HANDLE TokenHandle = NULL;
  1607. //
  1608. // Open the token,
  1609. //
  1610. Status = NtOpenThreadToken(
  1611. NtCurrentThread(),
  1612. TOKEN_QUERY,
  1613. (BOOLEAN) TRUE, // Not really using the impersonation token
  1614. &TokenHandle );
  1615. if ( !NT_SUCCESS(Status) ) {
  1616. printf( "Access Thread token while impersonating: " );
  1617. PrintStatus( Status );
  1618. return;
  1619. } else {
  1620. if ( DumpToken )
  1621. {
  1622. PrintToken( TokenHandle );
  1623. }
  1624. (VOID) NtClose( TokenHandle );
  1625. }
  1626. }
  1627. //
  1628. // If delegation is enabled and we are below our recursion depth, try
  1629. // this again.
  1630. //
  1631. if ((ClientFlags & ISC_REQ_DELEGATE) && (++RecursionDepth < MaxRecursionDepth))
  1632. {
  1633. TestSspRoutine(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ClientFlags, CredFlags);
  1634. }
  1635. //
  1636. // RevertToSelf (ServerSide)
  1637. //
  1638. // SecStatus = RevertSecurityContext( &ServerContextHandle );
  1639. //
  1640. // if ( SecStatus != STATUS_SUCCESS ) {
  1641. // printf( "RevertSecurityContext: " );
  1642. // PrintStatus( SecStatus );
  1643. // if ( !NT_SUCCESS(SecStatus) ) {
  1644. // return;
  1645. // }
  1646. // }
  1647. #ifdef notdef
  1648. //
  1649. // Impersonate the client manually
  1650. //
  1651. SecStatus = QuerySecurityContextToken( &ServerContextHandle,&Token );
  1652. if ( SecStatus != STATUS_SUCCESS ) {
  1653. printf( "QuerySecurityContextToken: " );
  1654. PrintStatus( SecStatus );
  1655. if ( !NT_SUCCESS(SecStatus) ) {
  1656. return;
  1657. }
  1658. }
  1659. if (!ImpersonateLoggedOnUser(Token))
  1660. {
  1661. printf("Impersonate logged on user failed: %d\n",GetLastError());
  1662. return;
  1663. }
  1664. //
  1665. // Do something while impersonating (Access the token)
  1666. //
  1667. {
  1668. NTSTATUS Status;
  1669. WCHAR UserName[100];
  1670. ULONG NameLength = 100;
  1671. //
  1672. // Open the token,
  1673. //
  1674. Status = NtOpenThreadToken(
  1675. NtCurrentThread(),
  1676. TOKEN_QUERY,
  1677. (BOOLEAN) TRUE, // Not really using the impersonation token
  1678. &TokenHandle );
  1679. if ( !NT_SUCCESS(Status) ) {
  1680. printf( "Access Thread token while impersonating: " );
  1681. PrintStatus( Status );
  1682. return;
  1683. } else {
  1684. (VOID) NtClose( TokenHandle );
  1685. }
  1686. if (!GetUserName(UserName, &NameLength))
  1687. {
  1688. printf("Failed to get username: %d\n",GetLastError());
  1689. return;
  1690. }
  1691. else
  1692. {
  1693. printf("Username = %ws\n",UserName);
  1694. }
  1695. }
  1696. //
  1697. // RevertToSelf (ServerSide)
  1698. //
  1699. // if (!RevertToSelf())
  1700. // {
  1701. // printf( "RevertToSelf failed: %d\n ",GetLastError() );
  1702. // return;
  1703. // }
  1704. CloseHandle(Token);
  1705. #endif
  1706. //
  1707. // Sign a message
  1708. //
  1709. SigBuffers[1].pvBuffer = bSigBuffer;
  1710. SigBuffers[1].cbBuffer = ContextSizes.cbMaxSignature;
  1711. SigBuffers[1].BufferType = SECBUFFER_TOKEN;
  1712. SigBuffers[0].pvBuffer = bDataBuffer;
  1713. SigBuffers[0].cbBuffer = sizeof(bDataBuffer);
  1714. SigBuffers[0].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY_WITH_CHECKSUM;
  1715. memset(bDataBuffer,0xeb,sizeof(bDataBuffer));
  1716. SignMessage.pBuffers = SigBuffers;
  1717. SignMessage.cBuffers = 2;
  1718. SignMessage.ulVersion = 0;
  1719. SecStatus = MakeSignature(
  1720. &ClientContextHandle,
  1721. 0,
  1722. &SignMessage,
  1723. 0 );
  1724. if ( SecStatus != STATUS_SUCCESS ) {
  1725. printf( "MakeSignature: " );
  1726. PrintStatus( SecStatus );
  1727. if ( !NT_SUCCESS(SecStatus) ) {
  1728. return;
  1729. }
  1730. }
  1731. if ( !QuietMode ) {
  1732. printf("\n Signature: \n");
  1733. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  1734. }
  1735. //
  1736. // Verify the signature
  1737. //
  1738. SecStatus = VerifySignature(
  1739. &ServerContextHandle,
  1740. &SignMessage,
  1741. 0,
  1742. 0 );
  1743. if ( SecStatus != STATUS_SUCCESS ) {
  1744. printf( "VerifySignature: " );
  1745. PrintStatus( SecStatus );
  1746. if ( !NT_SUCCESS(SecStatus) ) {
  1747. return;
  1748. }
  1749. }
  1750. //
  1751. // Encrypt a message
  1752. //
  1753. SigBuffers[0].pvBuffer = bSigBuffer;
  1754. SigBuffers[0].cbBuffer = ContextSizes.cbSecurityTrailer;
  1755. SigBuffers[0].BufferType = SECBUFFER_TOKEN;
  1756. pbSealBuffer = (PBYTE) LocalAlloc(0, 60);
  1757. memset(
  1758. pbSealBuffer,
  1759. 0xeb,
  1760. 60
  1761. );
  1762. SigBuffers[1].cbBuffer = 60;
  1763. SigBuffers[1].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY_WITH_CHECKSUM;
  1764. SigBuffers[1].pvBuffer = pbSealBuffer;
  1765. SignMessage.pBuffers = SigBuffers;
  1766. SignMessage.cBuffers = 2;
  1767. SignMessage.ulVersion = 0;
  1768. printf("\n Pre-Encrypt Blob: \n");
  1769. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  1770. SecStatus = EncryptMessage(
  1771. &ClientContextHandle,
  1772. 0,
  1773. &SignMessage,
  1774. 0 );
  1775. if ( SecStatus != STATUS_SUCCESS ) {
  1776. printf( "EncryptMessage: " );
  1777. PrintStatus( SecStatus );
  1778. if ( !NT_SUCCESS(SecStatus) ) {
  1779. return;
  1780. }
  1781. }
  1782. if ( !QuietMode ) {
  1783. printf("\n Encrypt Blob: \n");
  1784. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  1785. printf("\n Signature: \n");
  1786. DumpBuffer(SigBuffers[0].pvBuffer,SigBuffers[0].cbBuffer);
  1787. }
  1788. //
  1789. // Decrypt the message
  1790. //
  1791. //pbSealBuffer[11] = 0xcc;
  1792. for (Index = 1; Index < 4 ; Index++ )
  1793. {
  1794. SigBuffers[Index].cbBuffer = 20;
  1795. SigBuffers[Index].pvBuffer = pbSealBuffer + (Index - 1) * 20;
  1796. SigBuffers[Index].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY_WITH_CHECKSUM;
  1797. printf("\n %x: \n", Index);
  1798. DumpBuffer(SigBuffers[Index].pvBuffer,SigBuffers[Index].cbBuffer);
  1799. }
  1800. SignMessage.cBuffers = 4;
  1801. SecStatus = DecryptMessage(
  1802. &ServerContextHandle,
  1803. &SignMessage,
  1804. 0,
  1805. 0 );
  1806. if ( SecStatus != STATUS_SUCCESS ) {
  1807. printf( "DecryptMessage: " );
  1808. PrintStatus( SecStatus );
  1809. if ( !NT_SUCCESS(SecStatus) ) {
  1810. return;
  1811. }
  1812. }
  1813. //
  1814. // Now try the opposite.
  1815. //
  1816. //
  1817. // Encrypt a message
  1818. //
  1819. #define tstsize 133
  1820. SigBuffers[0].pvBuffer = bSigBuffer;
  1821. SigBuffers[0].cbBuffer = ContextSizes.cbSecurityTrailer;
  1822. SigBuffers[0].BufferType = SECBUFFER_TOKEN;
  1823. pbSealBuffer = (PBYTE) LocalAlloc(0, tstsize);
  1824. memset(
  1825. pbSealBuffer,
  1826. 0xeb,
  1827. tstsize
  1828. );
  1829. SigBuffers[1].cbBuffer = tstsize;
  1830. SigBuffers[1].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY_WITH_CHECKSUM;
  1831. SigBuffers[1].pvBuffer = pbSealBuffer;
  1832. SignMessage.pBuffers = SigBuffers;
  1833. SignMessage.cBuffers = 2;
  1834. SignMessage.ulVersion = 0;
  1835. SecStatus = EncryptMessage(
  1836. &ServerContextHandle,
  1837. 0,
  1838. &SignMessage,
  1839. 0 );
  1840. if ( SecStatus != STATUS_SUCCESS ) {
  1841. printf( "EncryptMessage: " );
  1842. PrintStatus( SecStatus );
  1843. if ( !NT_SUCCESS(SecStatus) ) {
  1844. return;
  1845. }
  1846. }
  1847. if ( !QuietMode ) {
  1848. printf("\n Encrypt Signature: \n");
  1849. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  1850. }
  1851. //
  1852. // Decrypt the message
  1853. //
  1854. for (Index = 1; Index < 7 ; Index++ )
  1855. {
  1856. SigBuffers[Index].cbBuffer = 20;
  1857. SigBuffers[Index].pvBuffer = pbSealBuffer + (Index - 1) * 20;
  1858. SigBuffers[Index].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY_WITH_CHECKSUM;
  1859. }
  1860. //pbSealBuffer[99] = 0xec;
  1861. SigBuffers[7].cbBuffer = 13;
  1862. SigBuffers[7].pvBuffer = pbSealBuffer + 120;
  1863. SigBuffers[7].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY_WITH_CHECKSUM;
  1864. SignMessage.cBuffers = 8;
  1865. SecStatus = DecryptMessage(
  1866. &ClientContextHandle,
  1867. &SignMessage,
  1868. 0,
  1869. 0 );
  1870. if ( SecStatus != STATUS_SUCCESS ) {
  1871. printf( "DecryptMessage: " );
  1872. PrintStatus( SecStatus );
  1873. if ( !NT_SUCCESS(SecStatus) ) {
  1874. return;
  1875. }
  1876. }
  1877. #define BIG_BUFFER_SIZE 144770
  1878. SigBuffers[0].pvBuffer = bSigBuffer;
  1879. SigBuffers[0].cbBuffer = ContextSizes.cbSecurityTrailer;
  1880. SigBuffers[0].BufferType = SECBUFFER_TOKEN;
  1881. pbSealBuffer = (PBYTE) LocalAlloc(0, BIG_BUFFER_SIZE);
  1882. memset(
  1883. pbSealBuffer,
  1884. 0xeb,
  1885. BIG_BUFFER_SIZE
  1886. );
  1887. SigBuffers[1].cbBuffer = BIG_BUFFER_SIZE;
  1888. SigBuffers[1].BufferType = SECBUFFER_DATA;
  1889. SigBuffers[1].pvBuffer = pbSealBuffer;
  1890. SigBuffers[2].cbBuffer = ContextSizes.cbBlockSize;
  1891. SigBuffers[2].BufferType = SECBUFFER_PADDING;
  1892. SigBuffers[2].pvBuffer = LocalAlloc(LMEM_ZEROINIT, ContextSizes.cbBlockSize);
  1893. SignMessage.pBuffers = SigBuffers;
  1894. SignMessage.cBuffers = 3;
  1895. SignMessage.ulVersion = 0;
  1896. SecStatus = EncryptMessage(
  1897. &ClientContextHandle,
  1898. 0,
  1899. &SignMessage,
  1900. 0 );
  1901. if ( SecStatus != STATUS_SUCCESS ) {
  1902. printf( "Big EncryptMessage: " );
  1903. PrintStatus( SecStatus );
  1904. if ( !NT_SUCCESS(SecStatus) ) {
  1905. return;
  1906. }
  1907. }
  1908. //
  1909. // Decrypt the message
  1910. //
  1911. cbWholeBuffer = SigBuffers[0].cbBuffer +
  1912. SigBuffers[1].cbBuffer +
  1913. SigBuffers[2].cbBuffer;
  1914. pbWholeBuffer = (PBYTE) LocalAlloc(LMEM_ZEROINIT, cbWholeBuffer);
  1915. RtlCopyMemory(
  1916. pbWholeBuffer,
  1917. SigBuffers[0].pvBuffer,
  1918. SigBuffers[0].cbBuffer
  1919. );
  1920. RtlCopyMemory(
  1921. pbWholeBuffer + SigBuffers[0].cbBuffer,
  1922. SigBuffers[1].pvBuffer,
  1923. SigBuffers[1].cbBuffer
  1924. );
  1925. RtlCopyMemory(
  1926. pbWholeBuffer + SigBuffers[0].cbBuffer + SigBuffers[1].cbBuffer,
  1927. SigBuffers[2].pvBuffer,
  1928. SigBuffers[2].cbBuffer
  1929. );
  1930. SigBuffers[0].pvBuffer = pbWholeBuffer;
  1931. SigBuffers[0].cbBuffer = cbWholeBuffer;
  1932. SigBuffers[0].BufferType = SECBUFFER_STREAM;
  1933. SigBuffers[1].cbBuffer = 0;
  1934. SigBuffers[1].BufferType = SECBUFFER_DATA;
  1935. SigBuffers[1].pvBuffer = NULL;
  1936. SignMessage.cBuffers = 2;
  1937. SignMessage.pBuffers = SigBuffers;
  1938. SecStatus = DecryptMessage(
  1939. &ServerContextHandle,
  1940. &SignMessage,
  1941. 0,
  1942. 0 );
  1943. if ( SecStatus != STATUS_SUCCESS ) {
  1944. printf( "set Big DecryptMessage: " );
  1945. PrintStatus( SecStatus );
  1946. if ( !NT_SUCCESS(SecStatus) ) {
  1947. return;
  1948. }
  1949. }
  1950. //
  1951. // Sign a message, this time to check if it can detect a change in the
  1952. // message
  1953. //
  1954. SigBuffers[1].pvBuffer = bSigBuffer;
  1955. SigBuffers[1].cbBuffer = ContextSizes.cbMaxSignature;
  1956. SigBuffers[1].BufferType = SECBUFFER_TOKEN ;
  1957. SigBuffers[0].pvBuffer = bDataBuffer;
  1958. SigBuffers[0].cbBuffer = sizeof(bDataBuffer);
  1959. SigBuffers[0].BufferType = SECBUFFER_DATA ;
  1960. memset(bDataBuffer,0xeb,sizeof(bDataBuffer));
  1961. SignMessage.pBuffers = SigBuffers;
  1962. SignMessage.cBuffers = 2;
  1963. SignMessage.ulVersion = 0;
  1964. SecStatus = MakeSignature(
  1965. &ClientContextHandle,
  1966. 0,
  1967. &SignMessage,
  1968. 0 );
  1969. if ( SecStatus != STATUS_SUCCESS ) {
  1970. printf( "MakeSignature: " );
  1971. PrintStatus( SecStatus );
  1972. if ( !NT_SUCCESS(SecStatus) ) {
  1973. return;
  1974. }
  1975. }
  1976. if ( !QuietMode ) {
  1977. printf("\n Signature: \n");
  1978. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  1979. }
  1980. //
  1981. // Mess up the message to see if VerifySignature works
  1982. //
  1983. bDataBuffer[10] = 0xec;
  1984. //
  1985. // Verify the signature
  1986. //
  1987. printf("BAD SIGNATURE TEST\n");
  1988. SecStatus = VerifySignature(
  1989. &ServerContextHandle,
  1990. &SignMessage,
  1991. 0,
  1992. 0 );
  1993. if ( SecStatus != SEC_E_MESSAGE_ALTERED ) {
  1994. printf( "VerifySignature: " );
  1995. PrintStatus( SecStatus );
  1996. if ( !NT_SUCCESS(SecStatus) ) {
  1997. return;
  1998. }
  1999. }
  2000. //
  2001. // Export & Import contexts
  2002. //
  2003. for (Index = 0; Index < 3 ; Index++ )
  2004. {
  2005. SecStatus = ExportSecurityContext(
  2006. &ClientContextHandle,
  2007. SECPKG_CONTEXT_EXPORT_DELETE_OLD,
  2008. &MarshalledContext,
  2009. &TokenHandle
  2010. );
  2011. if (!NT_SUCCESS(SecStatus))
  2012. {
  2013. printf("Failed to export context: ");
  2014. PrintStatus(SecStatus);
  2015. }
  2016. else
  2017. {
  2018. SecStatus = ImportSecurityContext(
  2019. PackageName,
  2020. &MarshalledContext,
  2021. TokenHandle,
  2022. &ClientContextHandle
  2023. );
  2024. if (!NT_SUCCESS(SecStatus))
  2025. {
  2026. printf("Failed to import context: ");
  2027. PrintStatus(SecStatus);
  2028. return;
  2029. }
  2030. //
  2031. // Sign a message again, using the imported context
  2032. //
  2033. SigBuffers[1].pvBuffer = bSigBuffer;
  2034. SigBuffers[1].cbBuffer = ContextSizes.cbMaxSignature;
  2035. SigBuffers[1].BufferType = SECBUFFER_TOKEN;
  2036. SigBuffers[0].pvBuffer = bDataBuffer;
  2037. SigBuffers[0].cbBuffer = sizeof(bDataBuffer);
  2038. SigBuffers[0].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY_WITH_CHECKSUM;;
  2039. memset(bDataBuffer,0xeb,sizeof(bDataBuffer));
  2040. SignMessage.pBuffers = SigBuffers;
  2041. SignMessage.cBuffers = 2;
  2042. SignMessage.ulVersion = 0;
  2043. SecStatus = MakeSignature(
  2044. &ClientContextHandle,
  2045. 0,
  2046. &SignMessage,
  2047. 0 );
  2048. if ( SecStatus != STATUS_SUCCESS ) {
  2049. printf( "MakeSignature: " );
  2050. PrintStatus( SecStatus );
  2051. if ( !NT_SUCCESS(SecStatus) ) {
  2052. return;
  2053. }
  2054. }
  2055. if ( !QuietMode ) {
  2056. printf("\n Signature: \n");
  2057. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  2058. }
  2059. //
  2060. // Verify the signature
  2061. //
  2062. SecStatus = VerifySignature(
  2063. &ServerContextHandle,
  2064. &SignMessage,
  2065. 0,
  2066. 0 );
  2067. if ( SecStatus != STATUS_SUCCESS ) {
  2068. printf( "VerifySignature: " );
  2069. PrintStatus( SecStatus );
  2070. if ( !NT_SUCCESS(SecStatus) ) {
  2071. return;
  2072. }
  2073. }
  2074. }
  2075. }
  2076. //
  2077. // Delete both contexts.
  2078. //
  2079. SecStatus = DeleteSecurityContext( &ClientContextHandle );
  2080. if ( SecStatus != STATUS_SUCCESS ) {
  2081. printf( "DeleteSecurityContext( ClientContext %x : %x ) failed: ",
  2082. ClientContextHandle.dwLower, ClientContextHandle.dwUpper );
  2083. PrintStatus( SecStatus );
  2084. return;
  2085. }
  2086. SecStatus = DeleteSecurityContext( &ServerContextHandle );
  2087. if ( SecStatus != STATUS_SUCCESS ) {
  2088. printf( "DeleteSecurityContext( ServerContext %x : %x ) failed: ",
  2089. ServerContextHandle.dwLower, ServerContextHandle.dwUpper );
  2090. PrintStatus( SecStatus );
  2091. return;
  2092. }
  2093. //
  2094. // Free both credential handles
  2095. //
  2096. if (AcquiredServerCred)
  2097. {
  2098. SecStatus = FreeCredentialsHandle( ServerCredHandle );
  2099. if ( SecStatus != STATUS_SUCCESS ) {
  2100. printf( "FreeCredentialsHandle failed: " );
  2101. PrintStatus( SecStatus );
  2102. return;
  2103. }
  2104. ServerCredHandle = NULL;
  2105. }
  2106. SecStatus = FreeCredentialsHandle( &CredentialHandle2 );
  2107. if ( SecStatus != STATUS_SUCCESS ) {
  2108. printf( "FreeCredentialsHandle failed: " );
  2109. PrintStatus( SecStatus );
  2110. return;
  2111. }
  2112. //
  2113. // Final Cleanup
  2114. //
  2115. /*if ( NegotiateBuffer.pvBuffer != NULL ) {
  2116. (VOID) LocalFree( NegotiateBuffer.pvBuffer );
  2117. } */
  2118. if ( ChallengeBuffer.pvBuffer != NULL ) {
  2119. (VOID) LocalFree( ChallengeBuffer.pvBuffer );
  2120. }
  2121. if ( AuthenticateBuffer.pvBuffer != NULL ) {
  2122. (VOID) LocalFree( AuthenticateBuffer.pvBuffer );
  2123. }
  2124. }
  2125. VOID
  2126. TestLogonRoutine(
  2127. IN ULONG Count,
  2128. IN BOOLEAN Relogon,
  2129. IN SECURITY_LOGON_TYPE LogonType,
  2130. IN LPSTR PackageName,
  2131. IN LPSTR UserName,
  2132. IN LPSTR DomainName,
  2133. IN LPSTR Password
  2134. )
  2135. {
  2136. NTSTATUS Status;
  2137. PKERB_INTERACTIVE_LOGON LogonInfo;
  2138. ULONG LogonInfoSize = sizeof(KERB_INTERACTIVE_LOGON);
  2139. BOOLEAN WasEnabled;
  2140. STRING Name;
  2141. ULONG Dummy;
  2142. HANDLE LogonHandle = NULL;
  2143. ULONG PackageId;
  2144. TOKEN_SOURCE SourceContext;
  2145. PKERB_INTERACTIVE_PROFILE Profile = NULL;
  2146. ULONG ProfileSize;
  2147. LUID LogonId;
  2148. HANDLE TokenHandle = NULL;
  2149. QUOTA_LIMITS Quotas;
  2150. NTSTATUS SubStatus;
  2151. WCHAR UserNameString[100];
  2152. ULONG NameLength = 100;
  2153. PUCHAR Where;
  2154. ULONG Index;
  2155. HANDLE ThreadTokenHandle = NULL;
  2156. LARGE_INTEGER StartTime, EndTime;
  2157. printf("Logging On %s\\%s %s\n",DomainName, UserName, Password);
  2158. if (Relogon)
  2159. {
  2160. LogonInfoSize = sizeof(KERB_INTERACTIVE_UNLOCK_LOGON);
  2161. }
  2162. LogonInfoSize += (ULONG) (strlen(UserName) + ((DomainName == NULL) ?
  2163. 0 :
  2164. strlen(DomainName)) + strlen(Password) + 3 ) * sizeof(WCHAR);
  2165. LogonInfo = (PKERB_INTERACTIVE_LOGON) LocalAlloc(LMEM_ZEROINIT, LogonInfoSize);
  2166. if (NULL == LogonInfo)
  2167. {
  2168. printf("Failed to allocate LogonInfo\n");
  2169. return;
  2170. }
  2171. LogonInfo->MessageType = KerbInteractiveLogon;
  2172. RtlInitString(
  2173. &Name,
  2174. UserName
  2175. );
  2176. if (Relogon)
  2177. {
  2178. Where = ((PUCHAR) LogonInfo) + sizeof(KERB_INTERACTIVE_UNLOCK_LOGON);
  2179. }
  2180. else
  2181. {
  2182. Where = (PUCHAR) (LogonInfo + 1);
  2183. }
  2184. LogonInfo->UserName.Buffer = (LPWSTR) Where;
  2185. LogonInfo->UserName.MaximumLength = (USHORT) LogonInfoSize;
  2186. RtlAnsiStringToUnicodeString(
  2187. &LogonInfo->UserName,
  2188. &Name,
  2189. FALSE
  2190. );
  2191. Where += LogonInfo->UserName.Length + sizeof(WCHAR);
  2192. RtlInitString(
  2193. &Name,
  2194. DomainName
  2195. );
  2196. LogonInfo->LogonDomainName.Buffer = (LPWSTR) Where;
  2197. LogonInfo->LogonDomainName.MaximumLength = (USHORT) LogonInfoSize;
  2198. RtlAnsiStringToUnicodeString(
  2199. &LogonInfo->LogonDomainName,
  2200. &Name,
  2201. FALSE
  2202. );
  2203. Where += LogonInfo->LogonDomainName.Length + sizeof(WCHAR);
  2204. RtlInitString(
  2205. &Name,
  2206. Password
  2207. );
  2208. LogonInfo->Password.Buffer = (LPWSTR) Where;
  2209. LogonInfo->Password.MaximumLength = (USHORT) LogonInfoSize;
  2210. RtlAnsiStringToUnicodeString(
  2211. &LogonInfo->Password,
  2212. &Name,
  2213. FALSE
  2214. );
  2215. Where += LogonInfo->Password.Length + sizeof(WCHAR);
  2216. LogonInfo->MessageType = KerbInteractiveLogon;
  2217. if (Relogon)
  2218. {
  2219. HANDLE ProcessToken = NULL;
  2220. TOKEN_STATISTICS Stats;
  2221. ULONG StatsSize = sizeof(TOKEN_STATISTICS);
  2222. if (OpenProcessToken(
  2223. GetCurrentProcess(),
  2224. TOKEN_QUERY,
  2225. &ProcessToken))
  2226. {
  2227. if (GetTokenInformation(
  2228. ProcessToken,
  2229. TokenStatistics,
  2230. &Stats,
  2231. StatsSize,
  2232. &StatsSize
  2233. ))
  2234. {
  2235. PKERB_INTERACTIVE_UNLOCK_LOGON UnlockLogonInfo = (PKERB_INTERACTIVE_UNLOCK_LOGON) LogonInfo;
  2236. UnlockLogonInfo->LogonId = Stats.AuthenticationId;
  2237. LogonInfo->MessageType = KerbWorkstationUnlockLogon;
  2238. }
  2239. else
  2240. {
  2241. printf("Failed to get token info: %d\n",GetLastError());
  2242. }
  2243. }
  2244. else
  2245. {
  2246. printf("Failed to open process token info: %d\n",GetLastError());
  2247. }
  2248. }
  2249. //
  2250. // Turn on the TCB privilege
  2251. //
  2252. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, (BOOLEAN) OpenThreadToken(GetCurrentThread(),TOKEN_QUERY,FALSE,&ThreadTokenHandle) , &WasEnabled);
  2253. if (ThreadTokenHandle != NULL)
  2254. {
  2255. CloseHandle(ThreadTokenHandle);
  2256. ThreadTokenHandle = NULL;
  2257. }
  2258. if (!NT_SUCCESS(Status))
  2259. {
  2260. printf("Failed to adjust privilege: 0x%x\n",Status);
  2261. return;
  2262. }
  2263. RtlInitString(
  2264. &Name,
  2265. "SspTest"
  2266. );
  2267. Status = LsaRegisterLogonProcess(
  2268. &Name,
  2269. &LogonHandle,
  2270. &Dummy
  2271. );
  2272. if (!NT_SUCCESS(Status))
  2273. {
  2274. printf("Failed to register as a logon process: 0x%x\n",Status);
  2275. return;
  2276. }
  2277. strncpy(
  2278. SourceContext.SourceName,
  2279. "ssptest ",sizeof(SourceContext.SourceName)
  2280. );
  2281. NtAllocateLocallyUniqueId(
  2282. &SourceContext.SourceIdentifier
  2283. );
  2284. RtlInitString(
  2285. &Name,
  2286. PackageName
  2287. );
  2288. Status = LsaLookupAuthenticationPackage(
  2289. LogonHandle,
  2290. &Name,
  2291. &PackageId
  2292. );
  2293. if (!NT_SUCCESS(Status))
  2294. {
  2295. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  2296. return;
  2297. }
  2298. //
  2299. // Now call LsaLogonUser
  2300. //
  2301. RtlInitString(
  2302. &Name,
  2303. "ssptest"
  2304. );
  2305. for (Index = 0; Index < Count ; Index++ )
  2306. {
  2307. NtQuerySystemTime(&StartTime);
  2308. Status = LsaLogonUser(
  2309. LogonHandle,
  2310. &Name,
  2311. LogonType,
  2312. PackageId,
  2313. LogonInfo,
  2314. LogonInfoSize,
  2315. NULL, // no token groups
  2316. &SourceContext,
  2317. (PVOID *) &Profile,
  2318. &ProfileSize,
  2319. &LogonId,
  2320. &TokenHandle,
  2321. &Quotas,
  2322. &SubStatus
  2323. );
  2324. if (!NT_SUCCESS(Status))
  2325. {
  2326. printf("lsalogonuser failed: 0x%x\n",Status);
  2327. return;
  2328. }
  2329. if (!NT_SUCCESS(SubStatus))
  2330. {
  2331. printf("LsalogonUser failed: substatus = 0x%x\n",SubStatus);
  2332. return;
  2333. }
  2334. NtQuerySystemTime(&EndTime);
  2335. printf("logon took %d ms\t\t",(EndTime.QuadPart-StartTime.QuadPart) / 10000);
  2336. PrintTime("", EndTime);
  2337. ImpersonateLoggedOnUser( TokenHandle );
  2338. GetUserName(UserNameString,&NameLength);
  2339. printf("Username = %ws\n",UserNameString);
  2340. RevertToSelf();
  2341. NtClose(TokenHandle);
  2342. LsaFreeReturnBuffer(Profile);
  2343. Profile = NULL;
  2344. }
  2345. }
  2346. BOOL
  2347. LaunchCommandWindowAsUser(HANDLE hToken)
  2348. {
  2349. HANDLE hFullToken = NULL;
  2350. BOOL fRet = FALSE;
  2351. DWORD dwErr = 0;
  2352. WCHAR lpApp[MAX_PATH];
  2353. STARTUPINFOW startupinfo;
  2354. PROCESS_INFORMATION processinfo;
  2355. if (!DuplicateTokenEx(
  2356. hToken,
  2357. TOKEN_ALL_ACCESS,
  2358. NULL,
  2359. SecurityImpersonation,
  2360. TokenPrimary,
  2361. &hFullToken
  2362. )) {
  2363. dwErr = GetLastError();
  2364. printf("DuplicateTokenEx failed! - %x\n", dwErr);
  2365. return FALSE;
  2366. }
  2367. //
  2368. // At this point, we need to setup the LPSTARTUPINFO for the
  2369. // CreateProcessAsUser() call.
  2370. //
  2371. ZeroMemory(&startupinfo, sizeof(STARTUPINFOW));
  2372. startupinfo.cb = sizeof(STARTUPINFOW);
  2373. startupinfo.lpDesktop = L"winsta0\\default";
  2374. startupinfo.lpTitle = L"Impersonated Client Security Context";
  2375. GetSystemDirectoryW(lpApp, MAX_PATH);
  2376. wcscat(lpApp, L"\\cmd.exe");//potential for buffer overflow, but not likely
  2377. if (!CreateProcessAsUserW(
  2378. hFullToken,
  2379. lpApp,
  2380. NULL,
  2381. NULL,
  2382. NULL,
  2383. FALSE,
  2384. CREATE_NEW_CONSOLE,
  2385. NULL,
  2386. NULL,
  2387. &startupinfo,
  2388. &processinfo
  2389. )) {
  2390. printf("CreateProcessAsUserW failed! - %x\n", GetLastError());
  2391. return FALSE;
  2392. }
  2393. return fRet;
  2394. }
  2395. VOID
  2396. TestS4ULogonRoutine(
  2397. IN LPSTR UserName,
  2398. IN LPSTR DomainName
  2399. )
  2400. {
  2401. NTSTATUS Status;
  2402. PKERB_S4U_LOGON LogonInfo;
  2403. ULONG LogonInfoSize = sizeof(KERB_S4U_LOGON);
  2404. BOOLEAN WasEnabled, Trusted = TRUE;
  2405. STRING Name;
  2406. ULONG Dummy;
  2407. HANDLE LogonHandle = NULL;
  2408. ULONG PackageId;
  2409. TOKEN_SOURCE SourceContext;
  2410. PKERB_INTERACTIVE_PROFILE Profile = NULL;
  2411. ULONG ProfileSize;
  2412. LUID LogonId;
  2413. HANDLE TokenHandle = NULL;
  2414. QUOTA_LIMITS Quotas;
  2415. NTSTATUS SubStatus;
  2416. WCHAR UserNameString[100];
  2417. ULONG NameLength = 100;
  2418. PUCHAR Where;
  2419. //printf("S4U LogOn %s\\%s\n",((DomainName == NULL)? "<NULL>" : DomainName), UserName);
  2420. LogonInfoSize += (ULONG) ((strlen(UserName)+1) * sizeof(WCHAR));
  2421. LogonInfoSize += (ULONG) ((DomainName == NULL) ? 0 : ((strlen(DomainName) +1) * sizeof(WCHAR)));
  2422. LogonInfo = (PKERB_S4U_LOGON) LocalAlloc(LMEM_ZEROINIT, LogonInfoSize);
  2423. if (NULL == LogonInfo)
  2424. {
  2425. return;
  2426. }
  2427. LogonInfo->MessageType = KerbS4ULogon;
  2428. RtlInitString(
  2429. &Name,
  2430. UserName
  2431. );
  2432. Where = (PUCHAR) (LogonInfo + 1);
  2433. LogonInfo->ClientUpn.Buffer = (LPWSTR) Where;
  2434. LogonInfo->ClientUpn.MaximumLength = (USHORT) LogonInfoSize;
  2435. RtlAnsiStringToUnicodeString(
  2436. &LogonInfo->ClientUpn,
  2437. &Name,
  2438. FALSE
  2439. );
  2440. Where += LogonInfo->ClientUpn.Length + sizeof(WCHAR);
  2441. RtlInitString(
  2442. &Name,
  2443. DomainName
  2444. );
  2445. LogonInfo->ClientRealm.Buffer = (LPWSTR) Where;
  2446. LogonInfo->ClientRealm.MaximumLength = (USHORT) LogonInfoSize;
  2447. RtlAnsiStringToUnicodeString(
  2448. &LogonInfo->ClientRealm,
  2449. &Name,
  2450. FALSE
  2451. );
  2452. Where += LogonInfo->ClientRealm.Length + sizeof(WCHAR);
  2453. RtlInitString(
  2454. &Name,
  2455. "SspTest"
  2456. );
  2457. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  2458. if (!NT_SUCCESS(Status))
  2459. {
  2460. Trusted = FALSE;
  2461. }
  2462. RtlInitString(
  2463. &Name,
  2464. "SspTest"
  2465. );
  2466. if (Trusted)
  2467. {
  2468. Status = LsaRegisterLogonProcess(
  2469. &Name,
  2470. &LogonHandle,
  2471. &Dummy
  2472. );
  2473. }
  2474. else
  2475. {
  2476. Status = LsaConnectUntrusted(
  2477. &LogonHandle
  2478. );
  2479. }
  2480. strncpy(
  2481. SourceContext.SourceName,
  2482. "ssptest ",sizeof(SourceContext.SourceName)
  2483. );
  2484. NtAllocateLocallyUniqueId(
  2485. &SourceContext.SourceIdentifier
  2486. );
  2487. RtlInitString(
  2488. &Name,
  2489. MICROSOFT_KERBEROS_NAME_A
  2490. );
  2491. Status = LsaLookupAuthenticationPackage(
  2492. LogonHandle,
  2493. &Name,
  2494. &PackageId
  2495. );
  2496. if (!NT_SUCCESS(Status))
  2497. {
  2498. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  2499. return;
  2500. }
  2501. //
  2502. // Now call LsaLogonUser
  2503. //
  2504. RtlInitString(
  2505. &Name,
  2506. "ssptest"
  2507. );
  2508. Status = LsaLogonUser(
  2509. LogonHandle,
  2510. &Name,
  2511. Network,
  2512. PackageId,
  2513. LogonInfo,
  2514. LogonInfoSize,
  2515. NULL, // no token groups
  2516. &SourceContext,
  2517. (PVOID *) &Profile,
  2518. &ProfileSize,
  2519. &LogonId,
  2520. &TokenHandle,
  2521. &Quotas,
  2522. &SubStatus
  2523. );
  2524. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  2525. {
  2526. printf("lsalogonuser failed: 0x%x\n",Status);
  2527. printf(" substatus: 0x%x\n",SubStatus);
  2528. return;
  2529. }
  2530. //LaunchCommandWindowAsUser( TokenHandle );
  2531. ImpersonateLoggedOnUser( TokenHandle );
  2532. GetUserName(UserNameString,&NameLength);
  2533. printf("Username = %ws\n",UserNameString);
  2534. RevertToSelf();
  2535. if ( DumpToken )
  2536. {
  2537. PrintToken(TokenHandle);
  2538. }
  2539. NtClose(TokenHandle);
  2540. }
  2541. VOID
  2542. PrintKdcName(
  2543. IN PKERB_EXTERNAL_NAME Name
  2544. )
  2545. {
  2546. ULONG Index;
  2547. if (Name == NULL)
  2548. {
  2549. printf("(null)");
  2550. }
  2551. else
  2552. {
  2553. for (Index = 0; Index < Name->NameCount ; Index++ )
  2554. {
  2555. printf(" %wZ ",&Name->Names[Index]);
  2556. }
  2557. }
  2558. printf("\n");
  2559. }
  2560. #ifdef notdef
  2561. //+-------------------------------------------------------------------------
  2562. //
  2563. // Function: KerbBuildKerbCredFromExternalTickets
  2564. //
  2565. // Synopsis: Builds a marshalled KERB_CRED structure
  2566. //
  2567. // Effects: allocates destination with MIDL_user_allocate
  2568. //
  2569. // Arguments: Ticket - The ticket of the session key to seal the
  2570. // encrypted portion
  2571. // DelegationTicket - The ticket to marshall into the cred message
  2572. // MarshalledKerbCred - Receives a marshalled KERB_CRED structure
  2573. // KerbCredSizes - Receives size, in bytes, of marshalled
  2574. // KERB_CRED.
  2575. //
  2576. // Requires:
  2577. //
  2578. // Returns:
  2579. //
  2580. // Notes:
  2581. //
  2582. //
  2583. //--------------------------------------------------------------------------
  2584. NTSTATUS
  2585. KerbBuildKerbCredFromExternalTickets(
  2586. IN PKERB_EXTERNAL_TICKET Ticket,
  2587. IN PKERB_EXTERNAL_TICKET DelegationTicket,
  2588. OUT PUCHAR * MarshalledKerbCred,
  2589. OUT PULONG KerbCredSize
  2590. )
  2591. {
  2592. NTSTATUS Status = STATUS_SUCCESS;
  2593. KERBERR KerbErr;
  2594. KERB_CRED KerbCred;
  2595. KERB_CRED_INFO_LIST CredInfo;
  2596. KERB_ENCRYPTED_CRED EncryptedCred;
  2597. KERB_CRED_TICKET_LIST TicketList;
  2598. ULONG EncryptionOverhead;
  2599. ULONG BlockSize;
  2600. PUCHAR MarshalledEncryptPart = NULL;
  2601. ULONG MarshalledEncryptSize;
  2602. ULONG ConvertedFlags;
  2603. PKERB_TICKET DecodedTicket = NULL;
  2604. //
  2605. // Initialize the structures so they can be freed later.
  2606. //
  2607. *MarshalledKerbCred = NULL;
  2608. *KerbCredSize = 0;
  2609. RtlZeroMemory(
  2610. &KerbCred,
  2611. sizeof(KERB_CRED)
  2612. );
  2613. RtlZeroMemory(
  2614. &EncryptedCred,
  2615. sizeof(KERB_ENCRYPTED_CRED)
  2616. );
  2617. RtlZeroMemory(
  2618. &CredInfo,
  2619. sizeof(KERB_CRED_INFO_LIST)
  2620. );
  2621. RtlZeroMemory(
  2622. &TicketList,
  2623. sizeof(KERB_CRED_TICKET_LIST)
  2624. );
  2625. KerbCred.version = KERBEROS_VERSION;
  2626. KerbCred.message_type = KRB_CRED;
  2627. //
  2628. // Decode the ticket so we can put it in the structure (to re-encode it)
  2629. //
  2630. KerbErr = KerbUnpackData(
  2631. DelegationTicket->EncodedTicket,
  2632. DelegationTicket->EncodedTicketSize,
  2633. KERB_TICKET_PDU,
  2634. (PVOID *) &DecodedTicket
  2635. );
  2636. if (!KERB_SUCCESS(KerbErr))
  2637. {
  2638. printf("Failed to unpack encoded ticket: 0x%x\n",KerbErr);
  2639. Status = STATUS_INVALID_PARAMETER;
  2640. goto Cleanup;
  2641. }
  2642. //
  2643. // First stick the ticket into the ticket list.
  2644. //
  2645. TicketList.next= NULL;
  2646. TicketList.value = *DecodedTicket;
  2647. KerbCred.tickets = &TicketList;
  2648. //
  2649. // Now build the KERB_CRED_INFO for this ticket
  2650. //
  2651. CredInfo.value.key = * (PKERB_ENCRYPTION_KEY) &DelegationTicket->SessionKey;
  2652. KerbConvertLargeIntToGeneralizedTime(
  2653. &CredInfo.value.endtime,
  2654. NULL,
  2655. &DelegationTicket->EndTime
  2656. );
  2657. CredInfo.value.bit_mask |= endtime_present;
  2658. KerbConvertLargeIntToGeneralizedTime(
  2659. &CredInfo.value.KERB_CRED_INFO_renew_until,
  2660. NULL,
  2661. &DelegationTicket->RenewUntil
  2662. );
  2663. CredInfo.value.bit_mask |= KERB_CRED_INFO_renew_until_present;
  2664. ConvertedFlags = KerbConvertUlongToFlagUlong(DelegationTicket->TicketFlags);
  2665. CredInfo.value.flags.value = (PUCHAR) &ConvertedFlags;
  2666. CredInfo.value.flags.length = 8 * sizeof(ULONG);
  2667. CredInfo.value.bit_mask |= flags_present;
  2668. //
  2669. // The following fields are marked as optional but treated
  2670. // as mandatory by the MIT implementation of Kerberos.
  2671. //
  2672. KerbErr = KerbConvertKdcNameToPrincipalName(
  2673. &CredInfo.value.sender_name,
  2674. (PKERB_INTERNAL_NAME) DelegationTicket->ClientName
  2675. );
  2676. if (!KERB_SUCCESS(KerbErr))
  2677. {
  2678. Status = KerbMapKerbError(KerbErr);
  2679. goto Cleanup;
  2680. }
  2681. CredInfo.value.bit_mask |= sender_name_present;
  2682. KerbErr = KerbConvertKdcNameToPrincipalName(
  2683. &CredInfo.value.principal_name,
  2684. (PKERB_INTERNAL_NAME) DelegationTicket->ServiceName
  2685. );
  2686. if (!KERB_SUCCESS(KerbErr))
  2687. {
  2688. Status = KerbMapKerbError(KerbErr);
  2689. goto Cleanup;
  2690. }
  2691. CredInfo.value.bit_mask |= principal_name_present;
  2692. //
  2693. // NOTE: we are assuming that because we are sending a TGT the
  2694. // client realm is the same as the serve realm. If we ever
  2695. // send non-tgt or cross-realm tgt, this needs to be fixed.
  2696. //
  2697. KerbErr = KerbConvertUnicodeStringToRealm(
  2698. &CredInfo.value.principal_realm,
  2699. &DelegationTicket->DomainName
  2700. );
  2701. if (!KERB_SUCCESS(KerbErr))
  2702. {
  2703. goto Cleanup;
  2704. }
  2705. //
  2706. // The realms are the same, so don't allocate both
  2707. //
  2708. CredInfo.value.sender_realm = CredInfo.value.principal_realm;
  2709. CredInfo.value.bit_mask |= principal_realm_present | sender_realm_present;
  2710. EncryptedCred.ticket_info = &CredInfo;
  2711. //
  2712. // Now encrypted the encrypted cred into the cred
  2713. //
  2714. if (!KERB_SUCCESS(KerbPackEncryptedCred(
  2715. &EncryptedCred,
  2716. &MarshalledEncryptSize,
  2717. &MarshalledEncryptPart
  2718. )))
  2719. {
  2720. Status = STATUS_INSUFFICIENT_RESOURCES;
  2721. goto Cleanup;
  2722. }
  2723. //
  2724. // If we are doing DES encryption, then we are talking with an non-NT
  2725. // server. Hence, don't encrypt the kerb-cred.
  2726. //
  2727. if ((Ticket->SessionKey.KeyType == KERB_ETYPE_DES_CBC_CRC) ||
  2728. (Ticket->SessionKey.KeyType == KERB_ETYPE_DES_CBC_MD5))
  2729. {
  2730. KerbCred.encrypted_part.cipher_text.length = MarshalledEncryptSize;
  2731. KerbCred.encrypted_part.cipher_text.value = MarshalledEncryptPart;
  2732. KerbCred.encrypted_part.encryption_type = 0;
  2733. MarshalledEncryptPart = NULL;
  2734. }
  2735. else
  2736. {
  2737. //
  2738. // Now get the encryption overhead
  2739. //
  2740. KerbErr = KerbAllocateEncryptionBufferWrapper(
  2741. Ticket->SessionKey.KeyType,
  2742. MarshalledEncryptSize,
  2743. &KerbCred.encrypted_part.cipher_text.length,
  2744. &KerbCred.encrypted_part.cipher_text.value
  2745. );
  2746. if (!KERB_SUCCESS(KerbErr))
  2747. {
  2748. Status = KerbMapKerbError(KerbErr);
  2749. goto Cleanup;
  2750. }
  2751. //
  2752. // Encrypt the data.
  2753. //
  2754. KerbErr = KerbEncryptDataEx(
  2755. &KerbCred.encrypted_part,
  2756. MarshalledEncryptSize,
  2757. MarshalledEncryptPart,
  2758. Ticket->SessionKey.KeyType,
  2759. KERB_CRED_SALT,
  2760. (PKERB_ENCRYPTION_KEY) &Ticket->SessionKey
  2761. );
  2762. if (!KERB_SUCCESS(KerbErr))
  2763. {
  2764. Status = STATUS_INSUFFICIENT_RESOURCES;
  2765. goto Cleanup;
  2766. }
  2767. }
  2768. //
  2769. // Now we have to marshall the whole KERB_CRED
  2770. //
  2771. if (!KERB_SUCCESS(KerbPackKerbCred(
  2772. &KerbCred,
  2773. KerbCredSize,
  2774. MarshalledKerbCred
  2775. )))
  2776. {
  2777. Status = STATUS_INSUFFICIENT_RESOURCES;
  2778. goto Cleanup;
  2779. }
  2780. Cleanup:
  2781. if (DecodedTicket != NULL)
  2782. {
  2783. KerbFreeData(
  2784. KERB_TICKET_PDU,
  2785. DecodedTicket
  2786. );
  2787. }
  2788. KerbFreePrincipalName(&CredInfo.value.sender_name);
  2789. KerbFreePrincipalName(&CredInfo.value.principal_name);
  2790. KerbFreeRealm(&CredInfo.value.principal_realm);
  2791. if (MarshalledEncryptPart != NULL)
  2792. {
  2793. MIDL_user_free(MarshalledEncryptPart);
  2794. }
  2795. if (KerbCred.encrypted_part.cipher_text.value != NULL)
  2796. {
  2797. MIDL_user_free(KerbCred.encrypted_part.cipher_text.value);
  2798. }
  2799. return(Status);
  2800. }
  2801. #endif
  2802. VOID
  2803. TestCallPackageRoutine(
  2804. IN LPWSTR Function
  2805. )
  2806. {
  2807. NTSTATUS Status;
  2808. BOOLEAN WasEnabled;
  2809. STRING Name;
  2810. ULONG Dummy;
  2811. HANDLE LogonHandle = NULL;
  2812. ULONG PackageId;
  2813. KERB_DEBUG_REQUEST DebugRequest;
  2814. KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
  2815. PKERB_QUERY_TKT_CACHE_RESPONSE CacheResponse = NULL;
  2816. PKERB_EXTERNAL_TICKET CacheEntry = NULL;
  2817. ULONG Index;
  2818. PVOID Response;
  2819. ULONG ResponseSize;
  2820. NTSTATUS SubStatus;
  2821. BOOLEAN Trusted = TRUE;
  2822. //
  2823. // Turn on the TCB privilege
  2824. //
  2825. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  2826. if (!NT_SUCCESS(Status))
  2827. {
  2828. Trusted = FALSE;
  2829. }
  2830. RtlInitString(
  2831. &Name,
  2832. "SspTest"
  2833. );
  2834. if (Trusted)
  2835. {
  2836. Status = LsaRegisterLogonProcess(
  2837. &Name,
  2838. &LogonHandle,
  2839. &Dummy
  2840. );
  2841. }
  2842. else
  2843. {
  2844. Status = LsaConnectUntrusted(
  2845. &LogonHandle
  2846. );
  2847. }
  2848. if (!NT_SUCCESS(Status))
  2849. {
  2850. printf("Failed to register as a logon process: 0x%x\n",Status);
  2851. return;
  2852. }
  2853. RtlInitString(
  2854. &Name,
  2855. MICROSOFT_KERBEROS_NAME_A
  2856. );
  2857. Status = LsaLookupAuthenticationPackage(
  2858. LogonHandle,
  2859. &Name,
  2860. &PackageId
  2861. );
  2862. if (!NT_SUCCESS(Status))
  2863. {
  2864. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  2865. return;
  2866. }
  2867. if (_wcsicmp(Function,L"bp") == 0)
  2868. {
  2869. DebugRequest.MessageType = KerbDebugRequestMessage;
  2870. DebugRequest.DebugRequest = KERB_DEBUG_REQ_BREAKPOINT;
  2871. Status = LsaCallAuthenticationPackage(
  2872. LogonHandle,
  2873. PackageId,
  2874. &DebugRequest,
  2875. sizeof(DebugRequest),
  2876. &Response,
  2877. &ResponseSize,
  2878. &SubStatus
  2879. );
  2880. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  2881. {
  2882. printf("bp failed: 0x%x, 0x %x\n",Status, SubStatus);
  2883. }
  2884. }
  2885. else if (_wcsicmp(Function,L"tickets") == 0)
  2886. {
  2887. CacheRequest.MessageType = KerbQueryTicketCacheMessage;
  2888. CacheRequest.LogonId.LowPart = 0;
  2889. CacheRequest.LogonId.HighPart = 0;
  2890. Status = LsaCallAuthenticationPackage(
  2891. LogonHandle,
  2892. PackageId,
  2893. &CacheRequest,
  2894. sizeof(CacheRequest),
  2895. (PVOID *) &CacheResponse,
  2896. &ResponseSize,
  2897. &SubStatus
  2898. );
  2899. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  2900. {
  2901. printf("bp failed: 0x%x, 0x %x\n",Status, SubStatus);
  2902. }
  2903. else
  2904. {
  2905. printf("Cached Tickets:\n");
  2906. for (Index = 0; Index < CacheResponse->CountOfTickets ; Index++ )
  2907. {
  2908. printf("\tServer: %wZ@%wZ\n",
  2909. &CacheResponse->Tickets[Index].ServerName,
  2910. &CacheResponse->Tickets[Index].RealmName);
  2911. PrintTime("\t\tStart Time: ",CacheResponse->Tickets[Index].StartTime);
  2912. PrintTime("\t\tEnd Time: ",CacheResponse->Tickets[Index].EndTime);
  2913. PrintTime("\t\tRenew Time: ",CacheResponse->Tickets[Index].RenewTime);
  2914. printf("\t\tEncryptionType: %d\n",CacheResponse->Tickets[Index].EncryptionType);
  2915. printf("\t\tTicketFlags: 0x%x\n",CacheResponse->Tickets[Index].TicketFlags);
  2916. }
  2917. }
  2918. }
  2919. else if (_wcsicmp(Function,L"tgt") == 0)
  2920. {
  2921. CacheRequest.MessageType = KerbRetrieveTicketMessage;
  2922. CacheRequest.LogonId.LowPart = 0;
  2923. CacheRequest.LogonId.HighPart = 0;
  2924. Status = LsaCallAuthenticationPackage(
  2925. LogonHandle,
  2926. PackageId,
  2927. &CacheRequest,
  2928. sizeof(CacheRequest),
  2929. (PVOID *) &CacheEntry,
  2930. &ResponseSize,
  2931. &SubStatus
  2932. );
  2933. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  2934. {
  2935. printf("query tgt failed: 0x%x, 0x %x\n",Status, SubStatus);
  2936. }
  2937. else
  2938. {
  2939. printf("Cached TGT:\n");
  2940. printf("ServiceName: "); PrintKdcName(CacheEntry->ServiceName);
  2941. printf("TargetName: "); PrintKdcName(CacheEntry->TargetName);
  2942. printf("DomainName: %wZ\n",&CacheEntry->DomainName);
  2943. printf("TargetDomainName: %wZ\n",&CacheEntry->TargetDomainName);
  2944. printf("ClientName: "); PrintKdcName(CacheEntry->ClientName);
  2945. printf("TicketFlags: 0x%x\n",CacheEntry->TicketFlags);
  2946. PrintTime("StartTime: ",CacheEntry->StartTime);
  2947. PrintTime("StartTime: ",CacheEntry->StartTime);
  2948. PrintTime("EndTime: ",CacheEntry->EndTime);
  2949. PrintTime("RenewUntil: ",CacheEntry->RenewUntil);
  2950. PrintTime("TimeSkew: ",CacheEntry->TimeSkew);
  2951. LsaFreeReturnBuffer(CacheEntry);
  2952. }
  2953. }
  2954. else if (_wcsicmp(Function,L"stats") == 0)
  2955. {
  2956. PKERB_DEBUG_REPLY DbgReply;
  2957. PKERB_DEBUG_STATS DbgStats;
  2958. DebugRequest.MessageType = KerbDebugRequestMessage;
  2959. DebugRequest.DebugRequest = KERB_DEBUG_REQ_STATISTICS;
  2960. Status = LsaCallAuthenticationPackage(
  2961. LogonHandle,
  2962. PackageId,
  2963. &DebugRequest,
  2964. sizeof(DebugRequest),
  2965. &Response,
  2966. &ResponseSize,
  2967. &SubStatus
  2968. );
  2969. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  2970. {
  2971. printf("stats failed: 0x%x, 0x %x\n",Status, SubStatus);
  2972. }
  2973. else
  2974. {
  2975. DbgReply = (PKERB_DEBUG_REPLY) Response;
  2976. if (DbgReply->MessageType != KerbDebugRequestMessage)
  2977. {
  2978. printf("Wrong return message type: %d\n",DbgReply->MessageType);
  2979. return;
  2980. }
  2981. DbgStats = (PKERB_DEBUG_STATS) DbgReply->Data;
  2982. printf("Cache hits = %d\n",DbgStats->CacheHits);
  2983. printf("Cache Misses = %d\n",DbgStats->CacheMisses);
  2984. printf("Skewed Requets = %d\n",DbgStats->SkewedRequests);
  2985. printf("Success Requets = %d\n",DbgStats->SuccessRequests);
  2986. PrintTime("Last Sync = ",DbgStats->LastSync);
  2987. }
  2988. LsaFreeReturnBuffer(Response);
  2989. }
  2990. else if (_wcsicmp(Function,L"token") == 0)
  2991. {
  2992. DebugRequest.MessageType = KerbDebugRequestMessage;
  2993. DebugRequest.DebugRequest = KERB_DEBUG_CREATE_TOKEN;
  2994. Status = LsaCallAuthenticationPackage(
  2995. LogonHandle,
  2996. PackageId,
  2997. &DebugRequest,
  2998. sizeof(DebugRequest),
  2999. &Response,
  3000. &ResponseSize,
  3001. &SubStatus
  3002. );
  3003. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3004. {
  3005. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3006. }
  3007. }
  3008. else if (_wcsnicmp(Function,L"purge:", wcslen(L"purge:")) == 0)
  3009. {
  3010. PKERB_PURGE_TKT_CACHE_REQUEST CacheRequest = NULL;
  3011. UNICODE_STRING Target = {0};
  3012. UNICODE_STRING Target2 = {0};
  3013. USHORT Index;
  3014. RtlInitUnicodeString(
  3015. &Target2,
  3016. Function+wcslen(L"purge:")
  3017. );
  3018. CacheRequest = (PKERB_PURGE_TKT_CACHE_REQUEST)
  3019. LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_PURGE_TKT_CACHE_REQUEST));
  3020. CacheRequest->MessageType = KerbPurgeTicketCacheMessage;
  3021. Target.Buffer = (LPWSTR) (CacheRequest + 1);
  3022. Target.Length = Target2.Length;
  3023. Target.MaximumLength = Target2.MaximumLength;
  3024. RtlCopyMemory(
  3025. Target.Buffer,
  3026. Target2.Buffer,
  3027. Target2.Length
  3028. );
  3029. for (Index = 0; Index < Target.Length / sizeof(WCHAR); Index++ )
  3030. {
  3031. if (Target.Buffer[Index] == L'@')
  3032. {
  3033. CacheRequest->ServerName.Buffer = Target.Buffer;
  3034. CacheRequest->ServerName.Length = 2*Index;
  3035. CacheRequest->ServerName.MaximumLength = CacheRequest->ServerName.Length;
  3036. CacheRequest->RealmName.Buffer = Target.Buffer+Index+1;
  3037. CacheRequest->RealmName.Length = Target.Length - 2*(Index+1);
  3038. CacheRequest->RealmName.MaximumLength = CacheRequest->RealmName.Length;
  3039. break;
  3040. }
  3041. else if (Target.Buffer[Index] == L'\\')
  3042. {
  3043. CacheRequest->RealmName.Buffer = Target.Buffer;
  3044. CacheRequest->RealmName.Length = 2*Index;
  3045. CacheRequest->RealmName.MaximumLength = CacheRequest->RealmName.Length;
  3046. CacheRequest->ServerName.Buffer = Target.Buffer+Index+1;
  3047. CacheRequest->ServerName.Length = Target.Length - 2*(Index+1);
  3048. CacheRequest->ServerName.MaximumLength = CacheRequest->ServerName.Length;
  3049. break;
  3050. }
  3051. }
  3052. printf("Deleting tickets: %wZ\\%wZ\n",
  3053. &CacheRequest->RealmName, &CacheRequest->ServerName );
  3054. Status = LsaCallAuthenticationPackage(
  3055. LogonHandle,
  3056. PackageId,
  3057. CacheRequest,
  3058. Target2.Length + sizeof(KERB_PURGE_TKT_CACHE_REQUEST),
  3059. &Response,
  3060. &ResponseSize,
  3061. &SubStatus
  3062. );
  3063. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3064. {
  3065. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3066. }
  3067. }
  3068. else if (_wcsnicmp(Function,L"purgeex:", wcslen(L"purgeex:")) == 0)
  3069. {
  3070. PKERB_PURGE_TKT_CACHE_EX_REQUEST CacheRequest = NULL;
  3071. CacheRequest = (PKERB_PURGE_TKT_CACHE_EX_REQUEST)
  3072. LocalAlloc(LMEM_ZEROINIT, sizeof(KERB_PURGE_TKT_CACHE_EX_REQUEST));
  3073. CacheRequest->MessageType = KerbPurgeTicketCacheExMessage;
  3074. CacheRequest->Flags = KERB_PURGE_ALL_TICKETS;
  3075. printf("Deleting all tickets\n" );
  3076. Status = LsaCallAuthenticationPackage(
  3077. LogonHandle,
  3078. PackageId,
  3079. CacheRequest,
  3080. sizeof(KERB_PURGE_TKT_CACHE_EX_REQUEST),
  3081. &Response,
  3082. &ResponseSize,
  3083. &SubStatus
  3084. );
  3085. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3086. {
  3087. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3088. }
  3089. }
  3090. else if (_wcsnicmp(Function,L"retrieve:", wcslen(L"retrieve:")) == 0)
  3091. {
  3092. PKERB_RETRIEVE_TKT_REQUEST CacheRequest = NULL;
  3093. PKERB_RETRIEVE_TKT_RESPONSE CacheResponse = NULL;
  3094. UNICODE_STRING Target = {0};
  3095. UNICODE_STRING Target2 = {0};
  3096. RtlInitUnicodeString(
  3097. &Target2,
  3098. Function+wcslen(L"retrieve:")
  3099. );
  3100. CacheRequest = (PKERB_RETRIEVE_TKT_REQUEST)
  3101. LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST));
  3102. CacheRequest->MessageType = KerbRetrieveEncodedTicketMessage;
  3103. Target.Buffer = (LPWSTR) (CacheRequest + 1);
  3104. Target.Length = Target2.Length;
  3105. Target.MaximumLength = Target2.MaximumLength;
  3106. RtlCopyMemory(
  3107. Target.Buffer,
  3108. Target2.Buffer,
  3109. Target2.Length
  3110. );
  3111. CacheRequest->TargetName = Target;
  3112. printf("Retrieving tickets: %wZ\n",
  3113. &CacheRequest->TargetName );
  3114. Status = LsaCallAuthenticationPackage(
  3115. LogonHandle,
  3116. PackageId,
  3117. CacheRequest,
  3118. Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST),
  3119. &Response,
  3120. &ResponseSize,
  3121. &SubStatus
  3122. );
  3123. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3124. {
  3125. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3126. }
  3127. else
  3128. {
  3129. CacheResponse = (PKERB_RETRIEVE_TKT_RESPONSE) Response;
  3130. printf("Cached Ticket:\n");
  3131. printf("ServiceName: "); PrintKdcName(CacheResponse->Ticket.ServiceName);
  3132. printf("TargetName: "); PrintKdcName(CacheResponse->Ticket.TargetName);
  3133. printf("DomainName: %wZ\n",&CacheResponse->Ticket.DomainName);
  3134. printf("ClientDomain: %wZ\n", &CacheResponse->Ticket.AltTargetDomainName);
  3135. printf("TargetDomainName: %wZ\n",&CacheResponse->Ticket.TargetDomainName);
  3136. printf("ClientName: "); PrintKdcName(CacheResponse->Ticket.ClientName);
  3137. printf("TicketFlags: 0x%x\n",CacheResponse->Ticket.TicketFlags);
  3138. PrintTime("StartTime: ",CacheResponse->Ticket.StartTime);
  3139. PrintTime("StartTime: ",CacheResponse->Ticket.StartTime);
  3140. PrintTime("EndTime: ",CacheResponse->Ticket.EndTime);
  3141. PrintTime("RenewUntil: ",CacheResponse->Ticket.RenewUntil);
  3142. PrintTime("TimeSkew: ",CacheResponse->Ticket.TimeSkew);
  3143. LsaFreeReturnBuffer(CacheResponse);
  3144. }
  3145. }
  3146. else if (_wcsnicmp(Function,L"decode:", wcslen(L"decode:")) == 0)
  3147. {
  3148. PKERB_RETRIEVE_TKT_REQUEST CacheRequest = NULL;
  3149. PKERB_RETRIEVE_TKT_RESPONSE CacheResponse = NULL;
  3150. UNICODE_STRING Target = {0};
  3151. UNICODE_STRING Target2 = {0};
  3152. RtlInitUnicodeString(
  3153. &Target2,
  3154. Function+wcslen(L"decode:")
  3155. );
  3156. CacheRequest = (PKERB_RETRIEVE_TKT_REQUEST)
  3157. LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST));
  3158. CacheRequest->MessageType = KerbRetrieveEncodedTicketMessage;
  3159. Target.Buffer = (LPWSTR) (CacheRequest + 1);
  3160. Target.Length = Target2.Length;
  3161. Target.MaximumLength = Target2.MaximumLength;
  3162. RtlCopyMemory(
  3163. Target.Buffer,
  3164. Target2.Buffer,
  3165. Target2.Length
  3166. );
  3167. CacheRequest->TargetName = Target;
  3168. printf("Retrieving tickets: %wZ\n",
  3169. &CacheRequest->TargetName );
  3170. Status = LsaCallAuthenticationPackage(
  3171. LogonHandle,
  3172. PackageId,
  3173. CacheRequest,
  3174. Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST),
  3175. &Response,
  3176. &ResponseSize,
  3177. &SubStatus
  3178. );
  3179. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3180. {
  3181. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3182. }
  3183. else
  3184. {
  3185. PKERB_DECRYPT_REQUEST DecryptRequest = NULL;
  3186. PKERB_DECRYPT_RESPONSE DecryptResponse = NULL;
  3187. ULONG DecryptRequestSize = 0;
  3188. ULONG DecryptResponseSize = 0;
  3189. PKERB_ENCRYPTED_TICKET EncryptedTicket = NULL;
  3190. PKERB_TICKET DecodedTicket = NULL;
  3191. KERBERR KerbErr;
  3192. CacheResponse = (PKERB_RETRIEVE_TKT_RESPONSE) Response;
  3193. KerbErr = KerbUnpackData(
  3194. CacheResponse->Ticket.EncodedTicket,
  3195. CacheResponse->Ticket.EncodedTicketSize,
  3196. KERB_TICKET_PDU,
  3197. (PVOID *) &DecodedTicket
  3198. );
  3199. if (!KERB_SUCCESS(KerbErr))
  3200. {
  3201. printf("Failed to decode ticket: 0x%x\n",KerbErr);
  3202. return;
  3203. }
  3204. //
  3205. // Now try to decrypt the ticket with our default key
  3206. //
  3207. DecryptRequestSize = sizeof(KERB_DECRYPT_REQUEST) +
  3208. DecodedTicket->encrypted_part.cipher_text.length;
  3209. DecryptRequest = (PKERB_DECRYPT_REQUEST) LocalAlloc(LMEM_ZEROINIT, DecryptRequestSize);
  3210. DecryptRequest->MessageType = KerbDecryptDataMessage;
  3211. DecryptRequest->Flags = KERB_DECRYPT_FLAG_DEFAULT_KEY;
  3212. DecryptRequest->InitialVectorSize = 0;
  3213. DecryptRequest->InitialVector = NULL;
  3214. DecryptRequest->KeyUsage = KERB_TICKET_SALT;
  3215. DecryptRequest->CryptoType = DecodedTicket->encrypted_part.encryption_type;
  3216. DecryptRequest->EncryptedDataSize = DecodedTicket->encrypted_part.cipher_text.length;
  3217. DecryptRequest->EncryptedData = (PUCHAR) (DecryptRequest + 1);
  3218. RtlCopyMemory(
  3219. DecryptRequest->EncryptedData,
  3220. DecodedTicket->encrypted_part.cipher_text.value,
  3221. DecryptRequest->EncryptedDataSize
  3222. );
  3223. Status = LsaCallAuthenticationPackage(
  3224. LogonHandle,
  3225. PackageId,
  3226. DecryptRequest,
  3227. DecryptRequestSize,
  3228. (PVOID *) &DecryptResponse,
  3229. &DecryptResponseSize,
  3230. &SubStatus
  3231. );
  3232. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3233. {
  3234. printf("Failed to decrypt message: 0x%x or 0x%x\n",Status,SubStatus);
  3235. return;
  3236. }
  3237. //
  3238. // Now decode the encrypted ticket
  3239. //
  3240. KerbErr = KerbUnpackData(
  3241. DecryptResponse->DecryptedData,
  3242. DecryptResponseSize,
  3243. KERB_ENCRYPTED_TICKET_PDU,
  3244. (PVOID *) &EncryptedTicket
  3245. );
  3246. if (!KERB_SUCCESS(KerbErr))
  3247. {
  3248. printf("Failed to unpack encrypted ticket: 0x%x\n",KerbErr);
  3249. return;
  3250. }
  3251. //
  3252. // Now print some fields
  3253. //
  3254. printf("Enc.Ticket client_realm = %s\n",EncryptedTicket->client_realm);
  3255. printf("Enc.Ticket. client_name = %s\n",EncryptedTicket->client_name.name_string->value);
  3256. LsaFreeReturnBuffer(DecryptResponse);
  3257. LsaFreeReturnBuffer(CacheResponse);
  3258. }
  3259. }
  3260. else if (_wcsnicmp(Function,L"decrypt:", wcslen(L"decrypt:")) == 0)
  3261. {
  3262. PKERB_RETRIEVE_TKT_REQUEST CacheRequest = NULL;
  3263. PKERB_RETRIEVE_TKT_RESPONSE CacheResponse = NULL;
  3264. UNICODE_STRING Target = {0};
  3265. UNICODE_STRING Target2 = {0};
  3266. UNICODE_STRING Password = {0};
  3267. UNICODE_STRING EmptyString = {0};
  3268. KERB_ENCRYPTION_KEY Key = {0};
  3269. USHORT Index;
  3270. KERBERR KerbErr;
  3271. RtlInitUnicodeString(
  3272. &Target2,
  3273. Function+wcslen(L"decrypt:")
  3274. );
  3275. for (Index = 0; Index < Target2.Length / sizeof(WCHAR) ; Index ++ )
  3276. {
  3277. if (Target2.Buffer[Index] == L':')
  3278. {
  3279. Password = Target2;
  3280. Password.Length = Index*2;
  3281. Target2.Buffer = Target2.Buffer+Index+1;
  3282. Target2.Length -= (Index+1)*2;
  3283. }
  3284. }
  3285. printf("Decrypting with key %wZ\n",&Password);
  3286. CacheRequest = (PKERB_RETRIEVE_TKT_REQUEST)
  3287. LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST));
  3288. CacheRequest->MessageType = KerbRetrieveEncodedTicketMessage;
  3289. Target.Buffer = (LPWSTR) (CacheRequest + 1);
  3290. Target.Length = Target2.Length;
  3291. Target.MaximumLength = Target2.MaximumLength;
  3292. RtlCopyMemory(
  3293. Target.Buffer,
  3294. Target2.Buffer,
  3295. Target2.Length
  3296. );
  3297. CacheRequest->TargetName = Target;
  3298. printf("Retrieving tickets: %wZ\n",
  3299. &CacheRequest->TargetName );
  3300. Status = LsaCallAuthenticationPackage(
  3301. LogonHandle,
  3302. PackageId,
  3303. CacheRequest,
  3304. Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST),
  3305. &Response,
  3306. &ResponseSize,
  3307. &SubStatus
  3308. );
  3309. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3310. {
  3311. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3312. }
  3313. else
  3314. {
  3315. PKERB_DECRYPT_REQUEST DecryptRequest = NULL;
  3316. PKERB_DECRYPT_RESPONSE DecryptResponse = NULL;
  3317. ULONG DecryptRequestSize = 0;
  3318. ULONG DecryptResponseSize = 0;
  3319. PKERB_ENCRYPTED_TICKET EncryptedTicket = NULL;
  3320. PKERB_TICKET DecodedTicket = NULL;
  3321. CacheResponse = (PKERB_RETRIEVE_TKT_RESPONSE) Response;
  3322. KerbErr = KerbUnpackData(
  3323. CacheResponse->Ticket.EncodedTicket,
  3324. CacheResponse->Ticket.EncodedTicketSize,
  3325. KERB_TICKET_PDU,
  3326. (PVOID *) &DecodedTicket
  3327. );
  3328. if (!KERB_SUCCESS(KerbErr))
  3329. {
  3330. printf("Failed to decode ticket: 0x%x\n",KerbErr);
  3331. return;
  3332. }
  3333. KerbErr = KerbHashPasswordEx(
  3334. &Password,
  3335. &EmptyString,
  3336. DecodedTicket->encrypted_part.encryption_type,
  3337. &Key
  3338. );
  3339. if (!KERB_SUCCESS(KerbErr))
  3340. {
  3341. printf("Failed to hash key %wZ with type %d\n",
  3342. &Password,
  3343. DecodedTicket->encrypted_part.encryption_type
  3344. );
  3345. return;
  3346. }
  3347. //
  3348. // Now try to decrypt the ticket with our default key
  3349. //
  3350. DecryptRequestSize = sizeof(KERB_DECRYPT_REQUEST) +
  3351. DecodedTicket->encrypted_part.cipher_text.length +
  3352. Key.keyvalue.length;
  3353. DecryptRequest = (PKERB_DECRYPT_REQUEST) LocalAlloc(LMEM_ZEROINIT, DecryptRequestSize);
  3354. DecryptRequest->MessageType = KerbDecryptDataMessage;
  3355. DecryptRequest->Flags = 0;
  3356. DecryptRequest->InitialVectorSize = 0;
  3357. DecryptRequest->InitialVector = NULL;
  3358. DecryptRequest->KeyUsage = KERB_TICKET_SALT;
  3359. DecryptRequest->CryptoType = DecodedTicket->encrypted_part.encryption_type;
  3360. DecryptRequest->EncryptedDataSize = DecodedTicket->encrypted_part.cipher_text.length;
  3361. DecryptRequest->EncryptedData = (PUCHAR) (DecryptRequest + 1);
  3362. RtlCopyMemory(
  3363. DecryptRequest->EncryptedData,
  3364. DecodedTicket->encrypted_part.cipher_text.value,
  3365. DecryptRequest->EncryptedDataSize
  3366. );
  3367. DecryptRequest->Key.KeyType = Key.keytype;
  3368. DecryptRequest->Key.Length = Key.keyvalue.length;
  3369. DecryptRequest->Key.Value = DecryptRequest->EncryptedData + DecryptRequest->EncryptedDataSize;
  3370. RtlCopyMemory(
  3371. DecryptRequest->Key.Value,
  3372. Key.keyvalue.value,
  3373. Key.keyvalue.length
  3374. );
  3375. Status = LsaCallAuthenticationPackage(
  3376. LogonHandle,
  3377. PackageId,
  3378. DecryptRequest,
  3379. DecryptRequestSize,
  3380. (PVOID *) &DecryptResponse,
  3381. &DecryptResponseSize,
  3382. &SubStatus
  3383. );
  3384. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3385. {
  3386. printf("Failed to decrypt message: 0x%x or 0x%x\n",Status,SubStatus);
  3387. return;
  3388. }
  3389. //
  3390. // Now decode the encrypted ticket
  3391. //
  3392. KerbErr = KerbUnpackData(
  3393. DecryptResponse->DecryptedData,
  3394. DecryptResponseSize,
  3395. KERB_ENCRYPTED_TICKET_PDU,
  3396. (PVOID *) &EncryptedTicket
  3397. );
  3398. if (!KERB_SUCCESS(KerbErr))
  3399. {
  3400. printf("Failed to unpack encrypted ticket: 0x%x\n",KerbErr);
  3401. return;
  3402. }
  3403. //
  3404. // Now print some fields
  3405. //
  3406. printf("Enc.Ticket client_realm = %s\n",EncryptedTicket->client_realm);
  3407. printf("Enc.Ticket. client_name = %s\n",EncryptedTicket->client_name.name_string->value);
  3408. LsaFreeReturnBuffer(DecryptResponse);
  3409. LsaFreeReturnBuffer(CacheResponse);
  3410. }
  3411. }
  3412. else if (_wcsnicmp(Function,L"binding:", wcslen(L"binding:")) == 0)
  3413. {
  3414. PKERB_ADD_BINDING_CACHE_ENTRY_REQUEST CacheRequest = NULL;
  3415. UNICODE_STRING Server = {0};
  3416. UNICODE_STRING Target = {0};
  3417. UNICODE_STRING Target2 = {0};
  3418. USHORT Index;
  3419. RtlInitUnicodeString(
  3420. &Target2,
  3421. Function+wcslen(L"binding:")
  3422. );
  3423. CacheRequest = (PKERB_ADD_BINDING_CACHE_ENTRY_REQUEST)
  3424. LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_ADD_BINDING_CACHE_ENTRY_REQUEST));
  3425. CacheRequest->MessageType = KerbAddBindingCacheEntryMessage;
  3426. Target.Buffer = (LPWSTR) (CacheRequest + 1);
  3427. Target.Length = Target2.Length;
  3428. Target.MaximumLength = Target2.MaximumLength;
  3429. RtlCopyMemory(
  3430. Target.Buffer,
  3431. Target2.Buffer,
  3432. Target2.Length
  3433. );
  3434. Server = Target;
  3435. for (Index = 0; Index < Target.Length / sizeof(WCHAR); Index++ )
  3436. {
  3437. if (Target.Buffer[Index] == L'@')
  3438. {
  3439. CacheRequest->KdcAddress.Buffer = Target.Buffer;
  3440. CacheRequest->KdcAddress.Length = 2*Index;
  3441. CacheRequest->KdcAddress.MaximumLength = CacheRequest->KdcAddress.Length;
  3442. CacheRequest->RealmName.Buffer = Target.Buffer+Index+1;
  3443. CacheRequest->RealmName.Length = Target.Length - 2*(Index+1);
  3444. CacheRequest->RealmName.MaximumLength = CacheRequest->RealmName.Length;
  3445. break;
  3446. }
  3447. else if (Target.Buffer[Index] == L'\\')
  3448. {
  3449. CacheRequest->RealmName.Buffer = Target.Buffer;
  3450. CacheRequest->RealmName.Length = 2*Index;
  3451. CacheRequest->RealmName.MaximumLength = CacheRequest->RealmName.Length;
  3452. CacheRequest->KdcAddress.Buffer = Target.Buffer+Index+1;
  3453. CacheRequest->KdcAddress.Length = Target.Length - 2*(Index+1);
  3454. CacheRequest->KdcAddress.MaximumLength = CacheRequest->KdcAddress.Length;
  3455. break;
  3456. }
  3457. }
  3458. CacheRequest->AddressType = 0;
  3459. printf("Updating binding cache: realm %wZ,kdc %wZ\n",
  3460. &CacheRequest->RealmName, &CacheRequest->KdcAddress );
  3461. Status = LsaCallAuthenticationPackage(
  3462. LogonHandle,
  3463. PackageId,
  3464. CacheRequest,
  3465. Target2.Length + sizeof(KERB_ADD_BINDING_CACHE_ENTRY_REQUEST),
  3466. &Response,
  3467. &ResponseSize,
  3468. &SubStatus
  3469. );
  3470. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3471. {
  3472. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3473. }
  3474. }
  3475. else if (_wcsnicmp(Function,L"purgesc:", wcslen(L"purgesc:")) == 0)
  3476. {
  3477. PKERB_REFRESH_SCCRED_REQUEST PurgeRequest = NULL;
  3478. ULONG RequestSize = sizeof(KERB_REFRESH_SCCRED_REQUEST);
  3479. UNICODE_STRING CredBlob = {0};
  3480. RtlInitUnicodeString(
  3481. &CredBlob,
  3482. Function+wcslen(L"purgesc:")
  3483. );
  3484. RequestSize += CredBlob.MaximumLength;
  3485. PurgeRequest = (PKERB_REFRESH_SCCRED_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize);
  3486. PurgeRequest->MessageType = KerbRefreshSmartcardCredentialsMessage;
  3487. PurgeRequest->Flags = KERB_REFRESH_SCCRED_GETTGT;
  3488. PurgeRequest->LogonId.LowPart = 0;
  3489. PurgeRequest->LogonId.HighPart = 0;
  3490. PurgeRequest->CredentialBlob.Buffer = (LPWSTR) ( PurgeRequest + 1 );
  3491. PurgeRequest->CredentialBlob.Length = CredBlob.Length;
  3492. PurgeRequest->CredentialBlob.MaximumLength = CredBlob.MaximumLength;
  3493. RtlCopyMemory(
  3494. PurgeRequest->CredentialBlob.Buffer,
  3495. CredBlob.Buffer,
  3496. CredBlob.MaximumLength
  3497. );
  3498. printf("Purging SC creds\n");
  3499. Status = LsaCallAuthenticationPackage(
  3500. LogonHandle,
  3501. PackageId,
  3502. PurgeRequest,
  3503. RequestSize,
  3504. &Response,
  3505. &ResponseSize,
  3506. &SubStatus
  3507. );
  3508. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3509. {
  3510. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3511. }
  3512. }
  3513. if (LogonHandle != NULL)
  3514. {
  3515. LsaDeregisterLogonProcess(LogonHandle);
  3516. }
  3517. if (CacheResponse != NULL)
  3518. {
  3519. LsaFreeReturnBuffer(CacheResponse);
  3520. }
  3521. }
  3522. VOID
  3523. TestGetTicketRoutine(
  3524. IN LPWSTR TargetName,
  3525. IN LPWSTR OPTIONAL UserName,
  3526. IN LPWSTR OPTIONAL DomainName,
  3527. IN LPWSTR OPTIONAL Password,
  3528. IN ULONG Flags
  3529. )
  3530. {
  3531. NTSTATUS Status;
  3532. BOOLEAN WasEnabled;
  3533. STRING Name;
  3534. ULONG Dummy;
  3535. HANDLE LogonHandle = NULL;
  3536. ULONG PackageId;
  3537. PVOID Response;
  3538. ULONG ResponseSize;
  3539. NTSTATUS SubStatus;
  3540. BOOLEAN Trusted = TRUE;
  3541. CredHandle Credentials = {0};
  3542. BOOLEAN UseCreds = FALSE;
  3543. //
  3544. // Turn on the TCB privilege
  3545. //
  3546. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  3547. if (!NT_SUCCESS(Status))
  3548. {
  3549. Trusted = FALSE;
  3550. }
  3551. RtlInitString(
  3552. &Name,
  3553. "SspTest"
  3554. );
  3555. if (Trusted)
  3556. {
  3557. Status = LsaRegisterLogonProcess(
  3558. &Name,
  3559. &LogonHandle,
  3560. &Dummy
  3561. );
  3562. }
  3563. else
  3564. {
  3565. Status = LsaConnectUntrusted(
  3566. &LogonHandle
  3567. );
  3568. }
  3569. if (!NT_SUCCESS(Status))
  3570. {
  3571. printf("Failed to register as a logon process: 0x%x\n",Status);
  3572. return;
  3573. }
  3574. RtlInitString(
  3575. &Name,
  3576. MICROSOFT_KERBEROS_NAME_A
  3577. );
  3578. Status = LsaLookupAuthenticationPackage(
  3579. LogonHandle,
  3580. &Name,
  3581. &PackageId
  3582. );
  3583. if (!NT_SUCCESS(Status))
  3584. {
  3585. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  3586. return;
  3587. }
  3588. //
  3589. // Get a cred handle if we need one
  3590. //
  3591. if ((UserName != NULL) ||
  3592. (DomainName != NULL) ||
  3593. (Password != NULL))
  3594. {
  3595. if (!GetCredentialsHandle(
  3596. &Credentials,
  3597. MICROSOFT_KERBEROS_NAME_W,
  3598. UserName,
  3599. DomainName,
  3600. Password,
  3601. SECPKG_CRED_OUTBOUND
  3602. ))
  3603. {
  3604. printf("Failed to get creds\n");
  3605. return;
  3606. }
  3607. UseCreds = TRUE;
  3608. }
  3609. {
  3610. PKERB_RETRIEVE_TKT_REQUEST CacheRequest = NULL;
  3611. PKERB_RETRIEVE_TKT_RESPONSE CacheResponse = NULL;
  3612. UNICODE_STRING Target = {0};
  3613. UNICODE_STRING Target2 = {0};
  3614. RtlInitUnicodeString(
  3615. &Target2,
  3616. TargetName
  3617. );
  3618. CacheRequest = (PKERB_RETRIEVE_TKT_REQUEST)
  3619. LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST));
  3620. CacheRequest->MessageType = KerbRetrieveEncodedTicketMessage;
  3621. CacheRequest->CacheOptions = Flags;
  3622. if (UseCreds)
  3623. {
  3624. CacheRequest->CacheOptions |= KERB_RETRIEVE_TICKET_USE_CREDHANDLE;
  3625. CacheRequest->CredentialsHandle = Credentials;
  3626. }
  3627. Target.Buffer = (LPWSTR) (CacheRequest + 1);
  3628. Target.Length = Target2.Length;
  3629. Target.MaximumLength = Target2.MaximumLength;
  3630. RtlCopyMemory(
  3631. Target.Buffer,
  3632. Target2.Buffer,
  3633. Target2.Length
  3634. );
  3635. CacheRequest->TargetName = Target;
  3636. printf("Retrieving tickets: %wZ\n",
  3637. &CacheRequest->TargetName );
  3638. Status = LsaCallAuthenticationPackage(
  3639. LogonHandle,
  3640. PackageId,
  3641. CacheRequest,
  3642. Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST),
  3643. &Response,
  3644. &ResponseSize,
  3645. &SubStatus
  3646. );
  3647. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3648. {
  3649. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3650. }
  3651. else
  3652. {
  3653. CacheResponse = (PKERB_RETRIEVE_TKT_RESPONSE) Response;
  3654. printf("Cached Ticket:\n");
  3655. printf("ServiceName: "); PrintKdcName(CacheResponse->Ticket.ServiceName);
  3656. printf("TargetName: "); PrintKdcName(CacheResponse->Ticket.TargetName);
  3657. printf("DomainName: %wZ\n",&CacheResponse->Ticket.DomainName);
  3658. printf("TargetDomainName: %wZ\n",&CacheResponse->Ticket.TargetDomainName);
  3659. printf("ClientDomainName: %wZ\n", &CacheResponse->Ticket.AltTargetDomainName);
  3660. printf("ClientName: "); PrintKdcName(CacheResponse->Ticket.ClientName);
  3661. printf("TicketFlags: 0x%x\n",CacheResponse->Ticket.TicketFlags);
  3662. PrintTime("StartTime: ",CacheResponse->Ticket.StartTime);
  3663. PrintTime("StartTime: ",CacheResponse->Ticket.StartTime);
  3664. PrintTime("EndTime: ",CacheResponse->Ticket.EndTime);
  3665. PrintTime("RenewUntil: ",CacheResponse->Ticket.RenewUntil);
  3666. PrintTime("TimeSkew: ",CacheResponse->Ticket.TimeSkew);
  3667. LsaFreeReturnBuffer(CacheResponse);
  3668. }
  3669. }
  3670. if (UseCreds)
  3671. {
  3672. FreeCredentialsHandle(&Credentials);
  3673. }
  3674. }
  3675. #include <ntmsv1_0.h>
  3676. VOID
  3677. TestChangeCachedPassword(
  3678. IN LPWSTR AccountName,
  3679. IN LPWSTR DomainName,
  3680. IN LPWSTR NewPassword
  3681. )
  3682. {
  3683. PMSV1_0_CHANGEPASSWORD_REQUEST Request = NULL;
  3684. HANDLE LogonHandle = NULL;
  3685. ULONG Dummy;
  3686. ULONG RequestSize = 0;
  3687. ULONG PackageId = 0;
  3688. PVOID Response;
  3689. ULONG ResponseSize;
  3690. NTSTATUS SubStatus = STATUS_SUCCESS, Status = STATUS_SUCCESS;
  3691. BOOLEAN Trusted = TRUE;
  3692. BOOLEAN WasEnabled;
  3693. PBYTE Where;
  3694. STRING Name;
  3695. //
  3696. // Turn on the TCB privilege
  3697. //
  3698. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  3699. if (!NT_SUCCESS(Status))
  3700. {
  3701. Trusted = FALSE;
  3702. }
  3703. RtlInitString(
  3704. &Name,
  3705. "SspTest"
  3706. );
  3707. if (Trusted)
  3708. {
  3709. Status = LsaRegisterLogonProcess(
  3710. &Name,
  3711. &LogonHandle,
  3712. &Dummy
  3713. );
  3714. }
  3715. else
  3716. {
  3717. Status = LsaConnectUntrusted(
  3718. &LogonHandle
  3719. );
  3720. }
  3721. if (!NT_SUCCESS(Status))
  3722. {
  3723. printf("Failed to register as a logon process: 0x%x\n",Status);
  3724. return;
  3725. }
  3726. RtlInitString(
  3727. &Name,
  3728. MSV1_0_PACKAGE_NAME
  3729. );
  3730. Status = LsaLookupAuthenticationPackage(
  3731. LogonHandle,
  3732. &Name,
  3733. &PackageId
  3734. );
  3735. if (!NT_SUCCESS(Status))
  3736. {
  3737. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  3738. return;
  3739. }
  3740. RequestSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) +
  3741. ((ULONG) wcslen(AccountName) +
  3742. (ULONG) wcslen(DomainName) +
  3743. (ULONG) (wcslen(NewPassword) + 3) * sizeof(WCHAR));
  3744. Request = (PMSV1_0_CHANGEPASSWORD_REQUEST) LocalAlloc(LMEM_ZEROINIT,RequestSize);
  3745. Where = (PBYTE) (Request + 1);
  3746. Request->MessageType = MsV1_0ChangeCachedPassword;
  3747. wcscpy(
  3748. (LPWSTR) Where,
  3749. DomainName
  3750. );
  3751. RtlInitUnicodeString(
  3752. &Request->DomainName,
  3753. (LPWSTR) Where
  3754. );
  3755. Where += Request->DomainName.MaximumLength;
  3756. wcscpy(
  3757. (LPWSTR) Where,
  3758. AccountName
  3759. );
  3760. RtlInitUnicodeString(
  3761. &Request->AccountName,
  3762. (LPWSTR) Where
  3763. );
  3764. Where += Request->AccountName.MaximumLength;
  3765. wcscpy(
  3766. (LPWSTR) Where,
  3767. NewPassword
  3768. );
  3769. RtlInitUnicodeString(
  3770. &Request->NewPassword,
  3771. (LPWSTR) Where
  3772. );
  3773. Where += Request->NewPassword.MaximumLength;
  3774. //
  3775. // Make the call
  3776. //
  3777. Status = LsaCallAuthenticationPackage(
  3778. LogonHandle,
  3779. PackageId,
  3780. Request,
  3781. RequestSize,
  3782. &Response,
  3783. &ResponseSize,
  3784. &SubStatus
  3785. );
  3786. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3787. {
  3788. printf("changepass failed: 0x%x, 0x%x\n",Status, SubStatus);
  3789. }
  3790. if (LogonHandle != NULL)
  3791. {
  3792. LsaDeregisterLogonProcess(LogonHandle);
  3793. }
  3794. }
  3795. VOID
  3796. TestChangePasswordRoutine(
  3797. IN LPWSTR UserName,
  3798. IN LPWSTR DomainName,
  3799. IN LPWSTR OldPassword,
  3800. IN LPWSTR NewPassword
  3801. )
  3802. {
  3803. #if 1
  3804. NTSTATUS Status;
  3805. Status = KerbChangePasswordUser(
  3806. DomainName,
  3807. UserName,
  3808. OldPassword,
  3809. NewPassword
  3810. );
  3811. if (!NT_SUCCESS(Status))
  3812. {
  3813. printf("Failed to change password: 0x%x\n",Status);
  3814. }
  3815. else
  3816. {
  3817. printf("Change password succeeded\n");
  3818. }
  3819. #else
  3820. NTSTATUS Status;
  3821. BOOLEAN WasEnabled;
  3822. STRING Name;
  3823. ULONG Dummy;
  3824. HANDLE LogonHandle = NULL;
  3825. ULONG PackageId;
  3826. PVOID Response;
  3827. ULONG ResponseSize;
  3828. NTSTATUS SubStatus;
  3829. BOOLEAN Trusted = TRUE;
  3830. PKERB_CHANGEPASSWORD_REQUEST ChangeRequest = NULL;
  3831. ULONG ChangeSize;
  3832. UNICODE_STRING User,Domain,OldPass,NewPass;
  3833. //
  3834. // Turn on the TCB privilege
  3835. //
  3836. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  3837. if (!NT_SUCCESS(Status))
  3838. {
  3839. Trusted = FALSE;
  3840. }
  3841. RtlInitString(
  3842. &Name,
  3843. "SspTest"
  3844. );
  3845. if (Trusted)
  3846. {
  3847. Status = LsaRegisterLogonProcess(
  3848. &Name,
  3849. &LogonHandle,
  3850. &Dummy
  3851. );
  3852. }
  3853. else
  3854. {
  3855. Status = LsaConnectUntrusted(
  3856. &LogonHandle
  3857. );
  3858. }
  3859. if (!NT_SUCCESS(Status))
  3860. {
  3861. printf("Failed to register as a logon process: 0x%x\n",Status);
  3862. return;
  3863. }
  3864. RtlInitString(
  3865. &Name,
  3866. MICROSOFT_KERBEROS_NAME_A
  3867. );
  3868. Status = LsaLookupAuthenticationPackage(
  3869. LogonHandle,
  3870. &Name,
  3871. &PackageId
  3872. );
  3873. if (!NT_SUCCESS(Status))
  3874. {
  3875. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  3876. return;
  3877. }
  3878. RtlInitUnicodeString(
  3879. &User,
  3880. UserName
  3881. );
  3882. RtlInitUnicodeString(
  3883. &Domain,
  3884. DomainName
  3885. );
  3886. RtlInitUnicodeString(
  3887. &OldPass,
  3888. OldPassword
  3889. );
  3890. RtlInitUnicodeString(
  3891. &NewPass,
  3892. NewPassword
  3893. );
  3894. ChangeSize = ROUND_UP_COUNT(sizeof(KERB_CHANGEPASSWORD_REQUEST),4)+
  3895. User.Length +
  3896. Domain.Length +
  3897. OldPass.Length +
  3898. NewPass.Length ;
  3899. ChangeRequest = (PKERB_CHANGEPASSWORD_REQUEST) LocalAlloc(LMEM_ZEROINIT, ChangeSize );
  3900. ChangeRequest->MessageType = KerbChangePasswordMessage;
  3901. ChangeRequest->AccountName = User;
  3902. ChangeRequest->AccountName.Buffer = (LPWSTR) ROUND_UP_POINTER(sizeof(KERB_CHANGEPASSWORD_REQUEST) + (PBYTE) ChangeRequest,4);
  3903. RtlCopyMemory(
  3904. ChangeRequest->AccountName.Buffer,
  3905. User.Buffer,
  3906. User.Length
  3907. );
  3908. ChangeRequest->DomainName = Domain;
  3909. ChangeRequest->DomainName.Buffer = ChangeRequest->AccountName.Buffer + ChangeRequest->AccountName.Length / sizeof(WCHAR);
  3910. RtlCopyMemory(
  3911. ChangeRequest->DomainName.Buffer,
  3912. Domain.Buffer,
  3913. Domain.Length
  3914. );
  3915. ChangeRequest->OldPassword = OldPass;
  3916. ChangeRequest->OldPassword.Buffer = ChangeRequest->DomainName.Buffer + ChangeRequest->DomainName.Length / sizeof(WCHAR);
  3917. RtlCopyMemory(
  3918. ChangeRequest->OldPassword.Buffer,
  3919. OldPass.Buffer,
  3920. OldPass.Length
  3921. );
  3922. ChangeRequest->NewPassword = NewPass;
  3923. ChangeRequest->NewPassword.Buffer = ChangeRequest->OldPassword.Buffer + ChangeRequest->OldPassword.Length / sizeof(WCHAR);
  3924. RtlCopyMemory(
  3925. ChangeRequest->NewPassword.Buffer,
  3926. NewPass.Buffer,
  3927. NewPass.Length
  3928. );
  3929. printf("Changing password for %wZ@%wZ from %wZ to %wZ\n",
  3930. &ChangeRequest->AccountName,
  3931. &ChangeRequest->DomainName,
  3932. &ChangeRequest->OldPassword,
  3933. &ChangeRequest->NewPassword
  3934. );
  3935. ChangeRequest->Impersonating = TRUE;
  3936. Status = LsaCallAuthenticationPackage(
  3937. LogonHandle,
  3938. PackageId,
  3939. ChangeRequest,
  3940. ChangeSize,
  3941. &Response,
  3942. &ResponseSize,
  3943. &SubStatus
  3944. );
  3945. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  3946. {
  3947. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  3948. }
  3949. if (LogonHandle != NULL)
  3950. {
  3951. LsaDeregisterLogonProcess(LogonHandle);
  3952. }
  3953. if (Response != NULL)
  3954. {
  3955. LsaFreeReturnBuffer(Response);
  3956. }
  3957. #endif
  3958. }
  3959. VOID
  3960. TestSetPasswordRoutine(
  3961. IN LPWSTR UserName,
  3962. IN LPWSTR DomainName,
  3963. IN LPWSTR NewPassword
  3964. )
  3965. {
  3966. #if 1
  3967. NTSTATUS Status;
  3968. Status = KerbSetPasswordUser(
  3969. DomainName,
  3970. UserName,
  3971. NewPassword,
  3972. NULL
  3973. );
  3974. if (!NT_SUCCESS(Status))
  3975. {
  3976. printf("Failed to set password: 0x%x\n",Status);
  3977. }
  3978. else
  3979. {
  3980. printf("Set password succeeded\n");
  3981. }
  3982. #else
  3983. NTSTATUS Status;
  3984. BOOLEAN WasEnabled;
  3985. STRING Name;
  3986. ULONG Dummy;
  3987. HANDLE LogonHandle = NULL;
  3988. ULONG PackageId;
  3989. PVOID Response;
  3990. ULONG ResponseSize;
  3991. NTSTATUS SubStatus;
  3992. BOOLEAN Trusted = TRUE;
  3993. PKERB_SETPASSWORD_REQUEST SetRequest = NULL;
  3994. ULONG ChangeSize;
  3995. UNICODE_STRING User,Domain,OldPass,NewPass;
  3996. //
  3997. // Turn on the TCB privilege
  3998. //
  3999. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  4000. if (!NT_SUCCESS(Status))
  4001. {
  4002. Trusted = FALSE;
  4003. }
  4004. RtlInitString(
  4005. &Name,
  4006. "SspTest"
  4007. );
  4008. if (Trusted)
  4009. {
  4010. Status = LsaRegisterLogonProcess(
  4011. &Name,
  4012. &LogonHandle,
  4013. &Dummy
  4014. );
  4015. }
  4016. else
  4017. {
  4018. Status = LsaConnectUntrusted(
  4019. &LogonHandle
  4020. );
  4021. }
  4022. if (!NT_SUCCESS(Status))
  4023. {
  4024. printf("Failed to register as a logon process: 0x%x\n",Status);
  4025. return;
  4026. }
  4027. RtlInitString(
  4028. &Name,
  4029. MICROSOFT_KERBEROS_NAME_A
  4030. );
  4031. Status = LsaLookupAuthenticationPackage(
  4032. LogonHandle,
  4033. &Name,
  4034. &PackageId
  4035. );
  4036. if (!NT_SUCCESS(Status))
  4037. {
  4038. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  4039. return;
  4040. }
  4041. RtlInitUnicodeString(
  4042. &User,
  4043. UserName
  4044. );
  4045. RtlInitUnicodeString(
  4046. &Domain,
  4047. DomainName
  4048. );
  4049. RtlInitUnicodeString(
  4050. &NewPass,
  4051. NewPassword
  4052. );
  4053. ChangeSize = ROUND_UP_COUNT(sizeof(KERB_SETPASSWORD_REQUEST),4)+
  4054. User.Length +
  4055. Domain.Length +
  4056. NewPass.Length ;
  4057. SetRequest = (PKERB_SETPASSWORD_REQUEST) LocalAlloc(LMEM_ZEROINIT, ChangeSize );
  4058. SetRequest->MessageType = KerbSetPasswordMessage;
  4059. SetRequest->AccountName = User;
  4060. SetRequest->AccountName.Buffer = (LPWSTR) ROUND_UP_POINTER(sizeof(KERB_SETPASSWORD_REQUEST) + (PBYTE) SetRequest,4);
  4061. RtlCopyMemory(
  4062. SetRequest->AccountName.Buffer,
  4063. User.Buffer,
  4064. User.Length
  4065. );
  4066. SetRequest->DomainName = Domain;
  4067. SetRequest->DomainName.Buffer = SetRequest->AccountName.Buffer + SetRequest->AccountName.Length / sizeof(WCHAR);
  4068. RtlCopyMemory(
  4069. SetRequest->DomainName.Buffer,
  4070. Domain.Buffer,
  4071. Domain.Length
  4072. );
  4073. SetRequest->Password = NewPass;
  4074. SetRequest->Password.Buffer = SetRequest->DomainName.Buffer + SetRequest->DomainName.Length / sizeof(WCHAR);
  4075. RtlCopyMemory(
  4076. SetRequest->Password.Buffer,
  4077. NewPass.Buffer,
  4078. NewPass.Length
  4079. );
  4080. printf("Setting password for %wZ@%wZ to %wZ\n",
  4081. &SetRequest->AccountName,
  4082. &SetRequest->DomainName,
  4083. &SetRequest->Password
  4084. );
  4085. Status = LsaCallAuthenticationPackage(
  4086. LogonHandle,
  4087. PackageId,
  4088. SetRequest,
  4089. ChangeSize,
  4090. &Response,
  4091. &ResponseSize,
  4092. &SubStatus
  4093. );
  4094. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  4095. {
  4096. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  4097. }
  4098. if (LogonHandle != NULL)
  4099. {
  4100. LsaDeregisterLogonProcess(LogonHandle);
  4101. }
  4102. if (Response != NULL)
  4103. {
  4104. LsaFreeReturnBuffer(Response);
  4105. }
  4106. #endif
  4107. }
  4108. /*
  4109. #define KERB_REQUEST_ADD_CREDENTIAL 1
  4110. #define KERB_REQUEST_REPLACE_CREDENTIAL 2
  4111. #define KERB_REQUEST_REMOVE_CREDENTIAL 4
  4112. */
  4113. #define KERB_TEST_REGISTER 0x10
  4114. /*
  4115. VOID
  4116. TestRegisterMultiCred(
  4117. LPWSTR MachineName,
  4118. LPWSTR Domain,
  4119. LPWSTR Password,
  4120. ULONG Flags
  4121. )
  4122. {
  4123. SERVER_TRANSPORT_INFO_2 sti2 = {0};
  4124. CHAR netBiosName[ NETBIOS_NAME_LEN ];
  4125. OEM_STRING netBiosNameString;
  4126. UNICODE_STRING unicodeName;
  4127. NET_API_STATUS status;
  4128. NTSTATUS ntStatus;
  4129. LPSERVER_TRANSPORT_INFO_0 pBuf = NULL;
  4130. LPSERVER_TRANSPORT_INFO_0 pTmpBuf;
  4131. DWORD dwEntriesRead = 0;
  4132. DWORD dwTotalEntries = 0;
  4133. DWORD dwResumeHandle = 0;
  4134. DWORD i = 0;
  4135. DWORD dwTotalCount = 0;
  4136. PKERB_ADD_CREDENTIALS_REQUEST AddCredRequest = NULL;
  4137. ULONG Buffsize = sizeof(KERB_ADD_CREDENTIALS_REQUEST);
  4138. UNICODE_STRING Target2 = {0};
  4139. PVOID Response;
  4140. ULONG ResponseSize;
  4141. NTSTATUS SubStatus = STATUS_SUCCESS, Status = STATUS_SUCCESS;
  4142. BOOLEAN Trusted = TRUE;
  4143. BOOLEAN WasEnabled;
  4144. HANDLE LogonHandle = NULL;
  4145. ULONG Dummy;
  4146. ULONG PackageId;
  4147. STRING Name;
  4148. PBYTE Where;
  4149. if ((Flags & KERB_TEST_REGISTER) != 0)
  4150. {
  4151. printf("Adding Netbios transport\n");
  4152. RtlInitUnicodeString( &unicodeName, MachineName );
  4153. netBiosNameString.Buffer = (PCHAR)netBiosName;
  4154. netBiosNameString.MaximumLength = sizeof( netBiosName );
  4155. ntStatus = RtlUpcaseUnicodeStringToOemString(
  4156. &netBiosNameString,
  4157. &unicodeName,
  4158. FALSE
  4159. );
  4160. if (ntStatus != STATUS_SUCCESS) {
  4161. printf("String conversion failed - %x\n", ntStatus);
  4162. return;
  4163. }
  4164. //
  4165. // Enum, and change, existing transports.
  4166. //
  4167. do
  4168. {
  4169. status = NetServerTransportEnum(NULL,
  4170. 0,
  4171. (LPBYTE *) &pBuf,
  4172. MAX_PREFERRED_LENGTH,
  4173. &dwEntriesRead,
  4174. &dwTotalEntries,
  4175. &dwResumeHandle);
  4176. //
  4177. // If the call succeeds,
  4178. //
  4179. if ((status == NERR_Success) || (status == ERROR_MORE_DATA))
  4180. {
  4181. if ((pTmpBuf = pBuf) != NULL)
  4182. {
  4183. //
  4184. // Loop through the entries;
  4185. // process access errors.
  4186. //
  4187. for (i = 0; i < dwEntriesRead; i++)
  4188. {
  4189. sti2.svti2_transportaddress = (LPBYTE) netBiosName;
  4190. sti2.svti2_transportaddresslength = strlen(netBiosName);
  4191. sti2.svti2_transportname = pTmpBuf->svti0_transportname;
  4192. status = NetServerTransportAddEx( NULL, 2, (LPBYTE)&sti2 );
  4193. if (status)
  4194. {
  4195. printf("NetServerTransportAddEx failed - %x\n", status);
  4196. }
  4197. //
  4198. // Print the transport protocol name.
  4199. //
  4200. wprintf(L"\tTransport: %s\n", pTmpBuf->svti0_transportname);
  4201. pTmpBuf++;
  4202. dwTotalCount++;
  4203. }
  4204. }
  4205. }
  4206. //
  4207. // Otherwise, indicate a system error.
  4208. //
  4209. else
  4210. printf("A system error has occurred: %d\n", status);
  4211. //
  4212. // Free the allocated buffer.
  4213. //
  4214. if (pBuf != NULL)
  4215. {
  4216. NetApiBufferFree(pBuf);
  4217. pBuf = NULL;
  4218. }
  4219. }
  4220. while (status == ERROR_MORE_DATA); // end do
  4221. }
  4222. //
  4223. // Turn on the TCB privilege
  4224. //
  4225. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  4226. if (!NT_SUCCESS(Status))
  4227. {
  4228. Trusted = FALSE;
  4229. }
  4230. RtlInitString(
  4231. &Name,
  4232. "SspTest"
  4233. );
  4234. if (Trusted)
  4235. {
  4236. Status = LsaRegisterLogonProcess(
  4237. &Name,
  4238. &LogonHandle,
  4239. &Dummy
  4240. );
  4241. }
  4242. else
  4243. {
  4244. Status = LsaConnectUntrusted(
  4245. &LogonHandle
  4246. );
  4247. }
  4248. if (!NT_SUCCESS(Status))
  4249. {
  4250. printf("Failed to register as a logon process: 0x%x\n",Status);
  4251. return;
  4252. }
  4253. RtlInitString(
  4254. &Name,
  4255. MICROSOFT_KERBEROS_NAME_A
  4256. );
  4257. Status = LsaLookupAuthenticationPackage(
  4258. LogonHandle,
  4259. &Name,
  4260. &PackageId
  4261. );
  4262. if (!NT_SUCCESS(Status))
  4263. {
  4264. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  4265. return;
  4266. }
  4267. Buffsize += (sizeof(WCHAR) * ( wcslen(MachineName) + wcslen(Domain) + wcslen(Password) + 3));
  4268. AddCredRequest = (PKERB_ADD_CREDENTIALS_REQUEST) LocalAlloc(LMEM_ZEROINIT,Buffsize);
  4269. if (NULL == AddCredRequest)
  4270. {
  4271. return;
  4272. }
  4273. AddCredRequest->MessageType = KerbAddExtraCredentialsMessage;
  4274. RtlInitUnicodeString(
  4275. &Target2,
  4276. MachineName
  4277. );
  4278. AddCredRequest->UserName.Buffer = (LPWSTR) (AddCredRequest + 1);
  4279. AddCredRequest->UserName.Length = Target2.Length;
  4280. AddCredRequest->UserName.MaximumLength = Target2.MaximumLength;
  4281. RtlCopyMemory(
  4282. AddCredRequest->UserName.Buffer,
  4283. Target2.Buffer,
  4284. Target2.MaximumLength
  4285. );
  4286. RtlInitUnicodeString(
  4287. &Target2,
  4288. Domain
  4289. );
  4290. Where = ((PBYTE) AddCredRequest->UserName.Buffer) + AddCredRequest->UserName.MaximumLength;
  4291. AddCredRequest->DomainName.Buffer = (LPWSTR) Where;
  4292. AddCredRequest->DomainName.Length = Target2.Length;
  4293. AddCredRequest->DomainName.MaximumLength = Target2.MaximumLength;
  4294. RtlCopyMemory(
  4295. AddCredRequest->DomainName.Buffer,
  4296. Target2.Buffer,
  4297. Target2.MaximumLength
  4298. );
  4299. RtlInitUnicodeString(
  4300. &Target2,
  4301. Password
  4302. );
  4303. Where += AddCredRequest->DomainName.MaximumLength;
  4304. AddCredRequest->Password.Buffer = (LPWSTR) Where;
  4305. AddCredRequest->Password.Length = Target2.Length;
  4306. AddCredRequest->Password.MaximumLength = Target2.MaximumLength;
  4307. RtlCopyMemory(
  4308. AddCredRequest->Password.Buffer,
  4309. Target2.Buffer,
  4310. Target2.MaximumLength
  4311. );
  4312. AddCredRequest->Flags = Flags;
  4313. printf("Updating second creds: u %wZ, d %wZ, p %wZ\n",
  4314. &AddCredRequest->UserName, &AddCredRequest->DomainName, &AddCredRequest->Password );
  4315. Status = LsaCallAuthenticationPackage(
  4316. LogonHandle,
  4317. PackageId,
  4318. AddCredRequest,
  4319. Buffsize,
  4320. &Response,
  4321. &ResponseSize,
  4322. &SubStatus
  4323. );
  4324. if (!NT_SUCCESS(Status) || !NT_SUCCESS(SubStatus))
  4325. {
  4326. printf("token failed: 0x%x, 0x %x\n",Status, SubStatus);
  4327. }
  4328. if (LogonHandle != NULL)
  4329. {
  4330. LsaDeregisterLogonProcess(LogonHandle);
  4331. }
  4332. return;
  4333. } */
  4334. PVOID
  4335. KdcAllocate(SIZE_T size)
  4336. {
  4337. return LocalAlloc( 0, size );
  4338. }
  4339. VOID
  4340. KdcFree(PVOID buff)
  4341. {
  4342. LocalFree( buff );
  4343. }
  4344. int __cdecl
  4345. main(
  4346. IN int argc,
  4347. IN char ** argv
  4348. )
  4349. /*++
  4350. Routine Description:
  4351. Drive the NtLmSsp service
  4352. Arguments:
  4353. argc - the number of command-line arguments.
  4354. argv - an array of pointers to the arguments.
  4355. Return Value:
  4356. Exit status
  4357. --*/
  4358. {
  4359. LPSTR argument;
  4360. int i;
  4361. ULONG j;
  4362. ULONG Iterations = 0;
  4363. LPSTR UserName = NULL,DomainName = NULL,Password = NULL, Package = MICROSOFT_KERBEROS_NAME_A;
  4364. LPWSTR DomainNameW = NULL;
  4365. LPWSTR UserNameW = NULL;
  4366. LPWSTR PasswordW = NULL;
  4367. LPWSTR OldPasswordW = NULL;
  4368. LPWSTR ServerDomainName = NULL;
  4369. LPWSTR ServerUserName = NULL;
  4370. LPWSTR ServerPassword = NULL;
  4371. LPWSTR TargetName = NULL;
  4372. LPWSTR PackageName = NULL;
  4373. LPWSTR PackageFunction = NULL;
  4374. LPWSTR PackageList = NULL;
  4375. ULONG ContextReq = 0;
  4376. ULONG CredFlags = 0;
  4377. BOOLEAN Relogon = FALSE;
  4378. SECURITY_LOGON_TYPE LogonType = Interactive;
  4379. enum {
  4380. NoAction,
  4381. #define USER_PARAM "/user:"
  4382. #define DOMAIN_PARAM "/domain:"
  4383. #define PASSWORD_PARAM "/password:"
  4384. #define CHANGE_PASSWORD_PARAM "/changepass:"
  4385. ChangePassword,
  4386. #define SET_PASSWORD_PARAM "/setpass"
  4387. SetPassword,
  4388. #define CHANGE_CACHED_PASSWORD_PARAM "/cache"
  4389. ChangeCachedPassword,
  4390. #define SERVER_USER_PARAM "/serveruser:"
  4391. #define SERVER_DOMAIN_PARAM "/serverdomain:"
  4392. #define SERVER_PASSWORD_PARAM "/serverpassword:"
  4393. #define TARGET_PARAM "/target:"
  4394. #define PACKAGENAME_PARAM "/package:"
  4395. #define PACKAGELIST_PARAM "/packagelist:"
  4396. #define ANSI_PARAM "/ansi"
  4397. #define FLAG_PARAM "/flags:"
  4398. #define RECURSE_PARAM "/recurse:"
  4399. #define SYSTEM_PARAM "/system"
  4400. #define TESTSSP_PARAM "/TestSsp"
  4401. TestSsp,
  4402. #define LOGON_PARAM2 "/Logon:"
  4403. #define LOGON_PARAM "/Logon"
  4404. TestLogon,
  4405. #define PACKAGE_PARAM "/callpackage:"
  4406. #define PACKAGE_PARAM2 "/cp:"
  4407. TestPackage,
  4408. #define BATCH_PARAM "/batch"
  4409. #define RELOGON_PARAM "/relogon"
  4410. #define NOPAC_PARAM "/nopac"
  4411. #define GETTICKET_PARAM "/ticket:"
  4412. TestGetTicket,
  4413. #define TIME_PARAM "/time:"
  4414. #define S4ULOGON_PARAM "/S4U:"
  4415. TestS4ULogon,
  4416. #define ISC_PARAM "/ISC:"
  4417. QuickISCTest,
  4418. #define DUMPTOKEN_PARAM "/DUMPTOKEN:"
  4419. #define CONVERT_PARAM "/CONVERT:"
  4420. Convert
  4421. } Action = NoAction;
  4422. SafeAllocaInitialize(SAFEALLOCA_USE_DEFAULT, SAFEALLOCA_USE_DEFAULT, KdcAllocate, KdcFree);
  4423. //
  4424. // Loop through the arguments handle each in turn
  4425. //
  4426. for ( i=1; i<argc; i++ ) {
  4427. argument = argv[i];
  4428. //
  4429. // Handle /ConfigureService
  4430. //
  4431. if ( _stricmp( argument, ANSI_PARAM ) == 0 ) {
  4432. DoAnsi = TRUE;
  4433. } else if ( _stricmp( argument, TESTSSP_PARAM ) == 0 ) {
  4434. if ( Action != NoAction ) {
  4435. goto Usage;
  4436. }
  4437. Action = TestSsp;
  4438. Iterations = 1;
  4439. } else if ( _strnicmp( argument,
  4440. USER_PARAM,
  4441. sizeof(USER_PARAM)-1 ) == 0 ){
  4442. argument = &argument[sizeof(USER_PARAM)-1];
  4443. UserNameW = NetpAllocWStrFromStr( argument );
  4444. } else if ( _strnicmp( argument,
  4445. DOMAIN_PARAM,
  4446. sizeof(DOMAIN_PARAM)-1 ) == 0 ){
  4447. argument = &argument[sizeof(DOMAIN_PARAM)-1];
  4448. DomainNameW = NetpAllocWStrFromStr( argument );
  4449. } else if ( _strnicmp( argument,
  4450. PASSWORD_PARAM,
  4451. sizeof(PASSWORD_PARAM)-1 ) == 0 ){
  4452. argument = &argument[sizeof(PASSWORD_PARAM)-1];
  4453. PasswordW = NetpAllocWStrFromStr( argument );
  4454. } else if ( _strnicmp( argument,
  4455. SERVER_USER_PARAM,
  4456. sizeof(SERVER_USER_PARAM)-1 ) == 0 ){
  4457. argument = &argument[sizeof(SERVER_USER_PARAM)-1];
  4458. ServerUserName = NetpAllocWStrFromStr( argument );
  4459. } else if ( _strnicmp( argument,
  4460. SERVER_DOMAIN_PARAM,
  4461. sizeof(SERVER_DOMAIN_PARAM)-1 ) == 0 ){
  4462. argument = &argument[sizeof(SERVER_DOMAIN_PARAM)-1];
  4463. ServerDomainName = NetpAllocWStrFromStr( argument );
  4464. } else if ( _strnicmp( argument,
  4465. SERVER_PASSWORD_PARAM,
  4466. sizeof(SERVER_PASSWORD_PARAM)-1 ) == 0 ){
  4467. argument = &argument[sizeof(SERVER_PASSWORD_PARAM)-1];
  4468. ServerPassword = NetpAllocWStrFromStr( argument );
  4469. } else if ( _strnicmp( argument,
  4470. TARGET_PARAM,
  4471. sizeof(TARGET_PARAM)-1 ) == 0 ){
  4472. argument = &argument[sizeof(TARGET_PARAM)-1];
  4473. TargetName = NetpAllocWStrFromStr( argument );
  4474. } else if ( _strnicmp( argument,
  4475. PACKAGENAME_PARAM,
  4476. sizeof(PACKAGENAME_PARAM)-1 ) == 0 ){
  4477. Package = &argument[sizeof(PACKAGENAME_PARAM)-1];
  4478. PackageName = NetpAllocWStrFromStr( Package );
  4479. } else if (_strnicmp(argument,
  4480. TIME_PARAM,
  4481. sizeof(TIME_PARAM)-1 ) == 0 ){
  4482. char *end;
  4483. LARGE_INTEGER ConvertTime;
  4484. LONGLONG Time;
  4485. ConvertTime.LowPart = strtoul( &argument[sizeof(TIME_PARAM)-1], &end, 16 );
  4486. i++;
  4487. argument = argv[i];
  4488. ConvertTime.HighPart = strtoul( argument, &end, 16 );
  4489. Time = ConvertTime.QuadPart / 10000000;
  4490. if (Time < 60)
  4491. {
  4492. printf("time : %d seconds\n", (LONG) Time);
  4493. }
  4494. else
  4495. {
  4496. Time = Time / 60;
  4497. if (Time < 60)
  4498. {
  4499. printf("time : %d minutes\n", (LONG) Time);
  4500. }
  4501. else
  4502. {
  4503. Time = Time / 60;
  4504. if (Time < 24)
  4505. {
  4506. printf("time: %d hours\n", (LONG) Time);
  4507. }
  4508. else
  4509. {
  4510. Time = Time / 24;
  4511. printf("time: %d days\n",(LONG) Time);
  4512. }
  4513. }
  4514. }
  4515. } else if ( _strnicmp( argument,
  4516. FLAG_PARAM,
  4517. sizeof(FLAG_PARAM)-1 ) == 0 ){
  4518. sscanf(&argument[sizeof(FLAG_PARAM)-1], "%x",&ContextReq);
  4519. } else if ( _strnicmp( argument,
  4520. RECURSE_PARAM,
  4521. sizeof(RECURSE_PARAM)-1 ) == 0 ){
  4522. sscanf(&argument[sizeof(RECURSE_PARAM)-1], "%d",&MaxRecursionDepth);
  4523. } else if ( _strnicmp( argument,
  4524. PACKAGELIST_PARAM,
  4525. sizeof(PACKAGELIST_PARAM)-1 ) == 0 ){
  4526. argument = &argument[sizeof(PACKAGELIST_PARAM)-1];
  4527. PackageList = NetpAllocWStrFromStr( argument );
  4528. } else if (_strnicmp( argument,
  4529. BATCH_PARAM,
  4530. sizeof(BATCH_PARAM) - 1) == 0) {
  4531. LogonType = Batch;
  4532. } else if (_strnicmp( argument,
  4533. DUMPTOKEN_PARAM,
  4534. sizeof(DUMPTOKEN_PARAM) - 1) == 0) {
  4535. DumpToken = TRUE;
  4536. } else if (_strnicmp( argument,
  4537. RELOGON_PARAM,
  4538. sizeof(RELOGON_PARAM) - 1) == 0) {
  4539. Relogon = TRUE;
  4540. } else if (_strnicmp( argument,
  4541. NOPAC_PARAM,
  4542. sizeof(NOPAC_PARAM) - 1) == 0) {
  4543. CredFlags |= SEC_WINNT_AUTH_IDENTITY_ONLY;
  4544. } else if (_strnicmp( argument,
  4545. SYSTEM_PARAM,
  4546. sizeof(SYSTEM_PARAM) - 1) == 0) {
  4547. HANDLE hWinlogon = NULL;
  4548. HANDLE SystemToken = NULL;
  4549. hWinlogon = FindAndOpenWinlogon();
  4550. if ( OpenProcessToken(
  4551. hWinlogon,
  4552. WRITE_DAC,
  4553. &SystemToken ) )
  4554. {
  4555. SECURITY_DESCRIPTOR EmptyDacl;
  4556. RtlZeroMemory(
  4557. &EmptyDacl,
  4558. sizeof(SECURITY_DESCRIPTOR)
  4559. );
  4560. InitializeSecurityDescriptor(
  4561. &EmptyDacl,
  4562. SECURITY_DESCRIPTOR_REVISION
  4563. );
  4564. SetSecurityDescriptorDacl(
  4565. &EmptyDacl,
  4566. FALSE,
  4567. NULL,
  4568. FALSE
  4569. );
  4570. if (!SetKernelObjectSecurity(
  4571. SystemToken,
  4572. DACL_SECURITY_INFORMATION,
  4573. &EmptyDacl))
  4574. {
  4575. printf("Failed to set token dacl: %d\n",GetLastError());
  4576. return(0);
  4577. }
  4578. CloseHandle(SystemToken);
  4579. }
  4580. if ( OpenProcessToken(
  4581. hWinlogon,
  4582. TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE,
  4583. &SystemToken ) )
  4584. {
  4585. ImpersonateLoggedOnUser(SystemToken);
  4586. CloseHandle(SystemToken);
  4587. }
  4588. else
  4589. {
  4590. printf("Failed to get system token: %d\n",GetLastError());
  4591. return(0);
  4592. }
  4593. CloseHandle(hWinlogon);
  4594. } else if ( _strnicmp( argument, LOGON_PARAM, sizeof(LOGON_PARAM)-1 ) == 0 ) {
  4595. if ( Action != NoAction ) {
  4596. goto Usage;
  4597. }
  4598. Action = TestLogon;
  4599. Iterations = 1;
  4600. if ( _strnicmp( argument, LOGON_PARAM2, sizeof(LOGON_PARAM2)-1 ) == 0 ) {
  4601. sscanf(&argument[sizeof(LOGON_PARAM2)-1], "%x",&Iterations);
  4602. }
  4603. if (argc < i + 2)
  4604. {
  4605. goto Usage;
  4606. }
  4607. UserName = argv[++i];
  4608. Password = argv[++i];
  4609. if (i < argc)
  4610. {
  4611. DomainName = argv[++i];
  4612. }
  4613. else
  4614. {
  4615. DomainName = NULL;
  4616. }
  4617. } else if (( _strnicmp( argument, PACKAGE_PARAM, sizeof(PACKAGE_PARAM) - 1 ) == 0 ) ||
  4618. ( _strnicmp( argument, PACKAGE_PARAM2, sizeof(PACKAGE_PARAM2) - 1 ) == 0 )) {
  4619. if ( Action != NoAction ) {
  4620. goto Usage;
  4621. }
  4622. argument = &argument[sizeof(PACKAGE_PARAM)-1];
  4623. PackageFunction = NetpAllocWStrFromStr( argument );
  4624. Action = TestPackage;
  4625. } else if ( _strnicmp( argument, GETTICKET_PARAM, sizeof(GETTICKET_PARAM) - 1 ) == 0 ) {
  4626. if ( Action != NoAction ) {
  4627. goto Usage;
  4628. }
  4629. argument = &argument[sizeof(GETTICKET_PARAM)-1];
  4630. PackageFunction = NetpAllocWStrFromStr( argument );
  4631. Action = TestGetTicket;
  4632. } else if ( _strnicmp( argument, CHANGE_PASSWORD_PARAM, sizeof(CHANGE_PASSWORD_PARAM) - 1 ) == 0 ) {
  4633. if ( Action != NoAction ) {
  4634. goto Usage;
  4635. }
  4636. argument = &argument[sizeof(CHANGE_PASSWORD_PARAM)-1];
  4637. OldPasswordW = NetpAllocWStrFromStr( argument );
  4638. Action = ChangePassword;
  4639. } else if ( _strnicmp( argument, SET_PASSWORD_PARAM, sizeof(SET_PASSWORD_PARAM) - 1 ) == 0 ) {
  4640. if ( Action != NoAction ) {
  4641. goto Usage;
  4642. }
  4643. Action = SetPassword;
  4644. } else if ( _strnicmp( argument, CHANGE_CACHED_PASSWORD_PARAM, sizeof(CHANGE_CACHED_PASSWORD_PARAM) - 1 ) == 0 ) {
  4645. if ( Action != NoAction ) {
  4646. goto Usage;
  4647. }
  4648. Action = ChangeCachedPassword;
  4649. } else if (_stricmp( argument, S4ULOGON_PARAM ) == 0 ) {
  4650. if ( Action != NoAction ) {
  4651. goto Usage;
  4652. }
  4653. Action = TestS4ULogon;
  4654. Iterations = 1;
  4655. UserName = argv[++i];
  4656. if (i < argc)
  4657. {
  4658. DomainName = argv[++i];
  4659. }
  4660. else
  4661. {
  4662. DomainName = NULL;
  4663. }
  4664. } else if (_strnicmp( argument, ISC_PARAM,sizeof(ISC_PARAM)-1 ) == 0 )
  4665. {
  4666. if ( Action != NoAction ) {
  4667. goto Usage;
  4668. }
  4669. Action = QuickISCTest;
  4670. argument = &argument[sizeof(ISC_PARAM)-1];
  4671. TargetName = NetpAllocWStrFromStr( argument );
  4672. }
  4673. else if (_strnicmp( argument, CONVERT_PARAM,sizeof(CONVERT_PARAM)-1 ) == 0 )
  4674. {
  4675. if ( Action != NoAction ) {
  4676. goto Usage;
  4677. }
  4678. sscanf(&argument[sizeof(FLAG_PARAM)-1], "%x",&ContextReq);
  4679. printf("%x", ContextReq);
  4680. Action = Convert;
  4681. }
  4682. else {
  4683. printf("Invalid parameter : %s\n",argument);
  4684. goto Usage;
  4685. }
  4686. }
  4687. //
  4688. // Perform the action requested
  4689. //
  4690. switch ( Action ) {
  4691. case TestSsp:
  4692. for ( j=0; j<Iterations ; j++ ) {
  4693. TestSspRoutine(
  4694. PackageName,
  4695. UserNameW,
  4696. DomainNameW,
  4697. PasswordW,
  4698. ServerUserName,
  4699. ServerDomainName,
  4700. ServerPassword,
  4701. TargetName,
  4702. PackageList,
  4703. ContextReq,
  4704. CredFlags
  4705. );
  4706. }
  4707. break;
  4708. case TestPackage:
  4709. TestCallPackageRoutine(PackageFunction);
  4710. break;
  4711. case TestLogon :
  4712. TestLogonRoutine(
  4713. Iterations,
  4714. Relogon,
  4715. LogonType,
  4716. Package,
  4717. UserName,
  4718. DomainName,
  4719. Password
  4720. );
  4721. break;
  4722. case TestS4ULogon :
  4723. TestS4ULogonRoutine(
  4724. UserName,
  4725. DomainName
  4726. );
  4727. break;
  4728. case ChangePassword :
  4729. TestChangePasswordRoutine(
  4730. UserNameW,
  4731. DomainNameW,
  4732. OldPasswordW,
  4733. PasswordW
  4734. );
  4735. break;
  4736. case ChangeCachedPassword :
  4737. TestChangeCachedPassword(
  4738. UserNameW,
  4739. DomainNameW,
  4740. PasswordW
  4741. );
  4742. break;
  4743. case SetPassword :
  4744. TestSetPasswordRoutine(
  4745. UserNameW,
  4746. DomainNameW,
  4747. PasswordW
  4748. );
  4749. break;
  4750. case TestGetTicket :
  4751. TestGetTicketRoutine(
  4752. PackageFunction,
  4753. UserNameW,
  4754. DomainNameW,
  4755. PasswordW,
  4756. ContextReq
  4757. );
  4758. break;
  4759. case QuickISCTest:
  4760. TestQuickISC(
  4761. TargetName
  4762. );
  4763. break;
  4764. case Convert:
  4765. printf("%x", (ContextReq >> 26));
  4766. }
  4767. return 0;
  4768. Usage:
  4769. printf("%s /logon username password [domainname]\n",argv[0]);
  4770. printf("%s /testssp [/package:pacakgename] [/target:targetname]\n", argv[0]);
  4771. printf("\t[/user:username] [/domain:user domain] [/password: client password]\n", argv[0]);
  4772. printf("\t[/serveruser:username] [/serverdomain:server domain] \n");
  4773. printf("\t[/serverpassword:server password] [/dumptoken] [/system]\n");
  4774. printf("%s /s4u: clientname [domain] [/dumptoken] [/system]\n", argv[0]);
  4775. printf("%s /callpackage:[purge:SPN | retrieve:SPN | binding:dc@domain] \n", argv[0]);
  4776. printf("\t[/system]\n");
  4777. printf("%s /ticket:SPN\n", argv[0]);
  4778. return 0;
  4779. }