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.

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