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.

579 lines
13 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ctlklsa.c
  5. Abstract:
  6. Local Security Authority Subsystem - Short CT for Lsa LookupAccountName/Sid
  7. This is a small test that simply calls the LsaLookupName/Sid API once.
  8. Usage:
  9. ctlklsa \\ServerName [-p] -a AccountName ... AccountName
  10. -p - pause before name and sid lookup operation
  11. -a - start of list of account names
  12. Building Instructions:
  13. nmake UMTEST=ctlklsa UMTYPE=console
  14. Author:
  15. Environment:
  16. Revision History:
  17. --*/
  18. #include "lsaclip.h"
  19. VOID
  20. DumpSID(
  21. IN PSID s
  22. );
  23. VOID
  24. CtPause(
  25. );
  26. #define LSA_WIN_STANDARD_BUFFER_SIZE 0x000000200L
  27. VOID __cdecl
  28. main(argc, argv)
  29. int argc;
  30. char **argv;
  31. {
  32. NTSTATUS
  33. Status = STATUS_SUCCESS,
  34. SidStatus;
  35. ULONG
  36. Index,
  37. ArgCount = (ULONG) argc,
  38. DomainIndex,
  39. NameIndex,
  40. NameCount,
  41. DomainSidLength;
  42. ANSI_STRING
  43. NamesAnsi[ LSA_WIN_STANDARD_BUFFER_SIZE],
  44. SystemNameAnsi;
  45. UNICODE_STRING
  46. Names[ LSA_WIN_STANDARD_BUFFER_SIZE],
  47. SystemName;
  48. PUNICODE_STRING
  49. DomainName;
  50. PSID
  51. Sid = NULL,
  52. *Sids = NULL;
  53. SECURITY_QUALITY_OF_SERVICE
  54. SecurityQualityOfService;
  55. OBJECT_ATTRIBUTES
  56. ObjectAttributes;
  57. LSA_HANDLE
  58. PolicyHandle;
  59. PLSA_REFERENCED_DOMAIN_LIST
  60. ReferencedDomains = NULL,
  61. ReferencedSidsDomains = NULL;
  62. PLSA_TRANSLATED_SID
  63. TranslatedSids = NULL;
  64. PLSA_TRANSLATED_NAME
  65. TranslatedNames = NULL;
  66. UCHAR
  67. SubAuthorityCount;
  68. BOOLEAN
  69. Pause = FALSE,
  70. DoLookupSids = TRUE;
  71. if (argc < 4) {
  72. printf("usage: ctlkacct <ServerName> [-p] -a <AccountName> [<AccountName> ...]\n\n");
  73. printf(" -p - pause before name and sid lookup operations\n");
  74. printf(" -a - start of list of account names\n\n");
  75. printf("example:\n");
  76. printf(" ctlklsa \\\\jimk -p -a interactive \"domain guests\" administrators\n\n");
  77. return;
  78. }
  79. NameIndex = 0;
  80. //
  81. // Capture argument 1, the Server Name
  82. //
  83. RtlInitString( &SystemNameAnsi, (PUCHAR) argv[1] );
  84. Status = RtlAnsiStringToUnicodeString(
  85. &SystemName,
  86. &SystemNameAnsi,
  87. TRUE
  88. );
  89. if (!NT_SUCCESS(Status)) {
  90. goto MainError;
  91. }
  92. for (Index = 2; Index < ArgCount; Index++) {
  93. if (strncmp(argv[Index], "-p", 2) == 0) {
  94. //
  95. // The caller wants a pause before each lookup call.
  96. //
  97. Pause = TRUE;
  98. } else if (strncmp(argv[Index], "-a", 2) == 0) {
  99. Index++;
  100. while (Index < ArgCount) {
  101. if (strncmp(argv[Index], "-", 1) == 0) {
  102. Index--;
  103. break;
  104. }
  105. //
  106. // Capture the Account Name as a Unicode String.
  107. //
  108. RtlInitString( &NamesAnsi[ NameIndex ], argv[Index] );
  109. Status = RtlAnsiStringToUnicodeString(
  110. &Names[ NameIndex ],
  111. &NamesAnsi[ NameIndex ],
  112. TRUE
  113. );
  114. if (!NT_SUCCESS(Status)) {
  115. break;
  116. }
  117. NameIndex++;
  118. Index++;
  119. }
  120. if (Index == ArgCount) {
  121. break;
  122. }
  123. }
  124. }
  125. if (!NT_SUCCESS(Status)) {
  126. goto MainError;
  127. }
  128. NameCount = NameIndex;
  129. SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  130. SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
  131. SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  132. SecurityQualityOfService.EffectiveOnly = FALSE;
  133. //
  134. // Set up the object attributes prior to opening the LSA.
  135. //
  136. InitializeObjectAttributes(
  137. &ObjectAttributes,
  138. NULL,
  139. 0L,
  140. NULL,
  141. NULL
  142. );
  143. //
  144. // The InitializeObjectAttributes macro presently stores NULL for
  145. // the SecurityQualityOfService field, so we must manually copy that
  146. // structure for now.
  147. //
  148. ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
  149. //
  150. // Open the LSA Policy Database for the target system. This is the
  151. // starting point for the Name Lookup operation.
  152. //
  153. Status = LsaOpenPolicy(
  154. &SystemName,
  155. &ObjectAttributes,
  156. POLICY_LOOKUP_NAMES,
  157. &PolicyHandle
  158. );
  159. if (!NT_SUCCESS(Status)) {
  160. goto MainError;
  161. }
  162. if (Pause) {
  163. printf( "\n\n..... Pausing before name lookup \n ");
  164. CtPause( );
  165. }
  166. //
  167. // Attempt to translate the Names to Sids.
  168. //
  169. Status = LsaLookupNames(
  170. PolicyHandle,
  171. NameCount,
  172. Names,
  173. &ReferencedDomains,
  174. &TranslatedSids
  175. );
  176. if (!NT_SUCCESS(Status)) {
  177. goto MainError;
  178. }
  179. //
  180. // Build the Sids from the output.
  181. //
  182. Sids = (PSID *) LocalAlloc( 0, NameCount * sizeof (PSID) );
  183. if (Sids == NULL) {
  184. Status = STATUS_INSUFFICIENT_RESOURCES;
  185. goto MainError;
  186. }
  187. for (NameIndex = 0; NameIndex < NameCount; NameIndex++) {
  188. if (TranslatedSids[NameIndex].Use == SidTypeUnknown) {
  189. Sids[NameIndex] = NULL;
  190. DoLookupSids = FALSE;
  191. } else {
  192. DomainIndex = TranslatedSids[NameIndex].DomainIndex;
  193. DomainSidLength = RtlLengthSid(
  194. ReferencedDomains->Domains[DomainIndex].Sid
  195. );
  196. Sid = (PSID) LocalAlloc( (UINT) 0, (UINT) (DomainSidLength + sizeof(ULONG)) );
  197. if (Sid == NULL) {
  198. printf(" ** ERROR - couldn't allocate heap !!\n");
  199. return;
  200. }
  201. RtlMoveMemory(
  202. Sid,
  203. ReferencedDomains->Domains[DomainIndex].Sid,
  204. DomainSidLength
  205. );
  206. if (TranslatedSids[NameIndex].Use != SidTypeDomain) {
  207. (*RtlSubAuthorityCountSid( Sid ))++;
  208. SubAuthorityCount = *RtlSubAuthorityCountSid( Sid );
  209. *RtlSubAuthoritySid(Sid,SubAuthorityCount - (UCHAR) 1) =
  210. TranslatedSids[NameIndex].RelativeId;
  211. }
  212. Sids[NameIndex] = Sid;
  213. }
  214. }
  215. //
  216. // Pause before SID lookup...
  217. //
  218. if (!DoLookupSids) {
  219. printf("\n\n Unknown Name causing sid lookup to be skipped\n");
  220. } else {
  221. if (Pause) {
  222. printf( "\n\n..... Pausing before SID lookup \n ");
  223. CtPause();
  224. }
  225. //
  226. // Now translate the Sids back to Names
  227. //
  228. SidStatus = LsaLookupSids(
  229. PolicyHandle,
  230. NameCount,
  231. (PSID *) Sids,
  232. &ReferencedSidsDomains,
  233. &TranslatedNames
  234. );
  235. }
  236. /*
  237. * Print information returned by LookupAccountName
  238. */
  239. printf(
  240. "*********************************************\n"
  241. "Information returned by LookupAccountName\n"
  242. "*********************************************\n\n"
  243. );
  244. for (NameIndex = 0; NameIndex < NameCount; NameIndex++) {
  245. printf(" Name looked up: *%wZ*\n", &Names[NameIndex]);
  246. printf(" Use = ");
  247. switch (TranslatedSids[NameIndex].Use) {
  248. case SidTypeUser:
  249. printf("SidTypeUser\n");
  250. break;
  251. case SidTypeGroup:
  252. printf("SidTypeGroup\n");
  253. break;
  254. case SidTypeDomain:
  255. printf("SidTypeDomain\n");
  256. break;
  257. case SidTypeAlias:
  258. printf("SidTypeAlias\n");
  259. break;
  260. case SidTypeWellKnownGroup:
  261. printf("SidTypeWellKnownGroup\n");
  262. break;
  263. case SidTypeDeletedAccount:
  264. printf("SidTypeDeletedAccount\n");
  265. break;
  266. case SidTypeInvalid:
  267. printf("SidTypeInvalid\n");
  268. break;
  269. case SidTypeUnknown:
  270. printf("SidTypeUnknown\n\n");
  271. break;
  272. default:
  273. printf("Hmmm - something unusual came back !!!! \n\n");
  274. break;
  275. }
  276. if (TranslatedSids[NameIndex].Use != SidTypeUnknown) {
  277. printf(" Sid = " );
  278. DumpSID((PSID) Sids[NameIndex]);
  279. DomainIndex = TranslatedSids[NameIndex].DomainIndex;
  280. DomainName = &ReferencedDomains->Domains[ DomainIndex ].Name;
  281. printf(" Referenced Domain Name = *%wZ*\n\n", DomainName );
  282. }
  283. }
  284. if (DoLookupSids) {
  285. printf(
  286. "*********************************************\n"
  287. "Information returned by LookupAccountSid\n"
  288. "*********************************************\n\n"
  289. );
  290. if (!NT_SUCCESS(SidStatus)) {
  291. printf(" Sid lookup failed. Status 0x%lx\n"
  292. " Dumping sids that were being looked up...\n",
  293. SidStatus);
  294. }
  295. for (NameIndex = 0; NameIndex < NameCount; NameIndex++) {
  296. printf(" Sid = " );
  297. DumpSID((PSID) Sids[NameIndex]);
  298. if (NT_SUCCESS(SidStatus)) {
  299. printf(" Sid Use = ");
  300. switch (TranslatedNames[NameIndex].Use) {
  301. case SidTypeUser:
  302. printf("SidTypeUser\n");
  303. break;
  304. case SidTypeGroup:
  305. printf("SidTypeGroup\n");
  306. break;
  307. case SidTypeDomain:
  308. printf("SidTypeDomain\n");
  309. break;
  310. case SidTypeAlias:
  311. printf("SidTypeAlias\n");
  312. break;
  313. case SidTypeWellKnownGroup:
  314. printf("SidTypeWellKnownGroup\n");
  315. break;
  316. case SidTypeDeletedAccount:
  317. printf("SidTypeDeletedAccount\n");
  318. break;
  319. case SidTypeInvalid:
  320. printf("SidTypeInvalid\n");
  321. break;
  322. case SidTypeUnknown:
  323. printf("SidTypeUnknown\n");
  324. break;
  325. default:
  326. printf("Hmmm - unexpected value !!!\n");
  327. break;
  328. }
  329. DomainIndex = TranslatedNames[NameIndex].DomainIndex;
  330. DomainName = &ReferencedSidsDomains->Domains[ DomainIndex ].Name;
  331. if (TranslatedNames[NameIndex].Use == SidTypeDomain) {
  332. printf(
  333. " Domain Name = *%wZ*\n\n",
  334. DomainName
  335. );
  336. } else {
  337. printf(
  338. " Account Name = *%wZ*\n"
  339. " Referenced Domain Name = *%wZ*\n\n",
  340. &TranslatedNames[NameIndex].Name,
  341. DomainName
  342. );
  343. }
  344. }
  345. }
  346. }
  347. MainFinish:
  348. return;
  349. MainError:
  350. printf("Error: status = 0x%lx\n", Status);
  351. goto MainFinish;
  352. }
  353. VOID
  354. DumpSID(
  355. IN PSID s
  356. )
  357. {
  358. SID_IDENTIFIER_AUTHORITY
  359. *a;
  360. ULONG
  361. id = 0,
  362. i;
  363. BOOLEAN
  364. PrintValue = FALSE;
  365. try {
  366. a = GetSidIdentifierAuthority(s);
  367. printf("s-1-");
  368. for (i=0; i<5; i++) {
  369. if ((a->Value[i] != 0) || PrintValue) {
  370. printf("%02x", a->Value[i]);
  371. PrintValue = TRUE;
  372. }
  373. }
  374. printf("%02x", a->Value[5]);
  375. for (i = 0; i < (ULONG) *GetSidSubAuthorityCount(s); i++) {
  376. printf("-0x%lx", *GetSidSubAuthority(s, i));
  377. }
  378. } except (EXCEPTION_EXECUTE_HANDLER) {
  379. printf("<invalid pointer (0x%lx)>\n", s);
  380. }
  381. printf("\n");
  382. }
  383. VOID
  384. CtPause(
  385. )
  386. {
  387. CHAR
  388. IgnoreInput[300];
  389. printf("Press <ENTER> to continue . . .");
  390. gets( &IgnoreInput[0] );
  391. return;
  392. }