Source code of Windows XP (NT5)
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.

618 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: logon2.c
  7. //
  8. // Contents: Logon test app
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 6-20-94 richardw Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <malloc.h>
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <ntlsa.h>
  24. #include <windows.h>
  25. #define DUMP_TOKEN 1
  26. #define DUMP_HEX 2
  27. char *User = NULL;
  28. char *Domain = NULL;
  29. char *Password = NULL;
  30. char *SecPackage = NULL;
  31. char *Cmd = NULL;
  32. DWORD fLogon = 0;
  33. DWORD fMe = 0;
  34. DWORD fService = 0;
  35. DWORD fCookie = 0;
  36. FILE * fOut;
  37. DWORD Threads;
  38. DWORD fDup = 0;
  39. DWORD LogonType = LOGON32_LOGON_INTERACTIVE;
  40. char * ImpLevels[] = { "Anonymous", "Identity", "Impersonation", "Delegation"};
  41. char * LogonTypes[] = { "Invalid", "Invalid", "Interactive", "Network", "Batch", "Service", "Proxy" };
  42. void DumpToken(HANDLE hToken);
  43. void
  44. DoArgs(int argc,
  45. char **argv)
  46. {
  47. int i;
  48. Threads = 1;
  49. if (argc < 3)
  50. {
  51. fprintf( fOut,"usage: %s <name> <domain> [-p pw] [-f flags] [-s] [-d] [-x cmd]\n", argv[0]);
  52. fprintf( fOut,"Tests logon path\n");
  53. fprintf( fOut," -p \tOverride password\n");
  54. fprintf( fOut," -D \tDump token\n");
  55. fprintf( fOut," -d \tduplicate\n");
  56. fprintf( fOut," -s \tLogon as service\n");
  57. fprintf( fOut," -x cmd \tStart cmd as user\n");
  58. fprintf( fOut," -o file\tSend output to file\n");
  59. fprintf( fOut," -t # \tHit with # threads at once\n");
  60. fprintf( fOut," -l type\tLogon type\n");
  61. exit(1);
  62. }
  63. for (i = 1; i < argc ; i++ )
  64. {
  65. if (*argv[i] == '-')
  66. {
  67. switch (*(argv[i]+1))
  68. {
  69. case 'f':
  70. fLogon = atoi(argv[++i]);
  71. break;
  72. case 'd':
  73. fDup = 1;
  74. break;
  75. case 'D':
  76. fMe |= DUMP_TOKEN;
  77. break;
  78. case 'x':
  79. Cmd = argv[++i];
  80. break;
  81. case 'p':
  82. Password = argv[++i];
  83. break;
  84. case 't':
  85. Threads = atoi(argv[++i]);
  86. break;
  87. case 's':
  88. LogonType = LOGON32_LOGON_SERVICE;
  89. break;
  90. case 'l':
  91. ++i;
  92. if (argv[i] == NULL )
  93. {
  94. fprintf(fOut, "No logon type specified\n");
  95. exit(1);
  96. }
  97. for (LogonType = 2 ;
  98. LogonType < sizeof(LogonTypes) / sizeof(PSTR) ;
  99. LogonType ++ )
  100. {
  101. if (_stricmp( LogonTypes[LogonType], argv[i]) == 0 )
  102. {
  103. break;
  104. }
  105. }
  106. if (LogonType == (sizeof(LogonTypes) / sizeof(PSTR) ))
  107. {
  108. fprintf(fOut, "Invalid logon type '%s'\n", argv[i]);
  109. exit(1);
  110. }
  111. break;
  112. case 'o':
  113. fOut = fopen(argv[++i], "w");
  114. if (!fOut)
  115. {
  116. fOut = stderr;
  117. }
  118. break;
  119. default:
  120. fprintf( fOut,"Invalid switch %s\n", argv[i]);
  121. exit(1);
  122. }
  123. }
  124. else
  125. {
  126. if (!User)
  127. User = argv[i];
  128. else
  129. if (!Domain)
  130. Domain = argv[i];
  131. }
  132. }
  133. if (!Password)
  134. Password = User;
  135. }
  136. DWORD
  137. DoIt(
  138. PVOID pv)
  139. {
  140. NTSTATUS scRet, SubStatus, Status;
  141. PISID pSid;
  142. LUID Luid;
  143. TOKEN_GROUPS TokenGroups;
  144. STRING sMe;
  145. HANDLE hToken;
  146. HANDLE hImp;
  147. HANDLE hDup;
  148. STRING sPackage;
  149. ULONG Package;
  150. LUID LogonId;
  151. TOKEN_SOURCE TokenSource;
  152. char ImpersonateName[MAX_PATH];
  153. DWORD cbImpersonateName = MAX_PATH;
  154. STARTUPINFO si;
  155. PROCESS_INFORMATION pi;
  156. POBJECT_TYPE_INFORMATION pTypeInfo;
  157. POBJECT_NAME_INFORMATION pNameInfo;
  158. POBJECT_BASIC_INFORMATION pBasicInfo;
  159. UCHAR Buffer[1024];
  160. HANDLE hWait;
  161. hWait = (HANDLE) pv;
  162. if (hWait != NULL)
  163. {
  164. WaitForSingleObjectEx( hWait, INFINITE, FALSE );
  165. }
  166. fprintf( fOut,"Logging on %s to %s\n", User, Domain);
  167. //
  168. // Copy the strings into the right places:
  169. //
  170. if (!LogonUserA(User, Domain, Password,
  171. LogonType,
  172. LOGON32_PROVIDER_DEFAULT, &hToken))
  173. {
  174. fprintf( fOut,"FAILED to logon, GetLastError is %d\n", GetLastError());
  175. }
  176. else
  177. {
  178. if (fMe & DUMP_TOKEN)
  179. DumpToken(hToken);
  180. if (!ImpersonateLoggedOnUser(hToken))
  181. {
  182. fprintf( fOut, "FAILED to impersonate, GetLastError is %d\n", GetLastError());
  183. }
  184. GetUserName(ImpersonateName, &cbImpersonateName);
  185. if (fDup)
  186. {
  187. if (OpenThreadToken( GetCurrentThread(),
  188. MAXIMUM_ALLOWED,
  189. TRUE,
  190. &hImp))
  191. {
  192. DumpToken( hImp );
  193. if (DuplicateTokenEx( hImp,
  194. MAXIMUM_ALLOWED,
  195. NULL,
  196. SecurityImpersonation,
  197. TokenPrimary,
  198. &hDup ) )
  199. {
  200. fprintf( fOut, "Success! Duplicated that token!\n");
  201. DumpToken( hToken );
  202. CloseHandle( hToken );
  203. }
  204. else
  205. {
  206. fprintf( fOut, "DuplicateTokenEx FAILED, %d\n", GetLastError() );
  207. }
  208. CloseHandle( hImp );
  209. }
  210. else
  211. {
  212. fprintf( fOut, "OpenThreadToken FAILED, %d\n", GetLastError() );
  213. }
  214. }
  215. RevertToSelf();
  216. fprintf( fOut,"Hey look! I'm %s\n", ImpersonateName);
  217. if (Cmd)
  218. {
  219. fprintf( fOut,"Starting '%s' as user\n", Cmd);
  220. ZeroMemory(&si, sizeof(si));
  221. si.cb = sizeof(si);
  222. if (!CreateProcessAsUser(hToken, NULL, Cmd, NULL, NULL, FALSE,
  223. CREATE_SEPARATE_WOW_VDM, NULL,
  224. NULL, &si, &pi))
  225. {
  226. fprintf( fOut,"FAILED, %d\n", GetLastError());
  227. }
  228. fprintf( fOut,"Process Info:\n");
  229. fprintf( fOut," Process Handle \t%x\n", pi.hProcess );
  230. fprintf( fOut," Thread Handle \t%x\n", pi.hThread );
  231. fprintf( fOut," Process Id \t%d\n", pi.dwProcessId );
  232. fprintf( fOut," Thread Id \t%d\n", pi.dwThreadId );
  233. ZeroMemory( Buffer, 1024 );
  234. pTypeInfo = (POBJECT_TYPE_INFORMATION) Buffer;
  235. pNameInfo = (POBJECT_NAME_INFORMATION) Buffer;
  236. pBasicInfo = (POBJECT_BASIC_INFORMATION) Buffer;
  237. Status = NtQueryObject( pi.hProcess, ObjectTypeInformation, pTypeInfo, 1024, NULL );
  238. if (NT_SUCCESS(Status))
  239. {
  240. fprintf( fOut," Type \t%ws\n", pTypeInfo->TypeName.Buffer );
  241. }
  242. ZeroMemory( Buffer, 1024 );
  243. Status = NtQueryObject(pi.hProcess, ObjectBasicInformation, pBasicInfo, 1024, NULL);
  244. if (NT_SUCCESS(Status))
  245. {
  246. fprintf( fOut," Attributes \t%#x\n", pBasicInfo->Attributes );
  247. fprintf( fOut," GrantedAccess\t%#x\n", pBasicInfo->GrantedAccess );
  248. fprintf( fOut," HandleCount \t%d\n", pBasicInfo->HandleCount );
  249. fprintf( fOut," PointerCount \t%d\n", pBasicInfo->PointerCount );
  250. }
  251. else
  252. {
  253. fprintf( fOut,"FAILED %x to query basic info\n", Status );
  254. }
  255. ZeroMemory( Buffer, 1024 );
  256. Status = NtQueryObject( pi.hProcess, ObjectNameInformation, pNameInfo, 1024, NULL );
  257. if (NT_SUCCESS(Status))
  258. {
  259. fprintf( fOut," Name \t%ws\n", pNameInfo->Name.Buffer);
  260. }
  261. else
  262. {
  263. fprintf( fOut,"FAILED %x to query name info\n", Status );
  264. }
  265. CloseHandle( pi.hProcess );
  266. CloseHandle( pi.hThread );
  267. }
  268. CloseHandle(hToken);
  269. }
  270. return(0);
  271. }
  272. __cdecl
  273. main (int argc, char *argv[])
  274. {
  275. HANDLE hWait;
  276. DWORD i;
  277. DWORD tid;
  278. HANDLE hThreads[64];
  279. fOut = stdout;
  280. //
  281. // Get params
  282. //
  283. DoArgs(argc, argv);
  284. if (Threads == 1)
  285. {
  286. DoIt(NULL);
  287. }
  288. else
  289. {
  290. if (Threads > 64 )
  291. {
  292. Threads = 64;
  293. }
  294. hWait = CreateEvent( NULL, TRUE, FALSE, NULL );
  295. for (i = 0; i < Threads ; i++ )
  296. {
  297. hThreads[i] = CreateThread( NULL, 0, DoIt, hWait, 0, &tid);
  298. }
  299. SetEvent( hWait );
  300. WaitForMultipleObjectsEx( Threads, hThreads, TRUE, INFINITE, FALSE );
  301. for ( i = 0 ; i < Threads ; i++ )
  302. {
  303. CloseHandle( hThreads[i] );
  304. }
  305. }
  306. return( 0 );
  307. }
  308. #define SATYPE_USER 1
  309. #define SATYPE_GROUP 2
  310. #define SATYPE_PRIV 3
  311. ULONG PID;
  312. void
  313. DumpSid(PSID pxSid)
  314. {
  315. PISID pSid = pxSid;
  316. int i, j =0;
  317. fprintf( fOut," S-%d-", pSid->Revision);
  318. for (i = 0;i < 6 ; i++ )
  319. {
  320. if (j)
  321. {
  322. fprintf( fOut,"%x", pSid->IdentifierAuthority.Value[i]);
  323. }
  324. else
  325. {
  326. if (pSid->IdentifierAuthority.Value[i])
  327. {
  328. j = 1;
  329. fprintf( fOut,"%x", pSid->IdentifierAuthority.Value[i]);
  330. }
  331. }
  332. if (i==4)
  333. {
  334. j = 1;
  335. }
  336. }
  337. for (i = 0; i < pSid->SubAuthorityCount ; i++ )
  338. {
  339. fprintf( fOut,(fMe & DUMP_HEX ? "-%x" : "-%lu"), pSid->SubAuthority[i]);
  340. }
  341. }
  342. void
  343. DumpSidAttr(PSID_AND_ATTRIBUTES pSA,
  344. int SAType)
  345. {
  346. DumpSid(pSA->Sid);
  347. if (SAType == SATYPE_GROUP)
  348. {
  349. fprintf( fOut,"\tAttributes - ");
  350. if (pSA->Attributes & SE_GROUP_MANDATORY)
  351. {
  352. fprintf( fOut,"Mandatory ");
  353. }
  354. if (pSA->Attributes & SE_GROUP_ENABLED_BY_DEFAULT)
  355. {
  356. fprintf( fOut,"Default ");
  357. }
  358. if (pSA->Attributes & SE_GROUP_ENABLED)
  359. {
  360. fprintf( fOut,"Enabled ");
  361. }
  362. if (pSA->Attributes & SE_GROUP_OWNER)
  363. {
  364. fprintf( fOut,"Owner ");
  365. }
  366. if (pSA->Attributes & SE_GROUP_LOGON_ID)
  367. {
  368. fprintf( fOut,"LogonId ");
  369. }
  370. }
  371. }
  372. CHAR * GetPrivName(PLUID pPriv)
  373. {
  374. switch (pPriv->LowPart)
  375. {
  376. case SE_CREATE_TOKEN_PRIVILEGE:
  377. return(SE_CREATE_TOKEN_NAME);
  378. case SE_ASSIGNPRIMARYTOKEN_PRIVILEGE:
  379. return(SE_ASSIGNPRIMARYTOKEN_NAME);
  380. case SE_LOCK_MEMORY_PRIVILEGE:
  381. return(SE_LOCK_MEMORY_NAME);
  382. case SE_INCREASE_QUOTA_PRIVILEGE:
  383. return(SE_INCREASE_QUOTA_NAME);
  384. case SE_UNSOLICITED_INPUT_PRIVILEGE:
  385. return(SE_UNSOLICITED_INPUT_NAME);
  386. case SE_TCB_PRIVILEGE:
  387. return(SE_TCB_NAME);
  388. case SE_SECURITY_PRIVILEGE:
  389. return(SE_SECURITY_NAME);
  390. case SE_TAKE_OWNERSHIP_PRIVILEGE:
  391. return(SE_TAKE_OWNERSHIP_NAME);
  392. case SE_LOAD_DRIVER_PRIVILEGE:
  393. return(SE_LOAD_DRIVER_NAME);
  394. case SE_SYSTEM_PROFILE_PRIVILEGE:
  395. return(SE_SYSTEM_PROFILE_NAME);
  396. case SE_SYSTEMTIME_PRIVILEGE:
  397. return(SE_SYSTEMTIME_NAME);
  398. case SE_PROF_SINGLE_PROCESS_PRIVILEGE:
  399. return(SE_PROF_SINGLE_PROCESS_NAME);
  400. case SE_INC_BASE_PRIORITY_PRIVILEGE:
  401. return(SE_INC_BASE_PRIORITY_NAME);
  402. case SE_CREATE_PAGEFILE_PRIVILEGE:
  403. return(SE_CREATE_PAGEFILE_NAME);
  404. case SE_CREATE_PERMANENT_PRIVILEGE:
  405. return(SE_CREATE_PERMANENT_NAME);
  406. case SE_BACKUP_PRIVILEGE:
  407. return(SE_BACKUP_NAME);
  408. case SE_RESTORE_PRIVILEGE:
  409. return(SE_RESTORE_NAME);
  410. case SE_SHUTDOWN_PRIVILEGE:
  411. return(SE_SHUTDOWN_NAME);
  412. case SE_DEBUG_PRIVILEGE:
  413. return(SE_DEBUG_NAME);
  414. case SE_AUDIT_PRIVILEGE:
  415. return(SE_AUDIT_NAME);
  416. case SE_SYSTEM_ENVIRONMENT_PRIVILEGE:
  417. return(SE_SYSTEM_ENVIRONMENT_NAME);
  418. case SE_CHANGE_NOTIFY_PRIVILEGE:
  419. return(SE_CHANGE_NOTIFY_NAME);
  420. case SE_REMOTE_SHUTDOWN_PRIVILEGE:
  421. return(SE_REMOTE_SHUTDOWN_NAME);
  422. default:
  423. return("Unknown Privilege");
  424. }
  425. }
  426. void
  427. DumpLuidAttr(PLUID_AND_ATTRIBUTES pLA,
  428. int LAType)
  429. {
  430. char * PrivName;
  431. fprintf( fOut,"0x%x%08x", pLA->Luid.HighPart, pLA->Luid.LowPart);
  432. fprintf( fOut," %-32s", GetPrivName(&pLA->Luid));
  433. if (LAType == SATYPE_PRIV)
  434. {
  435. fprintf( fOut," Attributes - ");
  436. if (pLA->Attributes & SE_PRIVILEGE_ENABLED)
  437. {
  438. fprintf( fOut,"Enabled ");
  439. }
  440. if (pLA->Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT)
  441. {
  442. fprintf( fOut,"Default ");
  443. }
  444. }
  445. }
  446. void
  447. DumpToken(HANDLE hToken)
  448. {
  449. PTOKEN_USER pTUser;
  450. PTOKEN_GROUPS pTGroups;
  451. PTOKEN_PRIVILEGES pTPrivs;
  452. PTOKEN_OWNER pTOwner;
  453. PTOKEN_PRIMARY_GROUP pTPrimaryGroup;
  454. TOKEN_STATISTICS TStats;
  455. ULONG cbInfo;
  456. ULONG cbRetInfo;
  457. NTSTATUS status;
  458. DWORD i;
  459. pTUser = malloc(256);
  460. status = GetTokenInformation( hToken,
  461. TokenUser,
  462. pTUser,
  463. 256,
  464. &cbRetInfo);
  465. if (!NT_SUCCESS(status))
  466. {
  467. fprintf( fOut,"FAILED querying token, %#x\n", status);
  468. return;
  469. }
  470. fprintf( fOut,"User\n ");
  471. DumpSidAttr(&pTUser->User, SATYPE_USER);
  472. fprintf( fOut,"\nGroups");
  473. pTGroups = malloc(4096);
  474. status = GetTokenInformation( hToken,
  475. TokenGroups,
  476. pTGroups,
  477. 4096,
  478. &cbRetInfo);
  479. for (i = 0; i < pTGroups->GroupCount ; i++ )
  480. {
  481. fprintf( fOut,"\n %02d ", i);
  482. DumpSidAttr(&pTGroups->Groups[i], SATYPE_GROUP);
  483. }
  484. pTPrimaryGroup = malloc(128);
  485. status = GetTokenInformation( hToken,
  486. TokenPrimaryGroup,
  487. pTPrimaryGroup,
  488. 128,
  489. &cbRetInfo);
  490. fprintf( fOut,"\nPrimary Group:\n ");
  491. DumpSid(pTPrimaryGroup->PrimaryGroup);
  492. fprintf( fOut,"\nPrivs\n");
  493. pTPrivs = malloc(4096);
  494. status = GetTokenInformation( hToken,
  495. TokenPrivileges,
  496. pTPrivs,
  497. 4096,
  498. &cbRetInfo);
  499. for (i = 0; i < pTPrivs->PrivilegeCount ; i++ )
  500. {
  501. fprintf( fOut,"\n %02d ", i);
  502. DumpLuidAttr(&pTPrivs->Privileges[i], SATYPE_PRIV);
  503. }
  504. status = GetTokenInformation( hToken,
  505. TokenStatistics,
  506. &TStats,
  507. sizeof(TStats),
  508. &cbRetInfo);
  509. fprintf( fOut, "\n\nAuth ID %x:%x\n", TStats.AuthenticationId.HighPart, TStats.AuthenticationId.LowPart);
  510. fprintf( fOut, "TokenId %x:%x\n", TStats.TokenId.HighPart, TStats.TokenId.LowPart);
  511. fprintf( fOut, "TokenType %s\n", TStats.TokenType == TokenPrimary ? "Primary" : "Impersonation");
  512. fprintf( fOut, "Imp Level %s\n", ImpLevels[ TStats.ImpersonationLevel ]);
  513. }