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.

12339 lines
401 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. tmachine.c
  5. Abstract:
  6. This module tests token duplication.
  7. Author:
  8. Jim Kelly (JimK) 8-Feb-1994
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. --*/
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // //
  15. // Includes //
  16. // //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include <stdio.h>
  19. #include <nt.h>
  20. #include <ntsam.h>
  21. #include <ntsamp.h>
  22. #include <ntlsa.h>
  23. #include <ntrpcp.h> // prototypes for MIDL user functions
  24. #include <seopaque.h>
  25. #include <string.h>
  26. #ifdef NOT_PART_OF_PROGRAM
  27. ///////////////////////////////////////////////////////////////////////////////
  28. // //
  29. // Definitions //
  30. // //
  31. ///////////////////////////////////////////////////////////////////////////////
  32. #define TMPP_USER_NAME_ADMIN "Administrator"
  33. #define TMPP_USER_NAME_GUEST "Guest"
  34. #define TMPP_GROUP_NAME_ADMINS "Domain Admins"
  35. #define TMPP_GROUP_NAME_USERS "Domain Users"
  36. #define TMPP_GROUP_NAME_NONE "None"
  37. #define TMPP_ALIAS_NAME_ADMINS "Administrators"
  38. #define TMPP_ALIAS_NAME_SYSTEM_OPS "System Operators"
  39. #define TMPP_ALIAS_NAME_POWER_USERS "Power Users"
  40. #define TMPP_ALIAS_NAME_USERS "Users"
  41. #define TMPP_ALIAS_NAME_GUESTS "Guests"
  42. #define TMPP_ALIAS_NAME_ACCOUNT_OPS "Account Operators"
  43. #define TMPP_ALIAS_NAME_PRINT_OPS "Print Operators"
  44. #define TMPP_ALIAS_NAME_BACKUP_OPS "Backup Operators"
  45. #define GROUP_NAME1 "GROUP1"
  46. #define ALIAS_NAME1 "ALIAS1"
  47. #define ALIAS_NAME2 "ALIAS2"
  48. #define USER_NAME1 "USER1"
  49. #define USER_NAME2 "USER2"
  50. #define USER_NAME3 "USER3"
  51. // Keep these names not longer than 8 char's until long registry names supported
  52. #define DUMMY_NAME1 "DName1"
  53. #define DUMMY_NAME2 "2emaNuD"
  54. #define DUMMY_STRING1 "This is test string 1"
  55. #define DUMMY_STRING2 "Test String2 - test string 2 - tEST sTRING 2"
  56. #define ALL_NAMES_COUNT (3)
  57. #define SOME_NAMES_COUNT (7)
  58. #define NO_NAMES_COUNT (2)
  59. #define LOOKUP_KNOWN_NAME0 TMPP_USER_NAME_ADMIN
  60. #define LOOKUP_KNOWN_NAME1_A TMPP_GROUP_NAME_NONE
  61. #define LOOKUP_KNOWN_NAME2_A TMPP_GROUP_NAME_NONE
  62. #define LOOKUP_KNOWN_NAME1_P TMPP_GROUP_NAME_USERS
  63. #define LOOKUP_KNOWN_NAME2_P TMPP_GROUP_NAME_USERS
  64. #define LOOKUP_KNOWN_NAME0_RID DOMAIN_USER_RID_ADMIN
  65. #define LOOKUP_KNOWN_NAME1_RID DOMAIN_GROUP_RID_USERS
  66. #define LOOKUP_KNOWN_NAME2_RID DOMAIN_GROUP_RID_USERS
  67. #define LOOKUP_UNKNOWN_NAME0 "JoeJoe"
  68. #define LOOKUP_UNKNOWN_NAME1 "Tanya"
  69. #define LOOKUP_UNKNOWN_NAME2 "Fred"
  70. #define LOOKUP_UNKNOWN_NAME3 "Anyone"
  71. #define LOOKUP_KNOWN_NAME0_USE (SidTypeUser)
  72. #define LOOKUP_KNOWN_NAME1_USE (SidTypeGroup)
  73. #define LOOKUP_KNOWN_NAME2_USE (SidTypeGroup)
  74. //
  75. // This byte is expected to be different in the DummyLogonHours and
  76. // NoRestrictionLogonHours.
  77. //
  78. #define LOGON_HOURS_DIFFERENT_OFFSET (5)
  79. ///////////////////////////////////////////////////////////////////////////////
  80. // //
  81. // Global variables //
  82. // //
  83. ///////////////////////////////////////////////////////////////////////////////
  84. LARGE_INTEGER LargeInteger1,
  85. LargeInteger2;
  86. UNICODE_STRING DummyName1,
  87. DummyName2,
  88. DummyString1,
  89. DummyString2;
  90. STRING DummyAnsiString1,
  91. DummyAnsiString2;
  92. LOGON_HOURS NoLogonRestriction,
  93. DummyLogonHours;
  94. CHAR NoLogonRestrictionBitMask[21],
  95. DummyLogonHoursBitMask[21];
  96. UNICODE_STRING AllNames[ALL_NAMES_COUNT],
  97. SomeNames[SOME_NAMES_COUNT],
  98. NoNames[NO_NAMES_COUNT];
  99. SID_NAME_USE AllUses[ALL_NAMES_COUNT],
  100. SomeUses[SOME_NAMES_COUNT],
  101. NoUses[NO_NAMES_COUNT];
  102. ULONG AllRids[ALL_NAMES_COUNT],
  103. SomeRids[SOME_NAMES_COUNT],
  104. NoRids[NO_NAMES_COUNT];
  105. PSID BuiltinDomainSid,
  106. AccountDomainSid,
  107. PrimaryDomainSid,
  108. WorldSid,
  109. AdminsAliasSid,
  110. AccountAliasSid;
  111. UNICODE_STRING BuiltinDomainName,
  112. AccountDomainName,
  113. PrimaryDomainName;
  114. BOOLEAN AccountDomainIsNotPrimaryDomain;
  115. //
  116. // These are NOT mutually exclusive
  117. //
  118. BOOLEAN BuiltinDomainTest, // Test the builting domain
  119. SecurityOperatorTest, // Test auditing accessibility
  120. AccountOpAliasTest, // Test account operator functions
  121. AdminsAliasTest; // Test domain admin functions
  122. ///////////////////////////////////////////////////////////////////////////////
  123. // //
  124. // private macros //
  125. // //
  126. ///////////////////////////////////////////////////////////////////////////////
  127. //
  128. // VOID
  129. // TST_SUCCESS_ASSERT( IN NTSTATUS S );
  130. //
  131. #define TST_SUCCESS_ASSERT( S ) \
  132. { \
  133. if ( !NT_SUCCESS((S)) ) { \
  134. printf("\n** SUCCESS STATUS ASSERTION FAILURE **\n"); \
  135. printf(" Status is: 0x%lx\n", (S) ); \
  136. ASSERT(NT_SUCCESS((S))); \
  137. } \
  138. }
  139. ///////////////////////////////////////////////////////////////////////////////
  140. // //
  141. // private service prototypes //
  142. // //
  143. ///////////////////////////////////////////////////////////////////////////////
  144. BOOLEAN
  145. TInitialize( VOID );
  146. BOOLEAN
  147. EnableSecurityPrivilege( VOID );
  148. VOID
  149. DetermineTestsToRun( VOID );
  150. VOID
  151. SeeIfSidIsSpecial(
  152. IN PSID Sid
  153. );
  154. BOOLEAN
  155. ServerTestSuite(
  156. PHANDLE ServerHandle,
  157. PHANDLE DomainHandle,
  158. PHANDLE BuiltinDomainHandle,
  159. PSID *DomainSid
  160. );
  161. BOOLEAN
  162. SecurityTestSuite(
  163. HANDLE ServerHandle,
  164. HANDLE DomainHandle,
  165. ULONG Pass
  166. );
  167. BOOLEAN
  168. CheckReturnedSD(
  169. IN SECURITY_INFORMATION SI,
  170. IN PSECURITY_DESCRIPTOR SD,
  171. IN BOOLEAN PrintTestSuccess
  172. );
  173. BOOLEAN
  174. DomainTestSuite(
  175. HANDLE DomainHandle
  176. );
  177. BOOLEAN
  178. GroupTestSuite(
  179. HANDLE DomainHandle,
  180. ULONG Pass
  181. );
  182. BOOLEAN
  183. AliasTestSuite(
  184. HANDLE DomainHandle,
  185. HANDLE BuiltinDomainHandle,
  186. PSID DomainSid,
  187. ULONG Pass
  188. );
  189. BOOLEAN
  190. UserTestSuite(
  191. HANDLE DomainHandle,
  192. ULONG Pass
  193. );
  194. NTSTATUS
  195. SampSetDomainPolicy( VOID );
  196. NTSTATUS
  197. SampGetLsaDomainInfo(
  198. PPOLICY_ACCOUNT_DOMAIN_INFO *PolicyAccountDomainInfo,
  199. PPOLICY_PRIMARY_DOMAIN_INFO *PolicyPrimaryDomainInfo
  200. );
  201. //
  202. // The following are in WRAPPERS.C, but are prototyped here since this
  203. // test is the only thing that should ever call them.
  204. //
  205. NTSTATUS
  206. SamTestPrivateFunctionsDomain(
  207. IN HANDLE DomainHandle
  208. );
  209. NTSTATUS
  210. SamTestPrivateFunctionsUser(
  211. IN HANDLE UserHandle
  212. );
  213. #endif // NOT_PART_OF_PROGRAM
  214. ///////////////////////////////////////////////////////////////////////////////
  215. // //
  216. // Routines //
  217. // //
  218. ///////////////////////////////////////////////////////////////////////////////
  219. VOID
  220. main (argc, argv)
  221. int argc;
  222. char **argv;
  223. /*++
  224. Routine Description:
  225. This is the main entry routine for this test.
  226. Arguments:
  227. NONE
  228. Return Value:
  229. --*/
  230. {
  231. NTSTATUS
  232. NtStatus;
  233. HANDLE
  234. h1, h2, h3;
  235. OBJECT_ATTRIBUTES
  236. ObjectAttributes;
  237. SECURITY_QUALITY_OF_SERVICE
  238. Qos;
  239. //
  240. // Duplicate our primary token to get an impersonation token.
  241. // (no security QOS causes duplicate to have Anonymous level)
  242. //
  243. NtStatus = NtOpenProcessToken( NtCurrentProcess(),
  244. TOKEN_DUPLICATE,
  245. &h1);
  246. printf("Test: Open Process Token: 0x%lx\n", NtStatus);
  247. InitializeObjectAttributes( &ObjectAttributes, NULL, 0, 0, NULL );
  248. NtStatus = NtDuplicateToken( h1,
  249. TOKEN_DUPLICATE,
  250. &ObjectAttributes,
  251. FALSE, // EffectiveOnly
  252. TokenImpersonation,
  253. &h2);
  254. printf("Test: Duplicate Primary to anonymous Impersonation: 0x%lx\n", NtStatus);
  255. //
  256. // Now duplicate that to get a primary
  257. //
  258. NtStatus = NtDuplicateToken( h2,
  259. TOKEN_DUPLICATE,
  260. &ObjectAttributes,
  261. FALSE, // EffectiveOnly
  262. TokenPrimary,
  263. &h3);
  264. printf("Test: Duplicate anonymous Impersonation to Primary: 0x%lx\n", NtStatus);
  265. //
  266. // Now try it again with Impersonate level.
  267. //
  268. Qos.Length = sizeof(Qos);
  269. Qos.ImpersonationLevel = SecurityImpersonation;
  270. Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
  271. Qos.EffectiveOnly = FALSE;
  272. InitializeObjectAttributes( &ObjectAttributes, NULL, 0, 0, NULL );
  273. ObjectAttributes.SecurityQualityOfService = &Qos;
  274. NtStatus = NtDuplicateToken( h1,
  275. TOKEN_DUPLICATE,
  276. &ObjectAttributes,
  277. FALSE, // EffectiveOnly
  278. TokenImpersonation,
  279. &h2);
  280. printf("Test: Duplicate Primary to IMPERSONATE Impersonation: 0x%lx\n", NtStatus);
  281. //
  282. // Now duplicate that to get a primary
  283. //
  284. NtStatus = NtDuplicateToken( h2,
  285. TOKEN_DUPLICATE,
  286. &ObjectAttributes,
  287. FALSE, // EffectiveOnly
  288. TokenPrimary,
  289. &h3);
  290. printf("Test: Duplicate IMPERSONATE Impersonation to Primary: 0x%lx\n", NtStatus);
  291. return;
  292. }
  293. #ifdef NOT_PART_OF_PROGRAM
  294. BOOLEAN
  295. TInitialize (
  296. VOID
  297. )
  298. /*++
  299. Routine Description:
  300. Initialize test variables, et cetera.
  301. Arguments:
  302. None.
  303. Return Value:
  304. Note:
  305. --*/
  306. {
  307. NTSTATUS NtStatus;
  308. STRING Name;
  309. ULONG i;
  310. SID_IDENTIFIER_AUTHORITY WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
  311. SID_IDENTIFIER_AUTHORITY DomainSidAuthority = {0,0,0,0,0,0};
  312. SID_IDENTIFIER_AUTHORITY BuiltinAuthority = SECURITY_NT_AUTHORITY;
  313. //
  314. // Get the domain SIDs from the policy database...
  315. //
  316. NtStatus = SampSetDomainPolicy();
  317. ASSERT(NT_SUCCESS(NtStatus));
  318. //
  319. // A random large integer value..
  320. //
  321. LargeInteger1.LowPart = 1234;
  322. LargeInteger1.HighPart = 0;
  323. LargeInteger2.LowPart = 4321;
  324. LargeInteger2.HighPart = 0;
  325. RtlInitString( &Name, DUMMY_NAME1 );
  326. NtStatus = RtlAnsiStringToUnicodeString( &DummyName1, &Name, TRUE );
  327. TST_SUCCESS_ASSERT(NtStatus);
  328. RtlInitString( &Name, DUMMY_NAME2 );
  329. NtStatus = RtlAnsiStringToUnicodeString( &DummyName2, &Name, TRUE );
  330. TST_SUCCESS_ASSERT(NtStatus);
  331. RtlInitString( &DummyAnsiString1, DUMMY_STRING1 );
  332. NtStatus = RtlAnsiStringToUnicodeString( &DummyString1, &DummyAnsiString1, TRUE );
  333. TST_SUCCESS_ASSERT(NtStatus);
  334. RtlInitString( &DummyAnsiString2, DUMMY_STRING2 );
  335. NtStatus = RtlAnsiStringToUnicodeString( &DummyString2, &DummyAnsiString2, TRUE );
  336. TST_SUCCESS_ASSERT(NtStatus);
  337. DummyLogonHours.UnitsPerWeek = SAM_HOURS_PER_WEEK;
  338. DummyLogonHours.LogonHours = &DummyLogonHoursBitMask[0];
  339. DummyLogonHoursBitMask[LOGON_HOURS_DIFFERENT_OFFSET] = 103; // Any non-zero value
  340. NoLogonRestriction.UnitsPerWeek = SAM_HOURS_PER_WEEK;
  341. NoLogonRestriction.LogonHours = &NoLogonRestrictionBitMask[0];
  342. for ( i=0; i<(ULONG)((NoLogonRestriction.UnitsPerWeek+7)/8); i++) {
  343. NoLogonRestrictionBitMask[0] = 0;
  344. }
  345. //
  346. // Initialize some SIDs
  347. //
  348. WorldSid = RtlAllocateHeap( RtlProcessHeap(), 0, RtlLengthRequiredSid(1) );
  349. ASSERT(WorldSid != NULL);
  350. RtlInitializeSid( WorldSid, &WorldSidAuthority, 1 );
  351. *(RtlSubAuthoritySid( WorldSid, 0 )) = SECURITY_WORLD_RID;
  352. AdminsAliasSid = RtlAllocateHeap(RtlProcessHeap(), 0,RtlLengthRequiredSid( 2 ));
  353. ASSERT(AdminsAliasSid != NULL);
  354. RtlInitializeSid( AdminsAliasSid, &BuiltinAuthority, 2 );
  355. *(RtlSubAuthoritySid( AdminsAliasSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  356. *(RtlSubAuthoritySid( AdminsAliasSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;
  357. AccountAliasSid = RtlAllocateHeap(RtlProcessHeap(), 0,RtlLengthRequiredSid( 2 ));
  358. ASSERT(AccountAliasSid != NULL);
  359. RtlInitializeSid( AccountAliasSid, &BuiltinAuthority, 2 );
  360. *(RtlSubAuthoritySid( AccountAliasSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  361. *(RtlSubAuthoritySid( AccountAliasSid, 1 )) = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
  362. //
  363. // Initialize some stuff for SID and NAME lookup operations
  364. //
  365. RtlInitString( &Name, LOOKUP_KNOWN_NAME0 );
  366. AllUses[0] = LOOKUP_KNOWN_NAME0_USE; AllRids[0] = LOOKUP_KNOWN_NAME0_RID;
  367. NtStatus = RtlAnsiStringToUnicodeString( &AllNames[0], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  368. SomeUses[0] = LOOKUP_KNOWN_NAME0_USE; SomeRids[0] = LOOKUP_KNOWN_NAME0_RID;
  369. NtStatus = RtlAnsiStringToUnicodeString( &SomeNames[0], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  370. if (AccountDomainIsNotPrimaryDomain == TRUE) {
  371. RtlInitString( &Name, LOOKUP_KNOWN_NAME1_A );
  372. } else {
  373. RtlInitString( &Name, LOOKUP_KNOWN_NAME1_P );
  374. }
  375. AllUses[1] = LOOKUP_KNOWN_NAME1_USE; AllRids[1] = LOOKUP_KNOWN_NAME1_RID;
  376. NtStatus = RtlAnsiStringToUnicodeString( &AllNames[1], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  377. SomeUses[1] = LOOKUP_KNOWN_NAME1_USE; SomeRids[1] = LOOKUP_KNOWN_NAME1_RID;
  378. NtStatus = RtlAnsiStringToUnicodeString( &SomeNames[1], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  379. RtlInitString( &Name, LOOKUP_UNKNOWN_NAME0 );
  380. SomeUses[2] = SidTypeUnknown;
  381. NtStatus = RtlAnsiStringToUnicodeString( &SomeNames[2], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  382. NoUses[0] = SidTypeUnknown;
  383. NtStatus = RtlAnsiStringToUnicodeString( &NoNames[0], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  384. RtlInitString( &Name, LOOKUP_UNKNOWN_NAME1 );
  385. SomeUses[3] = SidTypeUnknown;
  386. NtStatus = RtlAnsiStringToUnicodeString( &SomeNames[3], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  387. NoUses[1] = SidTypeUnknown;
  388. NtStatus = RtlAnsiStringToUnicodeString( &NoNames[1], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  389. RtlInitString( &Name, LOOKUP_UNKNOWN_NAME2 );
  390. SomeUses[4] = SidTypeUnknown;
  391. NtStatus = RtlAnsiStringToUnicodeString( &SomeNames[4], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  392. if (AccountDomainIsNotPrimaryDomain == TRUE) {
  393. RtlInitString( &Name, LOOKUP_KNOWN_NAME2_A );
  394. } else {
  395. RtlInitString( &Name, LOOKUP_KNOWN_NAME2_P );
  396. }
  397. AllUses[2] = LOOKUP_KNOWN_NAME2_USE; AllRids[2] = LOOKUP_KNOWN_NAME2_RID;
  398. NtStatus = RtlAnsiStringToUnicodeString( &AllNames[2], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  399. SomeUses[5] = LOOKUP_KNOWN_NAME2_USE; SomeRids[5] = LOOKUP_KNOWN_NAME2_RID;
  400. NtStatus = RtlAnsiStringToUnicodeString( &SomeNames[5], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  401. RtlInitString( &Name, LOOKUP_UNKNOWN_NAME3 );
  402. SomeUses[6] = SidTypeUnknown;
  403. NtStatus = RtlAnsiStringToUnicodeString( &SomeNames[6], &Name, TRUE ); TST_SUCCESS_ASSERT(NtStatus);
  404. DetermineTestsToRun();
  405. return(TRUE);
  406. }
  407. NTSTATUS
  408. SampSetDomainPolicy(
  409. )
  410. /*++
  411. Routine Description:
  412. This routine sets the names and SIDs for the builtin and account domains.
  413. The builtin account domain has a well known name and SID.
  414. The account domain has these stored in the Policy database.
  415. It places the information for these domains in:
  416. BuiltinDomainSid
  417. BuiltinDomainName
  418. AccountDomainSid
  419. AccountDomainName
  420. PrimaryDomainSid
  421. PrimaryDomainName
  422. It also sets the boolean:
  423. AccountDomainIsNotPrimaryDomain
  424. to TRUE if the account domain is found to be different from the
  425. Primary Domain.
  426. Arguments:
  427. None.
  428. Return Value:
  429. --*/
  430. {
  431. NTSTATUS NtStatus;
  432. PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo;
  433. PPOLICY_PRIMARY_DOMAIN_INFO PolicyPrimaryDomainInfo;
  434. SID_IDENTIFIER_AUTHORITY BuiltinAuthority = SECURITY_NT_AUTHORITY;
  435. //
  436. // Builtin domain - well-known name and SID
  437. //
  438. RtlInitUnicodeString( &BuiltinDomainName, L"Builtin");
  439. BuiltinDomainSid = RtlAllocateHeap(RtlProcessHeap(), 0,RtlLengthRequiredSid( 1 ));
  440. ASSERT( BuiltinDomainSid != NULL );
  441. RtlInitializeSid( BuiltinDomainSid, &BuiltinAuthority, 1 );
  442. *(RtlSubAuthoritySid( BuiltinDomainSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  443. //
  444. // Account domain
  445. //
  446. NtStatus = SampGetLsaDomainInfo(
  447. &PolicyAccountDomainInfo,
  448. &PolicyPrimaryDomainInfo
  449. );
  450. if (!NT_SUCCESS(NtStatus)) {
  451. return(NtStatus);
  452. }
  453. AccountDomainSid = PolicyAccountDomainInfo->DomainSid;
  454. AccountDomainName = PolicyAccountDomainInfo->DomainName;
  455. PrimaryDomainSid = PolicyPrimaryDomainInfo->Sid;
  456. PrimaryDomainName = PolicyPrimaryDomainInfo->Name;
  457. //
  458. // Determine whether the account domain is a primary domain.
  459. //
  460. AccountDomainIsNotPrimaryDomain =
  461. !RtlEqualUnicodeString( &PrimaryDomainName, &AccountDomainName, TRUE);
  462. return(NtStatus);;
  463. }
  464. NTSTATUS
  465. SampGetLsaDomainInfo(
  466. PPOLICY_ACCOUNT_DOMAIN_INFO *PolicyAccountDomainInfo,
  467. PPOLICY_PRIMARY_DOMAIN_INFO *PolicyPrimaryDomainInfo
  468. )
  469. /*++
  470. Routine Description:
  471. This routine retrieves ACCOUNT domain information from the LSA
  472. policy database.
  473. Arguments:
  474. PolicyAccountDomainInfo - Receives a pointer to a
  475. POLICY_ACCOUNT_DOMAIN_INFO structure containing the account
  476. domain info.
  477. PolicyPrimaryDomainInfo - Receives a pointer to a
  478. POLICY_PRIMARY_DOMAIN_INFO structure containing the Primary
  479. domain info.
  480. Return Value:
  481. STATUS_SUCCESS - Succeeded.
  482. Other status values that may be returned from:
  483. LsaOpenPolicy()
  484. LsaQueryInformationPolicy()
  485. --*/
  486. {
  487. NTSTATUS Status, IgnoreStatus;
  488. LSA_HANDLE PolicyHandle;
  489. OBJECT_ATTRIBUTES PolicyObjectAttributes;
  490. //
  491. // Open the policy database
  492. //
  493. InitializeObjectAttributes( &PolicyObjectAttributes,
  494. NULL, // Name
  495. 0, // Attributes
  496. NULL, // Root
  497. NULL ); // Security Descriptor
  498. Status = LsaOpenPolicy( NULL,
  499. &PolicyObjectAttributes,
  500. POLICY_VIEW_LOCAL_INFORMATION,
  501. &PolicyHandle );
  502. if ( NT_SUCCESS(Status) ) {
  503. //
  504. // Query the account domain information
  505. //
  506. Status = LsaQueryInformationPolicy( PolicyHandle,
  507. PolicyAccountDomainInformation,
  508. (PVOID *)PolicyAccountDomainInfo );
  509. #if DBG
  510. if ( NT_SUCCESS(Status) ) {
  511. ASSERT( (*PolicyAccountDomainInfo) != NULL );
  512. ASSERT( (*PolicyAccountDomainInfo)->DomainSid != NULL );
  513. ASSERT( (*PolicyAccountDomainInfo)->DomainName.Buffer != NULL );
  514. }
  515. #endif \\DBG
  516. //
  517. // Query the Primary domain information
  518. //
  519. Status = LsaQueryInformationPolicy( PolicyHandle,
  520. PolicyPrimaryDomainInformation,
  521. (PVOID *)PolicyPrimaryDomainInfo );
  522. #if DBG
  523. if ( NT_SUCCESS(Status) ) {
  524. ASSERT( (*PolicyPrimaryDomainInfo) != NULL );
  525. ASSERT( (*PolicyPrimaryDomainInfo)->Sid != NULL );
  526. ASSERT( (*PolicyPrimaryDomainInfo)->Name.Buffer != NULL );
  527. }
  528. #endif \\DBG
  529. IgnoreStatus = LsaClose( PolicyHandle );
  530. ASSERT(NT_SUCCESS(IgnoreStatus));
  531. }
  532. return(Status);
  533. }
  534. PSID
  535. CreateUserSid(
  536. PSID DomainSid,
  537. ULONG Rid
  538. )
  539. /*++
  540. Routine Description:
  541. This function creates a domain account sid given a domain sid and
  542. the relative id of the account within the domain.
  543. Arguments:
  544. None.
  545. Return Value:
  546. Pointer to Sid, or NULL on failure.
  547. The returned Sid must be freed with DeleteUserSid
  548. --*/
  549. {
  550. NTSTATUS IgnoreStatus;
  551. PSID AccountSid;
  552. UCHAR AccountSubAuthorityCount = *RtlSubAuthorityCountSid(DomainSid) + (UCHAR)1;
  553. ULONG AccountSidLength = RtlLengthRequiredSid(AccountSubAuthorityCount);
  554. PULONG RidLocation;
  555. // Temp sanity check
  556. ASSERT(AccountSidLength == SeLengthSid(DomainSid) + sizeof(ULONG));
  557. //
  558. // Allocate space for the account sid
  559. //
  560. AccountSid = MIDL_user_allocate(AccountSidLength);
  561. if (AccountSid != NULL) {
  562. //
  563. // Copy the domain sid into the first part of the account sid
  564. //
  565. IgnoreStatus = RtlCopySid(AccountSidLength, AccountSid, DomainSid);
  566. ASSERT(NT_SUCCESS(IgnoreStatus));
  567. //
  568. // Increment the account sid sub-authority count
  569. //
  570. *RtlSubAuthorityCountSid(AccountSid) = AccountSubAuthorityCount;
  571. //
  572. // Add the rid as the final sub-authority
  573. //
  574. RidLocation = RtlSubAuthoritySid(AccountSid, AccountSubAuthorityCount - 1);
  575. *RidLocation = Rid;
  576. }
  577. return(AccountSid);
  578. }
  579. VOID
  580. DeleteUserSid(
  581. PSID UserSid
  582. )
  583. /*++
  584. Routine Description:
  585. Frees a sid returned by CreateUserSid.
  586. Arguments:
  587. None.
  588. Return Value:
  589. None.
  590. --*/
  591. {
  592. MIDL_user_free(UserSid);
  593. }
  594. BOOLEAN
  595. EnableSecurityPrivilege(
  596. VOID
  597. )
  598. /*++
  599. Routine Description:
  600. This function enabled the SeSecurityPrivilege privilege.
  601. Arguments:
  602. None.
  603. Return Value:
  604. TRUE if privilege successfully enabled.
  605. FALSE if not successfully enabled.
  606. --*/
  607. {
  608. NTSTATUS Status;
  609. HANDLE Token;
  610. LUID SecurityPrivilege;
  611. PTOKEN_PRIVILEGES NewState;
  612. ULONG ReturnLength;
  613. //
  614. // Open our own token
  615. //
  616. Status = NtOpenProcessToken(
  617. NtCurrentProcess(),
  618. TOKEN_ADJUST_PRIVILEGES,
  619. &Token
  620. );
  621. if (!NT_SUCCESS(Status)) {
  622. printf(" \n\n\n");
  623. printf("Tsamobj: Can't open process token to enable Security Privilege.\n");
  624. printf(" Completion status of NtOpenProcessToken() is: 0x%lx\n", Status);
  625. printf("\n");
  626. return(FALSE);
  627. }
  628. //
  629. // Initialize the adjustment structure
  630. //
  631. SecurityPrivilege =
  632. RtlConvertLongToLargeInteger(SE_SECURITY_PRIVILEGE);
  633. ASSERT( (sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)) < 100);
  634. NewState = RtlAllocateHeap( RtlProcessHeap(), 0, 100 );
  635. NewState->PrivilegeCount = 1;
  636. NewState->Privileges[0].Luid = SecurityPrivilege;
  637. NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  638. //
  639. // Set the state of the privilege to ENABLED.
  640. //
  641. Status = NtAdjustPrivilegesToken(
  642. Token, // TokenHandle
  643. FALSE, // DisableAllPrivileges
  644. NewState, // NewState
  645. 0, // BufferLength
  646. NULL, // PreviousState (OPTIONAL)
  647. &ReturnLength // ReturnLength
  648. );
  649. // don't use NT_SUCCESS here because STATUS_NOT_ALL_ASSIGNED is a success status
  650. if (Status != STATUS_SUCCESS) {
  651. return(FALSE);
  652. }
  653. //
  654. // Clean up some stuff before returning
  655. //
  656. RtlFreeHeap( RtlProcessHeap(), 0, NewState );
  657. Status = NtClose( Token );
  658. ASSERT(NT_SUCCESS(Status));
  659. return TRUE;
  660. }
  661. VOID
  662. printfSid(
  663. PSID Sid
  664. )
  665. /*++
  666. Routine Description:
  667. Prints a sid
  668. Arguments:
  669. None.
  670. Return Value:
  671. None.
  672. --*/
  673. {
  674. UCHAR Buffer[128];
  675. UCHAR String[128];
  676. UCHAR i;
  677. ULONG Tmp;
  678. PISID iSid = (PISID)Sid; // pointer to opaque structure
  679. PSID NextSid = (PSID)Buffer;
  680. ASSERT(sizeof(Buffer) >= RtlLengthRequiredSid(1));
  681. {
  682. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_WORLD_SID_AUTHORITY;
  683. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  684. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_WORLD_RID;
  685. if (RtlEqualSid(Sid, NextSid)) {
  686. printf("World");
  687. return;
  688. }
  689. }
  690. {
  691. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_LOCAL_SID_AUTHORITY;
  692. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  693. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_LOCAL_RID;
  694. if (RtlEqualSid(Sid, NextSid)) {
  695. printf("Local");
  696. return;
  697. }
  698. }
  699. {
  700. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
  701. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  702. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_CREATOR_OWNER_RID;
  703. if (RtlEqualSid(Sid, NextSid)) {
  704. printf("Creator");
  705. return;
  706. }
  707. }
  708. {
  709. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
  710. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  711. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_DIALUP_RID;
  712. if (RtlEqualSid(Sid, NextSid)) {
  713. printf("Dialup");
  714. return;
  715. }
  716. }
  717. {
  718. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
  719. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  720. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_NETWORK_RID;
  721. if (RtlEqualSid(Sid, NextSid)) {
  722. printf("Network");
  723. return;
  724. }
  725. }
  726. {
  727. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
  728. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  729. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_BATCH_RID;
  730. if (RtlEqualSid(Sid, NextSid)) {
  731. printf("Batch");
  732. return;
  733. }
  734. }
  735. {
  736. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
  737. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  738. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_INTERACTIVE_RID;
  739. if (RtlEqualSid(Sid, NextSid)) {
  740. printf("Interactive");
  741. return;
  742. }
  743. }
  744. {
  745. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
  746. RtlInitializeSid(NextSid, &SidAuthority, 1 );
  747. *(RtlSubAuthoritySid(NextSid, 0)) = SECURITY_LOCAL_SYSTEM_RID;
  748. if (RtlEqualSid(Sid, NextSid)) {
  749. printf("Local System");
  750. return;
  751. }
  752. }
  753. sprintf(Buffer, "S-%u-", (USHORT)iSid->Revision );
  754. strcpy(String, Buffer);
  755. if ( (iSid->IdentifierAuthority.Value[0] != 0) ||
  756. (iSid->IdentifierAuthority.Value[1] != 0) ){
  757. sprintf(Buffer, "0x%02hx%02hx%02hx%02hx%02hx%02hx",
  758. (USHORT)iSid->IdentifierAuthority.Value[0],
  759. (USHORT)iSid->IdentifierAuthority.Value[1],
  760. (USHORT)iSid->IdentifierAuthority.Value[2],
  761. (USHORT)iSid->IdentifierAuthority.Value[3],
  762. (USHORT)iSid->IdentifierAuthority.Value[4],
  763. (USHORT)iSid->IdentifierAuthority.Value[5] );
  764. strcat(String, Buffer);
  765. } else {
  766. Tmp = (ULONG)iSid->IdentifierAuthority.Value[5] +
  767. (ULONG)(iSid->IdentifierAuthority.Value[4] << 8) +
  768. (ULONG)(iSid->IdentifierAuthority.Value[3] << 16) +
  769. (ULONG)(iSid->IdentifierAuthority.Value[2] << 24);
  770. sprintf(Buffer, "%lu", Tmp);
  771. strcat(String, Buffer);
  772. }
  773. for (i=0;i<iSid->SubAuthorityCount ;i++ ) {
  774. sprintf(Buffer, "-%lu", iSid->SubAuthority[i]);
  775. strcat(String, Buffer);
  776. }
  777. printf(Buffer);
  778. return;
  779. }
  780. VOID
  781. DetermineTestsToRun(
  782. VOID
  783. )
  784. /*++
  785. Routine Description:
  786. This function determines which tests are to be run.
  787. Arguments:
  788. None.
  789. Return Value:
  790. None.
  791. --*/
  792. {
  793. NTSTATUS Status;
  794. HANDLE Token;
  795. PTOKEN_USER User;
  796. PTOKEN_GROUPS Groups;
  797. ULONG ReturnLength,
  798. i;
  799. //
  800. // See if we can play with auditing information
  801. //
  802. SecurityOperatorTest = EnableSecurityPrivilege();
  803. //
  804. // Open our own token
  805. //
  806. Status = NtOpenProcessToken(
  807. NtCurrentProcess(),
  808. TOKEN_QUERY,
  809. &Token
  810. );
  811. if (!NT_SUCCESS(Status)) {
  812. printf(" \n\n\n");
  813. printf("Tsamobj: Can't open process token to query owner.\n");
  814. printf(" Completion status of NtOpenProcessToken() is: 0x%lx\n", Status);
  815. printf("\n");
  816. return;
  817. }
  818. //
  819. // Query the user id
  820. //
  821. User = RtlAllocateHeap( RtlProcessHeap(), 0, 1000 ); // should be plenty big
  822. Status = NtQueryInformationToken( Token, TokenUser, User, 1000, &ReturnLength );
  823. ASSERT(NT_SUCCESS(Status));
  824. //
  825. // See if the ID is one of the special IDs (e.g., local admin,
  826. // domain account operator, or domain admin)
  827. //
  828. SeeIfSidIsSpecial( User->User.Sid );
  829. //
  830. // Query the group ids
  831. //
  832. Groups = RtlAllocateHeap( RtlProcessHeap(), 0, 1000 ); // should be plenty big
  833. Status = NtQueryInformationToken( Token, TokenGroups, Groups, 1000, &ReturnLength );
  834. ASSERT(NT_SUCCESS(Status));
  835. //
  836. // See if any of these IDs are special IDs
  837. //
  838. for (i=0; i<Groups->GroupCount; i++) {
  839. SeeIfSidIsSpecial( Groups->Groups[i].Sid );
  840. }
  841. //
  842. // Clean up some stuff before returning
  843. //
  844. RtlFreeHeap( RtlProcessHeap(), 0, User );
  845. RtlFreeHeap( RtlProcessHeap(), 0, Groups );
  846. Status = NtClose( Token );
  847. ASSERT(NT_SUCCESS(Status));
  848. printf("\n\n\n\nPerforming:\n\n");
  849. printf(" Administrator Alias Test. . . . . ");
  850. if (AdminsAliasTest) {
  851. printf("Yes\n\n");
  852. } else {
  853. printf("No\n\n");
  854. }
  855. printf(" Account Operator Alias Test . . ");
  856. if (AccountOpAliasTest) {
  857. printf("Yes\n\n");
  858. } else {
  859. printf("No\n\n");
  860. }
  861. printf(" Security Operator Test . . . . . ");
  862. if (SecurityOperatorTest) {
  863. printf("Yes\n\n");
  864. } else {
  865. printf("No\n\n");
  866. }
  867. printf("\n\n\n");
  868. return;
  869. }
  870. VOID
  871. SeeIfSidIsSpecial(
  872. IN PSID Sid
  873. )
  874. /*++
  875. Routine Description:
  876. This function determines whether the passed SID is one of the special
  877. SIDs, such as ADMINISTRATORS alias, or DomainAccountOperator, and
  878. sets test flags accordingly.
  879. Arguments:
  880. Sid - Pointer to the SID to check.
  881. Return Value:
  882. None.
  883. --*/
  884. {
  885. if (RtlEqualSid( Sid, AdminsAliasSid )){
  886. AdminsAliasTest = TRUE;
  887. }
  888. if (RtlEqualSid( Sid, AccountAliasSid )){
  889. AccountOpAliasTest = TRUE;
  890. }
  891. return;
  892. }
  893. ///////////////////////////////////////////////////////////////////////////////
  894. // //
  895. // Server Object Test Suite //
  896. // //
  897. ///////////////////////////////////////////////////////////////////////////////
  898. BOOLEAN
  899. ServerTestSuite(
  900. PHANDLE ServerHandle,
  901. PHANDLE DomainHandle,
  902. PHANDLE BuiltinDomainHandle,
  903. PSID *DomainSid
  904. )
  905. {
  906. NTSTATUS NtStatus;
  907. OBJECT_ATTRIBUTES ObjectAttributes;
  908. BOOLEAN TestStatus = TRUE;
  909. ULONG CountReturned;
  910. SAM_ENUMERATE_HANDLE EnumerationContext;
  911. PSAM_RID_ENUMERATION EnumerationBuffer;
  912. PSID BuiltinDomainSid;
  913. ACCESS_MASK ServerAccessMask, DomainAccessMask;
  914. printf("\n");
  915. printf("\n");
  916. printf(" Server Object Test\n");
  917. ///////////////////////////////////////////////////////////////////////////
  918. // //
  919. // Connect To Server //
  920. // //
  921. ///////////////////////////////////////////////////////////////////////////
  922. printf("\n");
  923. printf(" Connect / Disconnect. . . . . . . . . . . . . . . . . Suite\n");
  924. printf(" Connect . . . . . . . . . . . . . . . . . . . . . . ");
  925. ServerAccessMask = SAM_SERVER_READ | SAM_SERVER_EXECUTE;
  926. if (AdminsAliasTest) {
  927. ServerAccessMask |= SAM_SERVER_ALL_ACCESS;
  928. }
  929. if (SecurityOperatorTest) {
  930. ServerAccessMask |= ACCESS_SYSTEM_SECURITY;
  931. }
  932. InitializeObjectAttributes( &ObjectAttributes, NULL, 0, 0, NULL );
  933. NtStatus = SamConnect(
  934. NULL, // ServerName (Local machine)
  935. ServerHandle,
  936. ServerAccessMask,
  937. &ObjectAttributes
  938. );
  939. if (!NT_SUCCESS(NtStatus)) {
  940. printf("Failed\n");
  941. printf(" Completion status is 0x%lx\n", NtStatus);
  942. TestStatus = FALSE;
  943. } else {
  944. printf("Succeeded\n");
  945. }
  946. if (NT_SUCCESS(NtStatus)) {
  947. printf(" Disconnect . . . . . . . . . . . . . . . . . . . . ");
  948. NtStatus = SamCloseHandle( (*ServerHandle) );
  949. if (!NT_SUCCESS(NtStatus)) {
  950. printf("Failed\n");
  951. printf(" Completion status is 0x%lx\n", NtStatus);
  952. TestStatus = FALSE;
  953. } else {
  954. printf("Succeeded\n");
  955. }
  956. }
  957. printf(" Re-Connect . . . . . . . . . . . . . . . . . . . . ");
  958. NtStatus = SamConnect(
  959. NULL, // ServerName (Local machine)
  960. ServerHandle,
  961. ServerAccessMask,
  962. &ObjectAttributes
  963. );
  964. if (!NT_SUCCESS(NtStatus)) {
  965. printf("Failed\n");
  966. printf(" Completion status is 0x%lx\n", NtStatus);
  967. TestStatus = FALSE;
  968. } else {
  969. printf("Succeeded\n");
  970. }
  971. ///////////////////////////////////////////////////////////////////////////
  972. // //
  973. // Lookup/Enumerate Domains Suite //
  974. // //
  975. ///////////////////////////////////////////////////////////////////////////
  976. printf("\n");
  977. printf(" Domain Lookup/Enumerate/Open . . . . . . . . . . . . Suite\n");
  978. if (NT_SUCCESS(NtStatus)) {
  979. printf(" Lookup Account Domain . . . . . . . . . . . . . . . ");
  980. NtStatus = SamLookupDomainInSamServer(
  981. (*ServerHandle),
  982. &AccountDomainName,
  983. DomainSid
  984. );
  985. if (!NT_SUCCESS(NtStatus)) {
  986. printf("Failed\n");
  987. printf(" Completion status is 0x%lx\n", NtStatus);
  988. TestStatus = FALSE;
  989. } else {
  990. if ( TRUE != RtlEqualSid((*DomainSid), AccountDomainSid)) {
  991. printf("Failed\n");
  992. printf(" The SID retrieved from the policy database did not\n");
  993. printf(" match the SID retrieved from SAM for the account\n");
  994. printf(" domain.\n");
  995. printf(" Sid from Policy Database is: ");
  996. printfSid( AccountDomainSid ); printf("\n");
  997. printf(" Sid from SAM is: ");
  998. printfSid( (*DomainSid) ); printf("\n");
  999. TestStatus = FALSE;
  1000. } else {
  1001. printf("Succeeded\n");
  1002. }
  1003. }
  1004. }
  1005. if (NT_SUCCESS(NtStatus)) {
  1006. printf(" Enumerate Domain . . . . . . . . . . . . . . . . . ");
  1007. EnumerationContext = 0;
  1008. EnumerationBuffer = NULL;
  1009. NtStatus = SamEnumerateDomainsInSamServer(
  1010. (*ServerHandle),
  1011. &EnumerationContext,
  1012. (PVOID *)&EnumerationBuffer,
  1013. 1024, // PreferedMaximumLength
  1014. &CountReturned
  1015. );
  1016. if (!NT_SUCCESS(NtStatus)) {
  1017. printf("Failed\n");
  1018. printf(" Completion status is 0x%lx\n", NtStatus);
  1019. TestStatus = FALSE;
  1020. } else {
  1021. if (CountReturned == 0) {
  1022. printf("Failed\n");
  1023. printf(" Completion status is 0x%lx\n", NtStatus);
  1024. printf(" CountReturned is: 0x%lx\n", CountReturned);
  1025. printf(" EnumerationContext is: 0x%lx\n", EnumerationContext);
  1026. printf(" EnumerationBuffer Address is: 0x%lx\n", (ULONG)EnumerationBuffer);
  1027. TestStatus = FALSE;
  1028. } else {
  1029. printf("Succeeded\n");
  1030. }
  1031. SamFreeMemory( EnumerationBuffer );
  1032. }
  1033. }
  1034. if (NT_SUCCESS(NtStatus)) {
  1035. printf(" Open Account Domain . . . . . . . . . . . . . . . . ");
  1036. if (NT_SUCCESS(NtStatus)) {
  1037. DomainAccessMask = DOMAIN_READ | DOMAIN_EXECUTE;
  1038. if (AccountOpAliasTest) {
  1039. DomainAccessMask |= DOMAIN_READ | DOMAIN_WRITE | DOMAIN_EXECUTE;
  1040. }
  1041. if (AdminsAliasTest) {
  1042. DomainAccessMask |= DOMAIN_ALL_ACCESS;
  1043. }
  1044. if (SecurityOperatorTest) {
  1045. DomainAccessMask |= ACCESS_SYSTEM_SECURITY;
  1046. }
  1047. NtStatus = SamOpenDomain(
  1048. (*ServerHandle),
  1049. DomainAccessMask,
  1050. *DomainSid,
  1051. DomainHandle
  1052. );
  1053. if (!NT_SUCCESS(NtStatus)) {
  1054. printf("Failed\n");
  1055. printf(" Completion status is 0x%lx\n", NtStatus);
  1056. TestStatus = FALSE;
  1057. } else {
  1058. printf("Succeeded\n");
  1059. }
  1060. }
  1061. }
  1062. if (NT_SUCCESS(NtStatus)) {
  1063. printf(" Open Builtin Domain . . . . . . . . . . . . . . . . ");
  1064. NtStatus = SamLookupDomainInSamServer(
  1065. (*ServerHandle),
  1066. &BuiltinDomainName,
  1067. &BuiltinDomainSid
  1068. );
  1069. if (NT_SUCCESS(NtStatus)) {
  1070. DomainAccessMask = DOMAIN_READ | DOMAIN_EXECUTE;
  1071. if (AccountOpAliasTest) {
  1072. DomainAccessMask |= DOMAIN_READ | DOMAIN_WRITE | DOMAIN_EXECUTE;
  1073. }
  1074. if (AdminsAliasTest) {
  1075. DomainAccessMask |= (DOMAIN_EXECUTE | DOMAIN_READ |
  1076. DOMAIN_READ_OTHER_PARAMETERS |
  1077. DOMAIN_ADMINISTER_SERVER |
  1078. DOMAIN_CREATE_ALIAS);
  1079. }
  1080. // if (SecurityOperatorTest) {
  1081. // DomainAccessMask |= ACCESS_SYSTEM_SECURITY;
  1082. // }
  1083. NtStatus = SamOpenDomain(
  1084. (*ServerHandle),
  1085. DomainAccessMask,
  1086. BuiltinDomainSid,
  1087. BuiltinDomainHandle
  1088. );
  1089. if (!NT_SUCCESS(NtStatus)) {
  1090. printf("Failed\n");
  1091. printf(" Completion status is 0x%lx\n", NtStatus);
  1092. TestStatus = FALSE;
  1093. } else {
  1094. printf("Succeeded\n");
  1095. }
  1096. }
  1097. }
  1098. return(TestStatus);
  1099. }
  1100. ///////////////////////////////////////////////////////////////////////////////
  1101. // //
  1102. // Security Manipulation Test Suite //
  1103. // //
  1104. ///////////////////////////////////////////////////////////////////////////////
  1105. BOOLEAN
  1106. SecurityTestSuite(
  1107. HANDLE ServerHandle,
  1108. HANDLE DomainHandle,
  1109. ULONG Pass
  1110. )
  1111. {
  1112. BOOLEAN TestStatus = TRUE;
  1113. NTSTATUS NtStatus;
  1114. PSECURITY_DESCRIPTOR OriginalServerSD,
  1115. OriginalDomainSD,
  1116. OriginalUserSD,
  1117. OriginalGroupSD,
  1118. SD1;
  1119. SECURITY_INFORMATION SI1;
  1120. PVOID TmpPointer1;
  1121. SECURITY_DESCRIPTOR SD1_Body;
  1122. HANDLE GroupHandle,
  1123. UserHandle;
  1124. printf("\n");
  1125. printf("\n");
  1126. printf("\n");
  1127. if (Pass == 1) {
  1128. printf(" Security Manipulation (Pass #1) Test\n");
  1129. ///////////////////////////////////////////////////////////////////////////
  1130. // //
  1131. // Query Suite //
  1132. // //
  1133. ///////////////////////////////////////////////////////////////////////////
  1134. printf("\n");
  1135. printf(" Query Security . . . . . . . . . . . . . . . . . . . Suite\n");
  1136. //
  1137. // Get Server's original SD
  1138. //
  1139. SI1 = 0;
  1140. if (AdminsAliasTest) {
  1141. SI1 |= OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  1142. DACL_SECURITY_INFORMATION;
  1143. }
  1144. if (SecurityOperatorTest) {
  1145. SI1 |= SACL_SECURITY_INFORMATION;
  1146. }
  1147. if (SI1 != 0) {
  1148. printf(" Query Server Security Descriptor . . . . . . . . . . ");
  1149. SD1 = NULL;
  1150. NtStatus = SamQuerySecurityObject(
  1151. ServerHandle,
  1152. SI1,
  1153. &SD1
  1154. );
  1155. if (NT_SUCCESS(NtStatus)) {
  1156. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1157. //
  1158. // Normally we would do a "SamFreeMemory( SD1 )" here.
  1159. // However, we want to save this SD for future reference
  1160. // and use.
  1161. //
  1162. OriginalServerSD = SD1;
  1163. } else {
  1164. printf("Failed\n");
  1165. printf(" Completion status is 0x%lx\n", NtStatus);
  1166. TestStatus = FALSE;
  1167. }
  1168. }
  1169. //
  1170. // Get domain's original SD
  1171. //
  1172. SI1 = 0;
  1173. if (AdminsAliasTest) {
  1174. SI1 |= OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  1175. DACL_SECURITY_INFORMATION;
  1176. }
  1177. if (SecurityOperatorTest) {
  1178. SI1 |= SACL_SECURITY_INFORMATION;
  1179. }
  1180. if (SI1 != 0) {
  1181. printf(" Query Domain Security Descriptor . . . . . . . . . . ");
  1182. SD1 = NULL;
  1183. NtStatus = SamQuerySecurityObject(
  1184. DomainHandle,
  1185. SI1,
  1186. &SD1
  1187. );
  1188. if (NT_SUCCESS(NtStatus)) {
  1189. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1190. //
  1191. // Normally we would do a "SamFreeMemory( SD1 )" here.
  1192. // However, we want to save this SD for future reference
  1193. // and use.
  1194. //
  1195. OriginalDomainSD = SD1;
  1196. } else {
  1197. printf("Failed\n");
  1198. printf(" Completion status is 0x%lx\n", NtStatus);
  1199. TestStatus = FALSE;
  1200. }
  1201. }
  1202. //
  1203. // Make sure the wrapper doesn't choke on a non-null pointer being passed
  1204. // (assuming we have allocated memory).
  1205. //
  1206. SI1 = 0;
  1207. if (AdminsAliasTest) {
  1208. SI1 |= OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  1209. DACL_SECURITY_INFORMATION;
  1210. }
  1211. if (SecurityOperatorTest) {
  1212. SI1 |= SACL_SECURITY_INFORMATION;
  1213. }
  1214. if (SI1 != 0) {
  1215. printf(" Query Passing Non-null return buffer . . . . . . . . ");
  1216. SD1 = RtlAllocateHeap( RtlProcessHeap(), 0, 1000 ); ASSERT(SD1 != NULL);
  1217. TmpPointer1 = SD1;
  1218. NtStatus = SamQuerySecurityObject(
  1219. DomainHandle,
  1220. SI1,
  1221. &SD1
  1222. );
  1223. if (NT_SUCCESS(NtStatus)) {
  1224. if (SD1 != TmpPointer1) {
  1225. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1226. if (TestStatus) {
  1227. SamFreeMemory( SD1 );
  1228. }
  1229. } else {
  1230. printf("Failed\n");
  1231. printf(" Passed buffer address used on return.\n");
  1232. printf(" RPC should have allocated another buffer.\n");
  1233. TestStatus = FALSE;
  1234. }
  1235. } else {
  1236. printf("Failed\n");
  1237. printf(" Completion status is 0x%lx\n", NtStatus);
  1238. TestStatus = FALSE;
  1239. }
  1240. RtlFreeHeap( RtlProcessHeap(), 0, TmpPointer1 );
  1241. }
  1242. //
  1243. // Make sure we can query nothing
  1244. //
  1245. printf(" Query Nothing . . . . . . . . . . . . . . . . . . . . ");
  1246. SI1 = 0;
  1247. SD1 = NULL;
  1248. NtStatus = SamQuerySecurityObject(
  1249. DomainHandle,
  1250. SI1,
  1251. &SD1
  1252. );
  1253. if (NT_SUCCESS(NtStatus)) {
  1254. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1255. if (TestStatus) {
  1256. SamFreeMemory( SD1 );
  1257. }
  1258. } else {
  1259. printf("Failed\n");
  1260. printf(" Completion status is 0x%lx\n", NtStatus);
  1261. TestStatus = FALSE;
  1262. }
  1263. //
  1264. // Query owner
  1265. //
  1266. if (AdminsAliasTest) {
  1267. printf(" Query Owner (Server Object) . . . . . . . . . . . . . ");
  1268. SI1 = OWNER_SECURITY_INFORMATION;
  1269. SD1 = NULL;
  1270. NtStatus = SamQuerySecurityObject(
  1271. ServerHandle,
  1272. SI1,
  1273. &SD1
  1274. );
  1275. if (NT_SUCCESS(NtStatus)) {
  1276. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1277. if (TestStatus) {
  1278. SamFreeMemory( SD1 );
  1279. }
  1280. } else {
  1281. printf("Failed\n");
  1282. printf(" Completion status is 0x%lx\n", NtStatus);
  1283. TestStatus = FALSE;
  1284. }
  1285. }
  1286. if (AdminsAliasTest) {
  1287. printf(" Query Owner (Domain Object) . . . . . . . . . . . . . ");
  1288. SI1 = OWNER_SECURITY_INFORMATION;
  1289. SD1 = NULL;
  1290. NtStatus = SamQuerySecurityObject(
  1291. DomainHandle,
  1292. SI1,
  1293. &SD1
  1294. );
  1295. if (NT_SUCCESS(NtStatus)) {
  1296. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1297. if (TestStatus) {
  1298. SamFreeMemory( SD1 );
  1299. }
  1300. } else {
  1301. printf("Failed\n");
  1302. printf(" Completion status is 0x%lx\n", NtStatus);
  1303. TestStatus = FALSE;
  1304. }
  1305. }
  1306. if (AdminsAliasTest) {
  1307. //
  1308. // Query Group
  1309. //
  1310. printf(" Query Group . . . . . . . . . . . . . . . . . . . . . ");
  1311. SI1 = GROUP_SECURITY_INFORMATION;
  1312. SD1 = NULL;
  1313. NtStatus = SamQuerySecurityObject(
  1314. DomainHandle,
  1315. SI1,
  1316. &SD1
  1317. );
  1318. if (NT_SUCCESS(NtStatus)) {
  1319. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1320. if (TestStatus) {
  1321. SamFreeMemory( SD1 );
  1322. }
  1323. } else {
  1324. printf("Failed\n");
  1325. printf(" Completion status is 0x%lx\n", NtStatus);
  1326. TestStatus = FALSE;
  1327. }
  1328. //
  1329. // Query Dacl
  1330. //
  1331. printf(" Query DACL . . . . . . . . . . . . . . . . . . . . . ");
  1332. SI1 = DACL_SECURITY_INFORMATION;
  1333. SD1 = NULL;
  1334. NtStatus = SamQuerySecurityObject(
  1335. DomainHandle,
  1336. SI1,
  1337. &SD1
  1338. );
  1339. if (NT_SUCCESS(NtStatus)) {
  1340. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1341. if (TestStatus) {
  1342. SamFreeMemory( SD1 );
  1343. }
  1344. } else {
  1345. printf("Failed\n");
  1346. printf(" Completion status is 0x%lx\n", NtStatus);
  1347. TestStatus = FALSE;
  1348. }
  1349. //
  1350. // Query Sacl
  1351. //
  1352. printf(" Query SACL . . . . . . . . . . . . . . . . . . . . . ");
  1353. SI1 = SACL_SECURITY_INFORMATION;
  1354. SD1 = NULL;
  1355. NtStatus = SamQuerySecurityObject(
  1356. DomainHandle,
  1357. SI1,
  1358. &SD1
  1359. );
  1360. if (NT_SUCCESS(NtStatus)) {
  1361. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1362. if (TestStatus) {
  1363. SamFreeMemory( SD1 );
  1364. }
  1365. } else {
  1366. printf("Failed\n");
  1367. printf(" Completion status is 0x%lx\n", NtStatus);
  1368. TestStatus = FALSE;
  1369. }
  1370. } // end_if (AdminsAliasTest)
  1371. ///////////////////////////////////////////////////////////////////////////
  1372. // //
  1373. // Set Suite //
  1374. // //
  1375. ///////////////////////////////////////////////////////////////////////////
  1376. printf("\n");
  1377. printf(" Set Security . . . . . . . . . . . . . . . . . . . . Suite\n");
  1378. //
  1379. // Make sure we can set nothing
  1380. //
  1381. printf(" Set Nothing . . . . . . . . . . . . . . . . . . . . . ");
  1382. SI1 = 0;
  1383. SD1 = &SD1_Body;
  1384. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1385. ASSERT( NT_SUCCESS(NtStatus) );
  1386. NtStatus = SamSetSecurityObject(
  1387. DomainHandle,
  1388. SI1, // <------ This is invalid
  1389. SD1
  1390. );
  1391. if (NtStatus == STATUS_INVALID_PARAMETER) {
  1392. printf("Succeeded\n");
  1393. } else {
  1394. printf("Failed\n");
  1395. printf(" Completion status is 0x%lx\n", NtStatus);
  1396. TestStatus = FALSE;
  1397. }
  1398. //
  1399. // set something not passed
  1400. //
  1401. printf(" Set something not passed. . . . . . . . . . . . . . . ");
  1402. SI1 = GROUP_SECURITY_INFORMATION;
  1403. SD1 = &SD1_Body;
  1404. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1405. ASSERT( NT_SUCCESS(NtStatus) );
  1406. NtStatus = SamSetSecurityObject(
  1407. DomainHandle,
  1408. SI1,
  1409. SD1
  1410. );
  1411. if (NtStatus == STATUS_BAD_DESCRIPTOR_FORMAT) {
  1412. printf("Succeeded\n");
  1413. } else {
  1414. printf("Failed\n");
  1415. printf(" Completion status is 0x%lx\n", NtStatus);
  1416. TestStatus = FALSE;
  1417. }
  1418. //
  1419. // set a non-existant DACL
  1420. //
  1421. if (AdminsAliasTest) {
  1422. printf(" Set non-existant DACL (Server object) . . . . . . . . ");
  1423. SI1 = DACL_SECURITY_INFORMATION;
  1424. SD1 = &SD1_Body;
  1425. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1426. SD1_Body.Control = SE_DACL_PRESENT;
  1427. ASSERT( NT_SUCCESS(NtStatus) );
  1428. NtStatus = SamSetSecurityObject(
  1429. ServerHandle,
  1430. SI1,
  1431. SD1
  1432. );
  1433. if (NT_SUCCESS(NtStatus)) {
  1434. printf("Succeeded\n");
  1435. } else {
  1436. printf("Failed\n");
  1437. printf(" Completion status is 0x%lx\n", NtStatus);
  1438. TestStatus = FALSE;
  1439. }
  1440. }
  1441. if (AdminsAliasTest) {
  1442. printf(" Set non-existant DACL (Domain Object) . . . . . . . . ");
  1443. SI1 = DACL_SECURITY_INFORMATION;
  1444. SD1 = &SD1_Body;
  1445. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1446. SD1_Body.Control = SE_DACL_PRESENT;
  1447. ASSERT( NT_SUCCESS(NtStatus) );
  1448. NtStatus = SamSetSecurityObject(
  1449. DomainHandle,
  1450. SI1,
  1451. SD1
  1452. );
  1453. if (NT_SUCCESS(NtStatus)) {
  1454. printf("Succeeded\n");
  1455. } else {
  1456. printf("Failed\n");
  1457. printf(" Completion status is 0x%lx\n", NtStatus);
  1458. TestStatus = FALSE;
  1459. }
  1460. }
  1461. //
  1462. // set original DACL (From original SD)
  1463. //
  1464. if (AdminsAliasTest) {
  1465. printf(" Set original DACL (Server Object) . . . . . . . . . . ");
  1466. SI1 = DACL_SECURITY_INFORMATION;
  1467. SD1 = OriginalServerSD;
  1468. NtStatus = SamSetSecurityObject(
  1469. ServerHandle,
  1470. SI1,
  1471. SD1
  1472. );
  1473. if (NT_SUCCESS(NtStatus)) {
  1474. printf("Succeeded\n");
  1475. } else {
  1476. printf("Failed\n");
  1477. printf(" Completion status is 0x%lx\n", NtStatus);
  1478. TestStatus = FALSE;
  1479. }
  1480. }
  1481. if (AdminsAliasTest) {
  1482. printf(" Set original DACL (Domain Object) . . . . . . . . . . ");
  1483. SI1 = DACL_SECURITY_INFORMATION;
  1484. SD1 = OriginalDomainSD;
  1485. NtStatus = SamSetSecurityObject(
  1486. DomainHandle,
  1487. SI1,
  1488. SD1
  1489. );
  1490. if (NT_SUCCESS(NtStatus)) {
  1491. printf("Succeeded\n");
  1492. } else {
  1493. printf("Failed\n");
  1494. printf(" Completion status is 0x%lx\n", NtStatus);
  1495. TestStatus = FALSE;
  1496. }
  1497. }
  1498. if (AdminsAliasTest) {
  1499. //
  1500. // set a non-existant SACL
  1501. //
  1502. printf(" Set non-existant SACL . . . . . . . . . . . . . . . . ");
  1503. SI1 = SACL_SECURITY_INFORMATION;
  1504. SD1 = &SD1_Body;
  1505. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1506. SD1_Body.Control = SE_SACL_PRESENT;
  1507. ASSERT( NT_SUCCESS(NtStatus) );
  1508. NtStatus = SamSetSecurityObject(
  1509. DomainHandle,
  1510. SI1,
  1511. SD1
  1512. );
  1513. if (NT_SUCCESS(NtStatus)) {
  1514. printf("Succeeded\n");
  1515. } else {
  1516. printf("Failed\n");
  1517. printf(" Completion status is 0x%lx\n", NtStatus);
  1518. TestStatus = FALSE;
  1519. }
  1520. //
  1521. // set original SACL (From original SD)
  1522. //
  1523. printf(" Set original SACL . . . . . . . . . . . . . . . . . . ");
  1524. SI1 = SACL_SECURITY_INFORMATION;
  1525. SD1 = OriginalDomainSD;
  1526. NtStatus = SamSetSecurityObject(
  1527. DomainHandle,
  1528. SI1,
  1529. SD1
  1530. );
  1531. if (NT_SUCCESS(NtStatus)) {
  1532. printf("Succeeded\n");
  1533. } else {
  1534. printf("Failed\n");
  1535. printf(" Completion status is 0x%lx\n", NtStatus);
  1536. TestStatus = FALSE;
  1537. }
  1538. //
  1539. // set a owner to null
  1540. //
  1541. printf(" Set null Owner . . . . . . . . . . . . . . . . . . . ");
  1542. SI1 = OWNER_SECURITY_INFORMATION;
  1543. SD1 = &SD1_Body;
  1544. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1545. SD1_Body.Owner = NULL;
  1546. ASSERT( NT_SUCCESS(NtStatus) );
  1547. NtStatus = SamSetSecurityObject(
  1548. DomainHandle,
  1549. SI1,
  1550. SD1
  1551. );
  1552. if (NtStatus = STATUS_BAD_DESCRIPTOR_FORMAT) {
  1553. printf("Succeeded\n");
  1554. } else {
  1555. printf("Failed\n");
  1556. printf(" Completion status is 0x%lx\n", NtStatus);
  1557. TestStatus = FALSE;
  1558. }
  1559. //
  1560. // set owner to invalid value
  1561. //
  1562. printf(" Set owner to invalid value . . . . . . . . . . . . . ");
  1563. SI1 = OWNER_SECURITY_INFORMATION;
  1564. SD1 = &SD1_Body;
  1565. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1566. SD1_Body.Owner = WorldSid;
  1567. ASSERT( NT_SUCCESS(NtStatus) );
  1568. NtStatus = SamSetSecurityObject(
  1569. DomainHandle,
  1570. SI1,
  1571. SD1
  1572. );
  1573. if (NtStatus = STATUS_INVALID_OWNER) {
  1574. printf("Succeeded\n");
  1575. } else {
  1576. printf("Failed\n");
  1577. printf(" Completion status is 0x%lx\n", NtStatus);
  1578. TestStatus = FALSE;
  1579. }
  1580. //
  1581. // set a owner to valid value
  1582. //
  1583. printf(" Set owner to valid value . . . . . . . . . . . . . . ");
  1584. printf("Untested\n");
  1585. //
  1586. // set group to null
  1587. //
  1588. printf(" Set null Group . . . . . . . . . . . . . . . . . . . ");
  1589. SI1 = GROUP_SECURITY_INFORMATION;
  1590. SD1 = &SD1_Body;
  1591. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1592. SD1_Body.Group = NULL;
  1593. ASSERT( NT_SUCCESS(NtStatus) );
  1594. NtStatus = SamSetSecurityObject(
  1595. DomainHandle,
  1596. SI1,
  1597. SD1
  1598. );
  1599. if (NtStatus = STATUS_BAD_DESCRIPTOR_FORMAT) {
  1600. printf("Succeeded\n");
  1601. } else {
  1602. printf("Failed\n");
  1603. printf(" Completion status is 0x%lx\n", NtStatus);
  1604. TestStatus = FALSE;
  1605. }
  1606. //
  1607. // set Group to valid value
  1608. //
  1609. printf(" Set Group to valid value . . . . . . . . . . . . . . ");
  1610. SI1 = GROUP_SECURITY_INFORMATION;
  1611. SD1 = &SD1_Body;
  1612. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1613. SD1_Body.Group = WorldSid;
  1614. ASSERT( NT_SUCCESS(NtStatus) );
  1615. NtStatus = SamSetSecurityObject(
  1616. DomainHandle,
  1617. SI1,
  1618. SD1
  1619. );
  1620. if (NT_SUCCESS(NtStatus)) {
  1621. printf("Succeeded\n");
  1622. } else {
  1623. printf("Failed\n");
  1624. printf(" Completion status is 0x%lx\n", NtStatus);
  1625. TestStatus = FALSE;
  1626. }
  1627. //
  1628. // set Group back to original value
  1629. //
  1630. printf(" Set Group to original value . . . . . . . . . . . . . ");
  1631. SI1 = GROUP_SECURITY_INFORMATION;
  1632. SD1 = OriginalDomainSD;
  1633. NtStatus = SamSetSecurityObject(
  1634. DomainHandle,
  1635. SI1,
  1636. SD1
  1637. );
  1638. if (NT_SUCCESS(NtStatus)) {
  1639. printf("Succeeded\n");
  1640. } else {
  1641. printf("Failed\n");
  1642. printf(" Completion status is 0x%lx\n", NtStatus);
  1643. TestStatus = FALSE;
  1644. }
  1645. }
  1646. } // end Pass1
  1647. if (Pass == 2) {
  1648. ACCESS_MASK AccessMask;
  1649. PSID_NAME_USE LookedUpUses;
  1650. PULONG LookedUpRids;
  1651. UNICODE_STRING AccountNames[10];
  1652. STRING AccountNameAnsi;
  1653. //
  1654. // This pass depends upon user and group accounts established in pass #1
  1655. //
  1656. if (AdminsAliasTest) {
  1657. printf(" Security Manipulation (Pass #2) Test\n");
  1658. ///////////////////////////////////////////////////////////////////////////
  1659. // //
  1660. // Query Suite //
  1661. // //
  1662. ///////////////////////////////////////////////////////////////////////////
  1663. printf("\n");
  1664. printf(" Query Security (User Object). . . . . . . . . . . . . Suite\n");
  1665. AccessMask = READ_CONTROL;
  1666. if (SecurityOperatorTest) {
  1667. AccessMask |= ACCESS_SYSTEM_SECURITY;
  1668. }
  1669. //
  1670. // Open the user created in pass #1
  1671. //
  1672. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  1673. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  1674. TST_SUCCESS_ASSERT(NtStatus);
  1675. NtStatus = SamLookupNamesInDomain(
  1676. DomainHandle,
  1677. 1,
  1678. &AccountNames[0],
  1679. &LookedUpRids,
  1680. &LookedUpUses
  1681. );
  1682. RtlFreeUnicodeString( &AccountNames[0] );
  1683. TST_SUCCESS_ASSERT(NtStatus);
  1684. ASSERT(LookedUpUses[0] == SidTypeUser);
  1685. NtStatus = SamOpenUser(
  1686. DomainHandle,
  1687. AccessMask,
  1688. LookedUpRids[0],
  1689. &UserHandle);
  1690. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  1691. if (!NT_SUCCESS(NtStatus)) {
  1692. printf("Failed to open user account created in pass #1\n");
  1693. }
  1694. TST_SUCCESS_ASSERT(NT_SUCCESS(NtStatus));
  1695. //
  1696. // Get user's original SD
  1697. //
  1698. SI1 |= OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  1699. DACL_SECURITY_INFORMATION;
  1700. if (SecurityOperatorTest) {
  1701. SI1 |= SACL_SECURITY_INFORMATION;
  1702. }
  1703. printf(" Query User Security Descriptor . . . . . . . . . . . ");
  1704. SD1 = NULL;
  1705. NtStatus = SamQuerySecurityObject(
  1706. UserHandle,
  1707. SI1,
  1708. &SD1
  1709. );
  1710. if (NT_SUCCESS(NtStatus)) {
  1711. TestStatus = CheckReturnedSD( SI1, SD1, TRUE );
  1712. //
  1713. // Normally we would do a "SamFreeMemory( SD1 )" here.
  1714. // However, we want to save this SD for future reference
  1715. // and use.
  1716. //
  1717. OriginalUserSD = SD1;
  1718. } else {
  1719. printf("Failed\n");
  1720. printf(" Completion status is 0x%lx\n", NtStatus);
  1721. TestStatus = FALSE;
  1722. }
  1723. NtStatus = SamCloseHandle( UserHandle );
  1724. TST_SUCCESS_ASSERT( UserHandle );
  1725. ///////////////////////////////////////////////////////////////////////////
  1726. // //
  1727. // Set Suite //
  1728. // //
  1729. ///////////////////////////////////////////////////////////////////////////
  1730. printf("\n");
  1731. printf(" Set Security (User Object) . . . . . . . . . . . . . Suite\n");
  1732. AccessMask = WRITE_DAC | WRITE_OWNER;
  1733. if (SecurityOperatorTest) {
  1734. AccessMask |= ACCESS_SYSTEM_SECURITY;
  1735. }
  1736. //
  1737. // Open the user created in pass #1
  1738. //
  1739. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  1740. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  1741. TST_SUCCESS_ASSERT(NtStatus);
  1742. NtStatus = SamLookupNamesInDomain(
  1743. DomainHandle,
  1744. 1,
  1745. &AccountNames[0],
  1746. &LookedUpRids,
  1747. &LookedUpUses
  1748. );
  1749. RtlFreeUnicodeString( &AccountNames[0] );
  1750. TST_SUCCESS_ASSERT(NtStatus);
  1751. ASSERT(LookedUpUses[0] == SidTypeUser);
  1752. NtStatus = SamOpenUser(
  1753. DomainHandle,
  1754. AccessMask,
  1755. LookedUpRids[0],
  1756. &UserHandle);
  1757. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  1758. if (!NT_SUCCESS(NtStatus)) {
  1759. printf("Failed to open user account created in pass #1\n");
  1760. }
  1761. TST_SUCCESS_ASSERT(NT_SUCCESS(NtStatus));
  1762. //
  1763. // Make sure we can set nothing
  1764. //
  1765. printf(" Set Nothing . . . . . . . . . . . . . . . . . . . . . ");
  1766. SI1 = 0;
  1767. SD1 = &SD1_Body;
  1768. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1769. ASSERT( NT_SUCCESS(NtStatus) );
  1770. NtStatus = SamSetSecurityObject(
  1771. UserHandle,
  1772. SI1, // <------ This is invalid
  1773. SD1
  1774. );
  1775. if (NtStatus == STATUS_INVALID_PARAMETER) {
  1776. printf("Succeeded\n");
  1777. } else {
  1778. printf("Failed\n");
  1779. printf(" Completion status is 0x%lx\n", NtStatus);
  1780. TestStatus = FALSE;
  1781. }
  1782. //
  1783. // set something not passed
  1784. //
  1785. printf(" Set something not passed. . . . . . . . . . . . . . . ");
  1786. SI1 = GROUP_SECURITY_INFORMATION;
  1787. SD1 = &SD1_Body;
  1788. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1789. ASSERT( NT_SUCCESS(NtStatus) );
  1790. NtStatus = SamSetSecurityObject(
  1791. UserHandle,
  1792. SI1,
  1793. SD1
  1794. );
  1795. if (NtStatus == STATUS_BAD_DESCRIPTOR_FORMAT) {
  1796. printf("Succeeded\n");
  1797. } else {
  1798. printf("Failed\n");
  1799. printf(" Completion status is 0x%lx\n", NtStatus);
  1800. TestStatus = FALSE;
  1801. }
  1802. printf(" Set non-existant DACL . . . . . . . . . . . . . . . . ");
  1803. SI1 = DACL_SECURITY_INFORMATION;
  1804. SD1 = &SD1_Body;
  1805. NtStatus = RtlCreateSecurityDescriptor( SD1, SECURITY_DESCRIPTOR_REVISION1 );
  1806. SD1_Body.Control = SE_DACL_PRESENT;
  1807. ASSERT( NT_SUCCESS(NtStatus) );
  1808. NtStatus = SamSetSecurityObject(
  1809. UserHandle,
  1810. SI1,
  1811. SD1
  1812. );
  1813. if (NT_SUCCESS(NtStatus)) {
  1814. printf("Succeeded\n");
  1815. } else {
  1816. printf("Failed\n");
  1817. printf(" Completion status is 0x%lx\n", NtStatus);
  1818. TestStatus = FALSE;
  1819. }
  1820. //
  1821. // set original DACL (From original SD)
  1822. //
  1823. printf(" Set original DACL . . . . . . . . . . . . . . . . . . ");
  1824. SI1 = DACL_SECURITY_INFORMATION;
  1825. SD1 = OriginalUserSD;
  1826. NtStatus = SamSetSecurityObject(
  1827. UserHandle,
  1828. SI1,
  1829. SD1
  1830. );
  1831. if (NT_SUCCESS(NtStatus)) {
  1832. printf("Succeeded\n");
  1833. } else {
  1834. printf("Failed\n");
  1835. printf(" Completion status is 0x%lx\n", NtStatus);
  1836. TestStatus = FALSE;
  1837. }
  1838. NtStatus = SamCloseHandle( UserHandle );
  1839. TST_SUCCESS_ASSERT( UserHandle );
  1840. }
  1841. DBG_UNREFERENCED_LOCAL_VARIABLE( GroupHandle );
  1842. DBG_UNREFERENCED_LOCAL_VARIABLE( OriginalGroupSD );
  1843. }
  1844. return TestStatus;
  1845. }
  1846. BOOLEAN
  1847. CheckReturnedSD(
  1848. IN SECURITY_INFORMATION SI,
  1849. IN PSECURITY_DESCRIPTOR SD,
  1850. IN BOOLEAN PrintTestSuccess
  1851. )
  1852. {
  1853. NTSTATUS NtStatus;
  1854. BOOLEAN Failed = FALSE,
  1855. IgnoreBoolean,
  1856. AclPresent,
  1857. TestStatus = TRUE;
  1858. PSID SID;
  1859. PACL ACL;
  1860. //
  1861. // Check a returned security descriptor agains the information requested.
  1862. //
  1863. if (SD == NULL) {
  1864. TestStatus = FALSE;
  1865. if (PrintTestSuccess) {
  1866. printf("Failed\n");
  1867. Failed = TRUE;
  1868. printf(" The SecurityDescriptor return address was not properly\n");
  1869. printf(" set.\n");
  1870. }
  1871. }
  1872. if (TestStatus) {
  1873. //
  1874. // Check owner
  1875. //
  1876. NtStatus = RtlGetOwnerSecurityDescriptor ( SD, &SID, &IgnoreBoolean);
  1877. ASSERT(NT_SUCCESS(NtStatus));
  1878. if (SI & OWNER_SECURITY_INFORMATION) {
  1879. if (SID == NULL) {
  1880. if (PrintTestSuccess) {
  1881. if (!Failed) {
  1882. printf("Failed\n");
  1883. printf(" Security descriptor address is 0x%lx\n", SD );
  1884. Failed = TRUE;
  1885. }
  1886. printf(" An owner was requested but the owner field of the\n");
  1887. printf(" security descriptor is not set.\n");
  1888. TestStatus = FALSE;
  1889. }
  1890. }
  1891. } else { // Owner not specified
  1892. if (SID != NULL) {
  1893. if (PrintTestSuccess) {
  1894. if (!Failed) {
  1895. printf("Failed\n");
  1896. printf(" Security descriptor address is 0x%lx\n", SD );
  1897. Failed = TRUE;
  1898. }
  1899. printf(" An owner was not requested but the owner field of the\n");
  1900. printf(" security descriptor is set.\n");
  1901. TestStatus = FALSE;
  1902. }
  1903. }
  1904. }
  1905. //
  1906. // Check group
  1907. //
  1908. NtStatus = RtlGetGroupSecurityDescriptor ( SD, &SID, &IgnoreBoolean);
  1909. ASSERT(NT_SUCCESS(NtStatus));
  1910. if (SI & GROUP_SECURITY_INFORMATION) {
  1911. if (SID == NULL) {
  1912. if (PrintTestSuccess) {
  1913. if (!Failed) {
  1914. printf("Failed\n");
  1915. printf(" Security descriptor address is 0x%lx\n", SD );
  1916. Failed = TRUE;
  1917. }
  1918. printf(" A group was requested but the group field of the\n");
  1919. printf(" security descriptor is not set.\n");
  1920. TestStatus = FALSE;
  1921. }
  1922. }
  1923. } else { // Group not specified
  1924. if (SID != NULL) {
  1925. if (PrintTestSuccess) {
  1926. if (!Failed) {
  1927. printf("Failed\n");
  1928. printf(" Security descriptor address is 0x%lx\n", SD );
  1929. Failed = TRUE;
  1930. }
  1931. printf(" A group was not requested but the group field of the\n");
  1932. printf(" security descriptor is set.\n");
  1933. TestStatus = FALSE;
  1934. }
  1935. }
  1936. }
  1937. //
  1938. // Check sacl
  1939. //
  1940. NtStatus = RtlGetSaclSecurityDescriptor ( SD, &AclPresent, &ACL, &IgnoreBoolean);
  1941. ASSERT(NT_SUCCESS(NtStatus));
  1942. if (SI & SACL_SECURITY_INFORMATION) {
  1943. if (!AclPresent) {
  1944. if (PrintTestSuccess) {
  1945. if (!Failed) {
  1946. printf("Failed\n");
  1947. printf(" Security descriptor address is 0x%lx\n", SD );
  1948. Failed = TRUE;
  1949. }
  1950. printf(" An SACL was requested but the SaclPresent flag\n");
  1951. printf(" of the security descriptor is not set.\n");
  1952. TestStatus = FALSE;
  1953. }
  1954. }
  1955. } else { // sacl not specified
  1956. if (AclPresent) {
  1957. if (PrintTestSuccess) {
  1958. if (!Failed) {
  1959. printf("Failed\n");
  1960. printf(" Security descriptor address is 0x%lx\n", SD );
  1961. Failed = TRUE;
  1962. }
  1963. printf(" An SACL was not requested but the SaclPresent flag\n");
  1964. printf(" of the security descriptor is set.\n");
  1965. TestStatus = FALSE;
  1966. }
  1967. }
  1968. }
  1969. //
  1970. // Check Dacl
  1971. //
  1972. NtStatus = RtlGetDaclSecurityDescriptor ( SD, &AclPresent, &ACL, &IgnoreBoolean);
  1973. ASSERT(NT_SUCCESS(NtStatus));
  1974. if (SI & DACL_SECURITY_INFORMATION) {
  1975. if (!AclPresent) {
  1976. if (PrintTestSuccess) {
  1977. if (!Failed) {
  1978. printf("Failed\n");
  1979. printf(" Security descriptor address is 0x%lx\n", SD );
  1980. Failed = TRUE;
  1981. }
  1982. printf(" A DACL was requested but the DaclPresent flag\n");
  1983. printf(" of the security descriptor is not set.\n");
  1984. TestStatus = FALSE;
  1985. }
  1986. }
  1987. } else { // Dacl not specified
  1988. if (AclPresent) {
  1989. if (PrintTestSuccess) {
  1990. if (!Failed) {
  1991. printf("Failed\n");
  1992. printf(" Security descriptor address is 0x%lx\n", SD );
  1993. Failed = TRUE;
  1994. }
  1995. printf(" A DACL was not requested but the DaclPresent flag\n");
  1996. printf(" of the security descriptor is set.\n");
  1997. TestStatus = FALSE;
  1998. }
  1999. }
  2000. }
  2001. }
  2002. if (PrintTestSuccess) {
  2003. if (TestStatus) {
  2004. printf("Succeeded\n");
  2005. }
  2006. }
  2007. return(TestStatus);
  2008. }
  2009. ///////////////////////////////////////////////////////////////////////////////
  2010. // //
  2011. // Domain Object Test Suite //
  2012. // //
  2013. ///////////////////////////////////////////////////////////////////////////////
  2014. BOOLEAN
  2015. DomainTestSuite(
  2016. HANDLE DomainHandle
  2017. )
  2018. {
  2019. BOOLEAN TestStatus = TRUE;
  2020. NTSTATUS NtStatus, IgnoreStatus;
  2021. PVOID Buffer, Buffer1, Buffer2;
  2022. CHAR UnusedBuffer[20];
  2023. UNICODE_STRING AccountName;
  2024. STRING AccountNameAnsi;
  2025. HANDLE GroupHandle = NULL;
  2026. HANDLE AliasHandle = NULL;
  2027. HANDLE UserHandle = NULL;
  2028. HANDLE ValidUserHandle = NULL;
  2029. ULONG GroupRid, AliasRid, UserRid, SavedGroupRid, SavedAliasRid, AccountCount, i;
  2030. SAM_ENUMERATE_HANDLE EnumerationContext;
  2031. ULONG CountReturned;
  2032. USHORT NameLength;
  2033. PUNICODE_STRING LookedUpNames;
  2034. PSID_NAME_USE LookedUpUses;
  2035. PULONG LookedUpRids;
  2036. printf("\n");
  2037. printf("\n");
  2038. printf("\n");
  2039. printf(" Domain Test\n");
  2040. ///////////////////////////////////////////////////////////////////////////
  2041. // //
  2042. // Query Suite //
  2043. // //
  2044. ///////////////////////////////////////////////////////////////////////////
  2045. printf("\n");
  2046. printf(" Query Information . . . . . . . . . . . . . . . . . . Suite\n");
  2047. //
  2048. // Make sure the wrapper doesn't choke on a non-null pointer being passed
  2049. // (assuming we have allocated memory).
  2050. //
  2051. printf(" Query Buffer Allocation Test . . . . . . . . . . . . ");
  2052. Buffer = &UnusedBuffer[0];
  2053. NtStatus = SamQueryInformationDomain(
  2054. DomainHandle,
  2055. DomainStateInformation,
  2056. &Buffer
  2057. );
  2058. if (NT_SUCCESS(NtStatus)) {
  2059. if (Buffer != &UnusedBuffer[0]) {
  2060. if (Buffer != NULL) {
  2061. printf("Succeeded\n");
  2062. SamFreeMemory( Buffer );
  2063. } else {
  2064. printf("Failed\n");
  2065. printf(" Buffer address not set on return.\n");
  2066. printf(" RPC should have allocated a buffer.\n");
  2067. TestStatus = FALSE;
  2068. }
  2069. } else {
  2070. printf("Failed\n");
  2071. printf(" Passed buffer address used on return.\n");
  2072. printf(" RPC should have allocated another buffer.\n");
  2073. TestStatus = FALSE;
  2074. }
  2075. } else {
  2076. printf("Failed\n");
  2077. printf(" Completion status is 0x%lx\n", NtStatus);
  2078. TestStatus = FALSE;
  2079. }
  2080. //
  2081. // Query all the fixed length info levels
  2082. // Query - Password, Logoff, ServerRole, DomainState, ModifiedCount, LockoutInfo
  2083. //
  2084. printf(" Query DomainState . . . . . . . . . . . . . . . . . . ");
  2085. NtStatus = SamQueryInformationDomain(
  2086. DomainHandle,
  2087. DomainStateInformation,
  2088. &Buffer
  2089. );
  2090. if (NT_SUCCESS(NtStatus)) {
  2091. if (Buffer != NULL) {
  2092. printf("Succeeded\n");
  2093. SamFreeMemory( Buffer );
  2094. } else {
  2095. printf("Failed\n");
  2096. printf(" Buffer address not set on return.\n");
  2097. printf(" RPC should have allocated a buffer.\n");
  2098. TestStatus = FALSE;
  2099. }
  2100. } else {
  2101. printf("Failed\n");
  2102. printf(" Completion status is 0x%lx\n", NtStatus);
  2103. TestStatus = FALSE;
  2104. }
  2105. printf(" Query ServerRole . . . . . . . . . . . . . . . . . . ");
  2106. NtStatus = SamQueryInformationDomain(
  2107. DomainHandle,
  2108. DomainServerRoleInformation,
  2109. &Buffer
  2110. );
  2111. if (NT_SUCCESS(NtStatus)) {
  2112. if (Buffer != NULL) {
  2113. printf("Succeeded\n");
  2114. SamFreeMemory( Buffer );
  2115. } else {
  2116. printf("Failed\n");
  2117. printf(" Buffer address not set on return.\n");
  2118. printf(" RPC should have allocated a buffer.\n");
  2119. TestStatus = FALSE;
  2120. }
  2121. } else {
  2122. printf("Failed\n");
  2123. printf(" Completion status is 0x%lx\n", NtStatus);
  2124. TestStatus = FALSE;
  2125. }
  2126. printf(" Query Password Information . . . . . . . . . . . . . ");
  2127. NtStatus = SamQueryInformationDomain(
  2128. DomainHandle,
  2129. DomainPasswordInformation,
  2130. &Buffer
  2131. );
  2132. if (NT_SUCCESS(NtStatus)) {
  2133. if (Buffer != NULL) {
  2134. printf("Succeeded\n");
  2135. SamFreeMemory( Buffer );
  2136. } else {
  2137. printf("Failed\n");
  2138. printf(" Buffer address not set on return.\n");
  2139. printf(" RPC should have allocated a buffer.\n");
  2140. TestStatus = FALSE;
  2141. }
  2142. } else {
  2143. printf("Failed\n");
  2144. printf(" Completion status is 0x%lx\n", NtStatus);
  2145. TestStatus = FALSE;
  2146. }
  2147. printf(" Query Logoff Information . . . . . . . . . . . . . . ");
  2148. NtStatus = SamQueryInformationDomain(
  2149. DomainHandle,
  2150. DomainLogoffInformation,
  2151. &Buffer
  2152. );
  2153. if (NT_SUCCESS(NtStatus)) {
  2154. if (Buffer != NULL) {
  2155. printf("Succeeded\n");
  2156. SamFreeMemory( Buffer );
  2157. } else {
  2158. printf("Failed\n");
  2159. printf(" Buffer address not set on return.\n");
  2160. printf(" RPC should have allocated a buffer.\n");
  2161. TestStatus = FALSE;
  2162. }
  2163. } else {
  2164. printf("Failed\n");
  2165. printf(" Completion status is 0x%lx\n", NtStatus);
  2166. TestStatus = FALSE;
  2167. }
  2168. printf(" Query Modified . . . . . . . . . . . . . . . . . . . ");
  2169. NtStatus = SamQueryInformationDomain(
  2170. DomainHandle,
  2171. DomainModifiedInformation,
  2172. &Buffer
  2173. );
  2174. if (NT_SUCCESS(NtStatus)) {
  2175. if (Buffer != NULL) {
  2176. printf("Succeeded\n");
  2177. SamFreeMemory( Buffer );
  2178. } else {
  2179. printf("Failed\n");
  2180. printf(" Buffer address not set on return.\n");
  2181. printf(" RPC should have allocated a buffer.\n");
  2182. TestStatus = FALSE;
  2183. }
  2184. } else {
  2185. printf("Failed\n");
  2186. printf(" Completion status is 0x%lx\n", NtStatus);
  2187. TestStatus = FALSE;
  2188. }
  2189. printf(" Query Lockout . . . . . . . . . . . . . . . . . . . . ");
  2190. NtStatus = SamQueryInformationDomain(
  2191. DomainHandle,
  2192. DomainLockoutInformation,
  2193. &Buffer
  2194. );
  2195. if (NT_SUCCESS(NtStatus)) {
  2196. if (Buffer != NULL) {
  2197. printf("Succeeded\n");
  2198. SamFreeMemory( Buffer );
  2199. } else {
  2200. printf("Failed\n");
  2201. printf(" Buffer address not set on return.\n");
  2202. printf(" RPC should have allocated a buffer.\n");
  2203. TestStatus = FALSE;
  2204. }
  2205. } else {
  2206. printf("Failed\n");
  2207. printf(" Completion status is 0x%lx\n", NtStatus);
  2208. TestStatus = FALSE;
  2209. }
  2210. //
  2211. // Query the name of the domain ...
  2212. //
  2213. printf(" Query Domain Name . . . . . . . . . . . . . . . . . . ");
  2214. Buffer = NULL;
  2215. NtStatus = SamQueryInformationDomain(
  2216. DomainHandle,
  2217. DomainNameInformation,
  2218. &Buffer
  2219. );
  2220. if (NT_SUCCESS(NtStatus)) {
  2221. if (Buffer != NULL) {
  2222. if ( (((DOMAIN_NAME_INFORMATION *)Buffer)->DomainName.MaximumLength > 0) &&
  2223. (((DOMAIN_NAME_INFORMATION *)Buffer)->DomainName.Buffer != NULL) ) {
  2224. printf("Succeeded\n");
  2225. } else {
  2226. printf("Failed\n");
  2227. printf(" String body returned and allocated,\n");
  2228. printf(" but character buffer pointer is NULL.\n");
  2229. TestStatus = FALSE;
  2230. }
  2231. SamFreeMemory( Buffer );
  2232. } else {
  2233. printf("Failed\n");
  2234. printf(" Buffer address not set on return.\n");
  2235. printf(" RPC should have allocated a buffer.\n");
  2236. TestStatus = FALSE;
  2237. }
  2238. } else {
  2239. printf("Failed\n");
  2240. printf(" Completion status is 0x%lx\n", NtStatus);
  2241. TestStatus = FALSE;
  2242. }
  2243. //
  2244. // Query whatever is in the OEM Information field ...
  2245. //
  2246. printf(" Query OEM Information . . . . . . . . . . . . . . . . ");
  2247. Buffer = NULL;
  2248. NtStatus = SamQueryInformationDomain(
  2249. DomainHandle,
  2250. DomainOemInformation,
  2251. &Buffer
  2252. );
  2253. if (NT_SUCCESS(NtStatus)) {
  2254. if (Buffer != NULL) {
  2255. if ( (((DOMAIN_OEM_INFORMATION *)Buffer)->OemInformation.MaximumLength >= 0) &&
  2256. (((DOMAIN_OEM_INFORMATION *)Buffer)->OemInformation.Buffer != NULL) ) {
  2257. printf("Succeeded\n");
  2258. } else {
  2259. printf("Failed\n");
  2260. printf(" String body returned and allocated,\n");
  2261. printf(" but character buffer pointer is NULL.\n");
  2262. TestStatus = FALSE;
  2263. }
  2264. SamFreeMemory( Buffer );
  2265. } else {
  2266. printf("Failed\n");
  2267. printf(" Buffer address not set on return.\n");
  2268. printf(" RPC should have allocated a buffer.\n");
  2269. TestStatus = FALSE;
  2270. }
  2271. } else {
  2272. printf("Failed\n");
  2273. printf(" Completion status is 0x%lx\n", NtStatus);
  2274. TestStatus = FALSE;
  2275. }
  2276. //
  2277. // Query whatever is in the Replication Information field ...
  2278. //
  2279. printf(" Query Replication Information . . . . . . . . . . . . ");
  2280. Buffer = NULL;
  2281. NtStatus = SamQueryInformationDomain(
  2282. DomainHandle,
  2283. DomainReplicationInformation,
  2284. &Buffer
  2285. );
  2286. if (NT_SUCCESS(NtStatus)) {
  2287. if (Buffer != NULL) {
  2288. if ( (((DOMAIN_REPLICATION_INFORMATION *)Buffer)->ReplicaSourceNodeName.MaximumLength >= 0) &&
  2289. (((DOMAIN_REPLICATION_INFORMATION *)Buffer)->ReplicaSourceNodeName.Buffer != NULL) ) {
  2290. printf("Succeeded\n");
  2291. } else {
  2292. printf("Failed\n");
  2293. printf(" String body returned and allocated,\n");
  2294. printf(" but character buffer pointer is NULL.\n");
  2295. TestStatus = FALSE;
  2296. }
  2297. SamFreeMemory( Buffer );
  2298. } else {
  2299. printf("Failed\n");
  2300. printf(" Buffer address not set on return.\n");
  2301. printf(" RPC should have allocated a buffer.\n");
  2302. TestStatus = FALSE;
  2303. }
  2304. } else {
  2305. printf("Failed\n");
  2306. printf(" Completion status is 0x%lx\n", NtStatus);
  2307. TestStatus = FALSE;
  2308. }
  2309. //
  2310. // Query domain general Information...
  2311. //
  2312. printf(" Query General Information . . . . . . . . . . . . . . ");
  2313. Buffer = NULL;
  2314. NtStatus = SamQueryInformationDomain(
  2315. DomainHandle,
  2316. DomainGeneralInformation,
  2317. &Buffer
  2318. );
  2319. if (NT_SUCCESS(NtStatus)) {
  2320. if (Buffer != NULL) {
  2321. printf("Succeeded\n");
  2322. printf(" Number of Users is: 0x%lx\n",
  2323. ((DOMAIN_GENERAL_INFORMATION *)Buffer)->UserCount );
  2324. printf(" Number of groups is: 0x%lx\n",
  2325. ((DOMAIN_GENERAL_INFORMATION *)Buffer)->GroupCount);
  2326. printf(" Number of aliases is: 0x%lx\n",
  2327. ((DOMAIN_GENERAL_INFORMATION *)Buffer)->AliasCount);
  2328. SamFreeMemory( Buffer );
  2329. } else {
  2330. printf("Failed\n");
  2331. printf(" Buffer address not set on return.\n");
  2332. printf(" RPC should have allocated a buffer.\n");
  2333. TestStatus = FALSE;
  2334. }
  2335. } else {
  2336. printf("Failed\n");
  2337. printf(" Completion status is 0x%lx\n", NtStatus);
  2338. TestStatus = FALSE;
  2339. }
  2340. //
  2341. // Query domain general Information...
  2342. //
  2343. printf(" Query General Information 2 . . . . . . . . . . . . . ");
  2344. Buffer = NULL;
  2345. NtStatus = SamQueryInformationDomain(
  2346. DomainHandle,
  2347. DomainGeneralInformation2,
  2348. &Buffer
  2349. );
  2350. if (NT_SUCCESS(NtStatus)) {
  2351. if (Buffer != NULL) {
  2352. printf("Succeeded\n");
  2353. printf(" Number of Users is: 0x%lx\n",
  2354. ((DOMAIN_GENERAL_INFORMATION2 *)Buffer)->I1.UserCount );
  2355. printf(" Number of groups is: 0x%lx\n",
  2356. ((DOMAIN_GENERAL_INFORMATION2 *)Buffer)->I1.GroupCount);
  2357. printf(" Number of aliases is: 0x%lx\n",
  2358. ((DOMAIN_GENERAL_INFORMATION2 *)Buffer)->I1.AliasCount);
  2359. SamFreeMemory( Buffer );
  2360. } else {
  2361. printf("Failed\n");
  2362. printf(" Buffer address not set on return.\n");
  2363. printf(" RPC should have allocated a buffer.\n");
  2364. TestStatus = FALSE;
  2365. }
  2366. } else {
  2367. printf("Failed\n");
  2368. printf(" Completion status is 0x%lx\n", NtStatus);
  2369. TestStatus = FALSE;
  2370. }
  2371. ///////////////////////////////////////////////////////////////////////////
  2372. // //
  2373. // Set Suite //
  2374. // //
  2375. ///////////////////////////////////////////////////////////////////////////
  2376. printf(" Set Information . . . . . . . . . . . . . . . . . . . Suite\n");
  2377. //
  2378. // Set all the fixed length info levels
  2379. // - Password, Logoff, ServerRole, DomainState, ModifiedCount
  2380. //
  2381. /*
  2382. * CANT TEST SERVER STATE SETTING WITHOUT BREAKING THE REST OF THE TEST.
  2383. * THE REASON IS, ONCE THE STATE IS CHANGED, NOTHING ELSE CAN BE DONE.
  2384. *
  2385. * printf(" Set DomainState . . . . . . . . . . . . . . . . . . . ");
  2386. *
  2387. * //
  2388. * // Get the current value...
  2389. * //
  2390. *
  2391. * NtStatus = SamQueryInformationDomain(
  2392. * DomainHandle,
  2393. * DomainStateInformation,
  2394. * &Buffer1
  2395. * );
  2396. * ASSERT( NT_SUCCESS(NtStatus) );
  2397. *
  2398. * //
  2399. * // Change the field to a new value and write it out.
  2400. * //
  2401. *
  2402. * if ( ((DOMAIN_STATE_INFORMATION *)Buffer1)->DomainServerState ==
  2403. * DomainServerEnabled ) {
  2404. * ((DOMAIN_STATE_INFORMATION *)Buffer1)->DomainServerState =
  2405. * DomainServerDisabled;
  2406. * } else {
  2407. * ((DOMAIN_STATE_INFORMATION *)Buffer1)->DomainServerState =
  2408. * DomainServerEnabled;
  2409. * }
  2410. *
  2411. * NtStatus = SamSetInformationDomain(
  2412. * DomainHandle,
  2413. * DomainStateInformation,
  2414. * Buffer1
  2415. * );
  2416. * if ( NT_SUCCESS(NtStatus) ) {
  2417. *
  2418. * //
  2419. * // Now check that the change was really made...
  2420. * //
  2421. *
  2422. * NtStatus = SamQueryInformationDomain(
  2423. * DomainHandle,
  2424. * DomainStateInformation,
  2425. * &Buffer2
  2426. * );
  2427. * ASSERT(NT_SUCCESS( NtStatus ) );
  2428. * if (((DOMAIN_STATE_INFORMATION *)Buffer1)->DomainServerState ==
  2429. * ((DOMAIN_STATE_INFORMATION *)Buffer2)->DomainServerState ) {
  2430. *
  2431. * printf("Succeeded\n");
  2432. *
  2433. * } else {
  2434. *
  2435. * printf("Failed\n");
  2436. * printf(" Value queried doesn't match value written\n");
  2437. * printf(" Value Written is 0x%lx\n",
  2438. * (ULONG)((DOMAIN_STATE_INFORMATION *)Buffer1)->DomainServerState);
  2439. * printf(" Value Retrieved is 0x%lx\n",
  2440. * (ULONG)((DOMAIN_STATE_INFORMATION *)Buffer2)->DomainServerState);
  2441. *
  2442. * TestStatus = FALSE;
  2443. *
  2444. * }
  2445. *
  2446. * SamFreeMemory( Buffer1 );
  2447. * SamFreeMemory( Buffer2 );
  2448. *
  2449. * } else {
  2450. * printf("Failed\n");
  2451. * printf(" Completion status is 0x%lx\n", NtStatus);
  2452. * TestStatus = FALSE;
  2453. * SamFreeMemory( Buffer1 );
  2454. *
  2455. * }
  2456. */
  2457. /*
  2458. * CANT TEST SERVER ROLE SETTING WITHOUT BREAKING THE REST OF THE TEST.
  2459. * THE REASON IS, ONCE THE ROLE IS SET TO BACKUP, NOTHING ELSE CAN BE
  2460. * SET.
  2461. *
  2462. * printf(" Set ServerRole . . . . . . . . . . . . . . . . . . . ");
  2463. *
  2464. * //
  2465. * // Get the current value...
  2466. * //
  2467. *
  2468. * NtStatus = SamQueryInformationDomain(
  2469. * DomainHandle,
  2470. * DomainServerRoleInformation,
  2471. * &Buffer1
  2472. * );
  2473. * ASSERT( NT_SUCCESS(NtStatus) );
  2474. *
  2475. * //
  2476. * // Change the field to a new value and write it out.
  2477. * //
  2478. *
  2479. * if ( ((DOMAIN_SERVER_ROLE_INFORMATION *)Buffer1)->DomainServerRole ==
  2480. * DomainServerRolePrimary ) {
  2481. * ((DOMAIN_SERVER_ROLE_INFORMATION *)Buffer1)->DomainServerRole =
  2482. * DomainServerRoleBackup;
  2483. * } else {
  2484. * ((DOMAIN_SERVER_ROLE_INFORMATION *)Buffer1)->DomainServerRole =
  2485. * DomainServerRolePrimary;
  2486. * }
  2487. *
  2488. * NtStatus = SamSetInformationDomain(
  2489. * DomainHandle,
  2490. * DomainServerRoleInformation,
  2491. * Buffer1
  2492. * );
  2493. * if ( NT_SUCCESS(NtStatus) ) {
  2494. *
  2495. * //
  2496. * // Now check that the change was really made...
  2497. * //
  2498. *
  2499. * NtStatus = SamQueryInformationDomain(
  2500. * DomainHandle,
  2501. * DomainServerRoleInformation,
  2502. * &Buffer2
  2503. * );
  2504. * ASSERT(NT_SUCCESS( NtStatus ) );
  2505. * if (((DOMAIN_SERVER_ROLE_INFORMATION *)Buffer1)->DomainServerRole ==
  2506. * ((DOMAIN_SERVER_ROLE_INFORMATION *)Buffer2)->DomainServerRole ) {
  2507. *
  2508. * printf("Succeeded\n");
  2509. *
  2510. * } else {
  2511. *
  2512. * printf("Failed\n");
  2513. * printf(" Value queried doesn't match value written\n");
  2514. * printf(" Value Written is 0x%lx\n",
  2515. * (ULONG)((DOMAIN_SERVER_ROLE_INFORMATION *)Buffer1)->DomainServerRole);
  2516. * printf(" Value Retrieved is 0x%lx\n",
  2517. * (ULONG)((DOMAIN_SERVER_ROLE_INFORMATION *)Buffer2)->DomainServerRole);
  2518. *
  2519. * TestStatus = FALSE;
  2520. *
  2521. * }
  2522. *
  2523. * SamFreeMemory( Buffer1 );
  2524. * SamFreeMemory( Buffer2 );
  2525. *
  2526. * } else {
  2527. * printf("Failed\n");
  2528. * printf(" Completion status is 0x%lx\n", NtStatus);
  2529. * TestStatus = FALSE;
  2530. * SamFreeMemory( Buffer1 );
  2531. *
  2532. * }
  2533. */
  2534. printf(" Set Password Information . . . . . . . . . . . . . . ");
  2535. //
  2536. // Get the current value...
  2537. //
  2538. NtStatus = SamQueryInformationDomain(
  2539. DomainHandle,
  2540. DomainPasswordInformation,
  2541. &Buffer1
  2542. );
  2543. ASSERT( NT_SUCCESS(NtStatus) );
  2544. //
  2545. // Change a field to a new value and write it out.
  2546. //
  2547. if ( ((DOMAIN_PASSWORD_INFORMATION *)Buffer1)->MinPasswordLength == 0 ) {
  2548. ((DOMAIN_PASSWORD_INFORMATION *)Buffer1)->MinPasswordLength = 6;
  2549. } else {
  2550. ((DOMAIN_PASSWORD_INFORMATION *)Buffer1)->MinPasswordLength = 0;
  2551. }
  2552. //
  2553. // Set PasswordProperties to COMPLEX so that tests run after this one
  2554. // are a little more interesting.
  2555. //
  2556. ((DOMAIN_PASSWORD_INFORMATION *)Buffer1)->PasswordProperties |= DOMAIN_PASSWORD_COMPLEX;
  2557. NtStatus = SamSetInformationDomain(
  2558. DomainHandle,
  2559. DomainPasswordInformation,
  2560. Buffer1
  2561. );
  2562. if ( NT_SUCCESS(NtStatus) ) {
  2563. //
  2564. // Now check that the change was really made...
  2565. //
  2566. NtStatus = SamQueryInformationDomain(
  2567. DomainHandle,
  2568. DomainPasswordInformation,
  2569. &Buffer2
  2570. );
  2571. ASSERT(NT_SUCCESS( NtStatus ) );
  2572. if (((DOMAIN_PASSWORD_INFORMATION *)Buffer1)->MinPasswordLength ==
  2573. ((DOMAIN_PASSWORD_INFORMATION *)Buffer2)->MinPasswordLength ) {
  2574. printf("Succeeded\n");
  2575. } else {
  2576. printf("Failed\n");
  2577. printf(" Value queried doesn't match value written\n");
  2578. printf(" Value Written is 0x%lx\n",
  2579. (ULONG)((DOMAIN_PASSWORD_INFORMATION *)Buffer1)->MinPasswordLength);
  2580. printf(" Value Retrieved is 0x%lx\n",
  2581. (ULONG)((DOMAIN_PASSWORD_INFORMATION *)Buffer2)->MinPasswordLength);
  2582. TestStatus = FALSE;
  2583. }
  2584. SamFreeMemory( Buffer1 );
  2585. SamFreeMemory( Buffer2 );
  2586. } else {
  2587. printf("Failed\n");
  2588. printf(" Completion status is 0x%lx\n", NtStatus);
  2589. TestStatus = FALSE;
  2590. SamFreeMemory( Buffer1 );
  2591. }
  2592. printf(" Set Logoff Information . . . . . . . . . . . . . . . ");
  2593. //
  2594. // Get the current value...
  2595. //
  2596. NtStatus = SamQueryInformationDomain(
  2597. DomainHandle,
  2598. DomainLogoffInformation,
  2599. &Buffer1
  2600. );
  2601. ASSERT( NT_SUCCESS(NtStatus) );
  2602. //
  2603. // Change the field to a new value and write it out.
  2604. //
  2605. if ( ((DOMAIN_LOGOFF_INFORMATION *)Buffer1)->ForceLogoff.LowPart == 0 ) {
  2606. ((DOMAIN_LOGOFF_INFORMATION *)Buffer1)->ForceLogoff.LowPart = 1000;
  2607. } else {
  2608. ((DOMAIN_LOGOFF_INFORMATION *)Buffer1)->ForceLogoff.LowPart = 0;
  2609. }
  2610. NtStatus = SamSetInformationDomain(
  2611. DomainHandle,
  2612. DomainLogoffInformation,
  2613. Buffer1
  2614. );
  2615. if ( NT_SUCCESS(NtStatus) ) {
  2616. //
  2617. // Now check that the change was really made...
  2618. //
  2619. NtStatus = SamQueryInformationDomain(
  2620. DomainHandle,
  2621. DomainLogoffInformation,
  2622. &Buffer2
  2623. );
  2624. ASSERT(NT_SUCCESS( NtStatus ) );
  2625. if (((DOMAIN_LOGOFF_INFORMATION *)Buffer1)->ForceLogoff.LowPart ==
  2626. ((DOMAIN_LOGOFF_INFORMATION *)Buffer2)->ForceLogoff.LowPart ) {
  2627. printf("Succeeded\n");
  2628. } else {
  2629. printf("Failed\n");
  2630. printf(" Value queried doesn't match value written\n");
  2631. printf(" Value Written is 0x%lx\n",
  2632. (ULONG)((DOMAIN_LOGOFF_INFORMATION *)Buffer1)->ForceLogoff.LowPart);
  2633. printf(" Value Retrieved is 0x%lx\n",
  2634. (ULONG)((DOMAIN_LOGOFF_INFORMATION *)Buffer2)->ForceLogoff.LowPart);
  2635. TestStatus = FALSE;
  2636. }
  2637. SamFreeMemory( Buffer1 );
  2638. SamFreeMemory( Buffer2 );
  2639. } else {
  2640. printf("Failed\n");
  2641. printf(" Completion status is 0x%lx\n", NtStatus);
  2642. TestStatus = FALSE;
  2643. SamFreeMemory( Buffer1 );
  2644. }
  2645. printf(" Set Modified . . . . . . . . . . . . . . . . . . . . ");
  2646. NtStatus = SamSetInformationDomain(
  2647. DomainHandle,
  2648. DomainModifiedInformation,
  2649. &LargeInteger1
  2650. );
  2651. if (NtStatus != STATUS_INVALID_INFO_CLASS) {
  2652. printf("Failed\n");
  2653. printf(" Completion status is 0x%lx\n", NtStatus);
  2654. TestStatus = FALSE;
  2655. } else {
  2656. printf("Succeeded\n");
  2657. }
  2658. printf(" Set Lockout Information . . . . . . . . . . . . . . . ");
  2659. //
  2660. // Get the current value...
  2661. //
  2662. NtStatus = SamQueryInformationDomain(
  2663. DomainHandle,
  2664. DomainLockoutInformation,
  2665. &Buffer1
  2666. );
  2667. ASSERT( NT_SUCCESS(NtStatus) );
  2668. //
  2669. // Change the field to a new value and write it out.
  2670. //
  2671. if ( ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutDuration.LowPart == 0 ) {
  2672. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutDuration.LowPart = 9000000;
  2673. } else {
  2674. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutDuration.LowPart = 0;
  2675. }
  2676. if ( ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutObservationWindow.LowPart == 0 ) {
  2677. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutObservationWindow.LowPart = 8000000;
  2678. } else {
  2679. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutObservationWindow.LowPart = 0;
  2680. }
  2681. if ( ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutThreshold == 0 ) {
  2682. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutThreshold = 2;
  2683. } else {
  2684. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutThreshold = 0;
  2685. }
  2686. NtStatus = SamSetInformationDomain(
  2687. DomainHandle,
  2688. DomainLockoutInformation,
  2689. Buffer1
  2690. );
  2691. if ( NT_SUCCESS(NtStatus) ) {
  2692. //
  2693. // Now check that the change was really made...
  2694. //
  2695. NtStatus = SamQueryInformationDomain(
  2696. DomainHandle,
  2697. DomainLockoutInformation,
  2698. &Buffer2
  2699. );
  2700. ASSERT(NT_SUCCESS( NtStatus ) );
  2701. if ( (((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutDuration.LowPart ==
  2702. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer2)->LockoutDuration.LowPart ) &&
  2703. (((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutObservationWindow.LowPart ==
  2704. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer2)->LockoutObservationWindow.LowPart ) &&
  2705. (((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutThreshold ==
  2706. ((DOMAIN_LOCKOUT_INFORMATION *)Buffer2)->LockoutThreshold ) ) {
  2707. printf("Succeeded\n");
  2708. } else {
  2709. printf("Failed\n");
  2710. printf(" Value queried doesn't match value written\n");
  2711. printf(" Duration Written is 0x%lx\n",
  2712. (ULONG)((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutDuration.LowPart);
  2713. printf(" Duration Retrieved is 0x%lx\n",
  2714. (ULONG)((DOMAIN_LOCKOUT_INFORMATION *)Buffer2)->LockoutDuration.LowPart);
  2715. printf(" Window Written is 0x%lx\n",
  2716. (ULONG)((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutObservationWindow.LowPart);
  2717. printf(" Window Retrieved is 0x%lx\n",
  2718. (ULONG)((DOMAIN_LOCKOUT_INFORMATION *)Buffer2)->LockoutObservationWindow.LowPart);
  2719. printf(" Duration Written is 0x%lx\n",
  2720. (ULONG)((DOMAIN_LOCKOUT_INFORMATION *)Buffer1)->LockoutThreshold);
  2721. printf(" Duration Retrieved is 0x%lx\n",
  2722. (ULONG)((DOMAIN_LOCKOUT_INFORMATION *)Buffer2)->LockoutThreshold);
  2723. TestStatus = FALSE;
  2724. }
  2725. SamFreeMemory( Buffer1 );
  2726. SamFreeMemory( Buffer2 );
  2727. } else {
  2728. printf("Failed\n");
  2729. printf(" Completion status is 0x%lx\n", NtStatus);
  2730. TestStatus = FALSE;
  2731. SamFreeMemory( Buffer1 );
  2732. }
  2733. printf(" Set Domain Name . . . . . . . . . . . . . . . . . . . ");
  2734. NtStatus = SamSetInformationDomain(
  2735. DomainHandle,
  2736. DomainNameInformation,
  2737. &DummyName1
  2738. );
  2739. if (NtStatus != STATUS_INVALID_INFO_CLASS) {
  2740. printf("Failed\n");
  2741. printf(" Completion status is 0x%lx\n", NtStatus);
  2742. TestStatus = FALSE;
  2743. } else {
  2744. printf("Succeeded\n");
  2745. }
  2746. printf(" Set OEM Information . . . . . . . . . . . . . . . . . ");
  2747. //
  2748. // Get the current value...
  2749. //
  2750. NtStatus = SamQueryInformationDomain(
  2751. DomainHandle,
  2752. DomainOemInformation,
  2753. &Buffer1
  2754. );
  2755. ASSERT( NT_SUCCESS(NtStatus) );
  2756. //
  2757. // Change the field to a new value and write it out.
  2758. //
  2759. NameLength = ((DOMAIN_OEM_INFORMATION *)Buffer1)->OemInformation.Length;
  2760. if ( NameLength == DummyName1.Length ) {
  2761. ((DOMAIN_OEM_INFORMATION *)Buffer1)->OemInformation = DummyName2;
  2762. } else {
  2763. ((DOMAIN_OEM_INFORMATION *)Buffer1)->OemInformation = DummyName1;
  2764. }
  2765. NtStatus = SamSetInformationDomain(
  2766. DomainHandle,
  2767. DomainOemInformation,
  2768. Buffer1
  2769. );
  2770. if ( NT_SUCCESS(NtStatus) ) {
  2771. //
  2772. // Now check that the change was really made...
  2773. //
  2774. NtStatus = SamQueryInformationDomain(
  2775. DomainHandle,
  2776. DomainOemInformation,
  2777. &Buffer2
  2778. );
  2779. ASSERT(NT_SUCCESS( NtStatus ) );
  2780. if (((DOMAIN_OEM_INFORMATION *)Buffer1)->OemInformation.Length ==
  2781. ((DOMAIN_OEM_INFORMATION *)Buffer2)->OemInformation.Length ) {
  2782. printf("Succeeded\n");
  2783. } else {
  2784. printf("Failed\n");
  2785. printf(" Value queried doesn't match value written\n");
  2786. printf(" Value Written is 0x%lx\n",
  2787. (ULONG)((DOMAIN_OEM_INFORMATION *)Buffer1)->OemInformation.Length);
  2788. printf(" Value Retrieved is 0x%lx\n",
  2789. (ULONG)((DOMAIN_OEM_INFORMATION *)Buffer2)->OemInformation.Length);
  2790. TestStatus = FALSE;
  2791. }
  2792. SamFreeMemory( Buffer1 );
  2793. SamFreeMemory( Buffer2 );
  2794. } else {
  2795. printf("Failed\n");
  2796. printf(" Completion status is 0x%lx\n", NtStatus);
  2797. TestStatus = FALSE;
  2798. SamFreeMemory( Buffer1 );
  2799. }
  2800. printf(" Set Replication Information . . . . . . . . . . . . . ");
  2801. //
  2802. // Get the current value...
  2803. //
  2804. NtStatus = SamQueryInformationDomain(
  2805. DomainHandle,
  2806. DomainReplicationInformation,
  2807. &Buffer1
  2808. );
  2809. ASSERT( NT_SUCCESS(NtStatus) );
  2810. //
  2811. // Change the field to a new value and write it out.
  2812. //
  2813. NameLength = ((DOMAIN_REPLICATION_INFORMATION *)Buffer1)->ReplicaSourceNodeName.Length;
  2814. if ( NameLength == DummyName1.Length ) {
  2815. ((DOMAIN_REPLICATION_INFORMATION *)Buffer1)->ReplicaSourceNodeName = DummyName2;
  2816. } else {
  2817. ((DOMAIN_REPLICATION_INFORMATION *)Buffer1)->ReplicaSourceNodeName = DummyName1;
  2818. }
  2819. NtStatus = SamSetInformationDomain(
  2820. DomainHandle,
  2821. DomainReplicationInformation,
  2822. Buffer1
  2823. );
  2824. if ( NT_SUCCESS(NtStatus) ) {
  2825. //
  2826. // Now check that the change was really made...
  2827. //
  2828. NtStatus = SamQueryInformationDomain(
  2829. DomainHandle,
  2830. DomainReplicationInformation,
  2831. &Buffer2
  2832. );
  2833. ASSERT(NT_SUCCESS( NtStatus ) );
  2834. if (((DOMAIN_REPLICATION_INFORMATION *)Buffer1)->ReplicaSourceNodeName.Length ==
  2835. ((DOMAIN_REPLICATION_INFORMATION *)Buffer2)->ReplicaSourceNodeName.Length ) {
  2836. printf("Succeeded\n");
  2837. } else {
  2838. printf("Failed\n");
  2839. printf(" Value queried doesn't match value written\n");
  2840. printf(" Value Written is 0x%lx\n",
  2841. (ULONG)((DOMAIN_REPLICATION_INFORMATION *)Buffer1)->ReplicaSourceNodeName.Length);
  2842. printf(" Value Retrieved is 0x%lx\n",
  2843. (ULONG)((DOMAIN_REPLICATION_INFORMATION *)Buffer2)->ReplicaSourceNodeName.Length);
  2844. TestStatus = FALSE;
  2845. }
  2846. SamFreeMemory( Buffer1 );
  2847. SamFreeMemory( Buffer2 );
  2848. } else {
  2849. printf("Failed\n");
  2850. printf(" Completion status is 0x%lx\n", NtStatus);
  2851. TestStatus = FALSE;
  2852. SamFreeMemory( Buffer1 );
  2853. }
  2854. ///////////////////////////////////////////////////////////////////////////
  2855. // //
  2856. // Create User/Group/Alias Suite //
  2857. // //
  2858. ///////////////////////////////////////////////////////////////////////////
  2859. printf(" Create User/Group/Alias . . . . . . . . . . . . . . . . Suite\n");
  2860. printf(" Create Group . . . . . . . . . . . . . . . . . . . . ");
  2861. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  2862. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  2863. TST_SUCCESS_ASSERT(NtStatus);
  2864. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  2865. GroupRid = 0;
  2866. GroupHandle = NULL;
  2867. NtStatus = SamCreateGroupInDomain(
  2868. DomainHandle,
  2869. &AccountName,
  2870. GROUP_ALL_ACCESS,
  2871. &GroupHandle,
  2872. &GroupRid
  2873. );
  2874. RtlFreeUnicodeString( &AccountName );
  2875. if (NT_SUCCESS(NtStatus)) {
  2876. if ( (GroupHandle == NULL) || (GroupRid == 0) ) {
  2877. printf("Failed\n");
  2878. printf(" Invalid GroupHandle or GroupRid returned.\n");
  2879. printf(" Completion status is 0x%lx\n", NtStatus);
  2880. printf(" GroupHandle value is: 0x%lx\n", (ULONG)GroupHandle);
  2881. printf(" GroupRid value is: 0x%lx\n", GroupRid);
  2882. TestStatus = FALSE;
  2883. } else {
  2884. printf("Succeeded\n");
  2885. SavedGroupRid = GroupRid;
  2886. NtStatus = SamCloseHandle( GroupHandle );
  2887. if (!NT_SUCCESS(NtStatus)) {
  2888. printf(" SamCloseHandle() completion status is: 0x%lx\n", NtStatus);
  2889. }
  2890. ASSERT( NT_SUCCESS(NtStatus) );
  2891. }
  2892. } else {
  2893. printf("Failed\n");
  2894. printf(" Completion status is 0x%lx\n", NtStatus);
  2895. TestStatus = FALSE;
  2896. }
  2897. printf(" Create Duplicate Group . . . . . . . . . . . . . . . ");
  2898. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  2899. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  2900. TST_SUCCESS_ASSERT(NtStatus);
  2901. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  2902. GroupRid = 0;
  2903. GroupHandle = NULL;
  2904. NtStatus = SamCreateGroupInDomain(
  2905. DomainHandle,
  2906. &AccountName,
  2907. GROUP_ALL_ACCESS,
  2908. &GroupHandle,
  2909. &GroupRid
  2910. );
  2911. RtlFreeUnicodeString( &AccountName );
  2912. if (NtStatus != STATUS_GROUP_EXISTS) {
  2913. printf("Failed\n");
  2914. printf(" Completion status should be STATUS_GROUP_EXISTS\n");
  2915. printf(" Completion status is 0x%lx\n", NtStatus);
  2916. TestStatus = FALSE;
  2917. } else {
  2918. printf("Succeeded\n");
  2919. }
  2920. printf(" Create Alias . . . . . . . . . . . . . . . . . . . . ");
  2921. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  2922. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  2923. TST_SUCCESS_ASSERT(NtStatus);
  2924. AliasRid = 0;
  2925. AliasHandle = NULL;
  2926. NtStatus = SamCreateAliasInDomain(
  2927. DomainHandle,
  2928. &AccountName,
  2929. ALIAS_ALL_ACCESS,
  2930. &AliasHandle,
  2931. &AliasRid
  2932. );
  2933. RtlFreeUnicodeString( &AccountName );
  2934. if (NT_SUCCESS(NtStatus)) {
  2935. if ( (AliasHandle == NULL) || (AliasRid == 0) ) {
  2936. printf("Failed\n");
  2937. printf(" Invalid AliasHandle or AliasRid returned.\n");
  2938. printf(" Completion status is 0x%lx\n", NtStatus);
  2939. printf(" AliasHandle value is: 0x%lx\n", (ULONG)AliasHandle);
  2940. printf(" AliasRid value is: 0x%lx\n", AliasRid);
  2941. TestStatus = FALSE;
  2942. } else {
  2943. printf("Succeeded\n");
  2944. SavedAliasRid = AliasRid;
  2945. NtStatus = SamCloseHandle( AliasHandle );
  2946. if (!NT_SUCCESS(NtStatus)) {
  2947. printf(" SamCloseHandle() completion status is: 0x%lx\n", NtStatus);
  2948. }
  2949. ASSERT( NT_SUCCESS(NtStatus) );
  2950. if (AliasRid == SavedGroupRid) {
  2951. printf(" Create Group/Alias Comparison. . . . . . . . . . . . . Failed\n");
  2952. printf(" Same RID assigned to new alias and group.\n");
  2953. TestStatus = FALSE;
  2954. }
  2955. }
  2956. } else {
  2957. printf("Failed\n");
  2958. printf(" Completion status is 0x%lx\n", NtStatus);
  2959. TestStatus = FALSE;
  2960. }
  2961. printf(" Create another Alias . . . . . . . . . . . . . . . . ");
  2962. RtlInitString( &AccountNameAnsi, ALIAS_NAME2 );
  2963. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  2964. TST_SUCCESS_ASSERT(NtStatus);
  2965. AliasRid = 0;
  2966. AliasHandle = NULL;
  2967. NtStatus = SamCreateAliasInDomain(
  2968. DomainHandle,
  2969. &AccountName,
  2970. ALIAS_ALL_ACCESS,
  2971. &AliasHandle,
  2972. &AliasRid
  2973. );
  2974. RtlFreeUnicodeString( &AccountName );
  2975. if (NT_SUCCESS(NtStatus)) {
  2976. if ( (AliasHandle == NULL) || (AliasRid == 0) ) {
  2977. printf("Failed\n");
  2978. printf(" Invalid AliasHandle or AliasRid returned.\n");
  2979. printf(" Completion status is 0x%lx\n", NtStatus);
  2980. printf(" AliasHandle value is: 0x%lx\n", (ULONG)AliasHandle);
  2981. printf(" AliasRid value is: 0x%lx\n", AliasRid);
  2982. TestStatus = FALSE;
  2983. } else {
  2984. printf("Succeeded\n");
  2985. SavedAliasRid = AliasRid;
  2986. NtStatus = SamCloseHandle( AliasHandle );
  2987. if (!NT_SUCCESS(NtStatus)) {
  2988. printf(" SamCloseHandle() completion status is: 0x%lx\n", NtStatus);
  2989. }
  2990. ASSERT( NT_SUCCESS(NtStatus) );
  2991. if (AliasRid == SavedGroupRid) {
  2992. printf(" Create Group/Alias Comparison. . . . . . . . . . . . . Failed\n");
  2993. printf(" Same RID assigned to new alias and group.\n");
  2994. TestStatus = FALSE;
  2995. }
  2996. }
  2997. } else {
  2998. printf("Failed\n");
  2999. printf(" Completion status is 0x%lx\n", NtStatus);
  3000. TestStatus = FALSE;
  3001. }
  3002. printf(" Create Duplicate Alias . . . . . . . . . . . . . . . ");
  3003. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  3004. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3005. TST_SUCCESS_ASSERT(NtStatus);
  3006. AliasRid = 0;
  3007. AliasHandle = NULL;
  3008. NtStatus = SamCreateAliasInDomain(
  3009. DomainHandle,
  3010. &AccountName,
  3011. ALIAS_ALL_ACCESS,
  3012. &AliasHandle,
  3013. &AliasRid
  3014. );
  3015. RtlFreeUnicodeString( &AccountName );
  3016. if (NtStatus != STATUS_ALIAS_EXISTS) {
  3017. printf("Failed\n");
  3018. printf(" Completion status should be STATUS_ALIAS_EXISTS\n");
  3019. printf(" Completion status is 0x%lx\n", NtStatus);
  3020. TestStatus = FALSE;
  3021. } else {
  3022. printf("Succeeded\n");
  3023. }
  3024. printf(" Create User . . . . . . . . . . . . . . . . . . . . . ");
  3025. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  3026. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3027. TST_SUCCESS_ASSERT(NtStatus);
  3028. UserRid = 0;
  3029. UserHandle = NULL;
  3030. NtStatus = SamCreateUserInDomain(
  3031. DomainHandle,
  3032. &AccountName,
  3033. USER_ALL_ACCESS,
  3034. &UserHandle,
  3035. &UserRid
  3036. );
  3037. RtlFreeUnicodeString( &AccountName );
  3038. if (NT_SUCCESS(NtStatus)) {
  3039. if ( (UserHandle == NULL) || (UserRid == 0) ) {
  3040. printf("Failed\n");
  3041. printf(" Invalid UserHandle or UserRid returned.\n");
  3042. printf(" Completion status is 0x%lx\n", NtStatus);
  3043. printf(" UserHandle value is: 0x%lx\n", (ULONG)UserHandle);
  3044. printf(" UserRid value is: 0x%lx\n", UserRid);
  3045. TestStatus = FALSE;
  3046. } else {
  3047. printf("Succeeded\n");
  3048. ValidUserHandle = UserHandle;
  3049. if (UserRid == SavedGroupRid) {
  3050. printf(" Create Group/User Comparison. . . . . . . . . . . . . Failed\n");
  3051. printf(" Same RID assigned to new user and group.\n");
  3052. TestStatus = FALSE;
  3053. }
  3054. if (UserRid == SavedAliasRid) {
  3055. printf(" Create Alias/User Comparison. . . . . . . . . . . . . Failed\n");
  3056. printf(" Same RID assigned to new user and alias.\n");
  3057. TestStatus = FALSE;
  3058. }
  3059. }
  3060. } else {
  3061. printf("Failed\n");
  3062. printf(" Completion status is 0x%lx\n", NtStatus);
  3063. TestStatus = FALSE;
  3064. }
  3065. printf(" Create Duplicate User . . . . . . . . . . . . . . . . ");
  3066. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  3067. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3068. TST_SUCCESS_ASSERT(NtStatus);
  3069. UserRid = 0;
  3070. UserHandle = NULL;
  3071. NtStatus = SamCreateUserInDomain(
  3072. DomainHandle,
  3073. &AccountName,
  3074. USER_ALL_ACCESS,
  3075. &UserHandle,
  3076. &UserRid
  3077. );
  3078. RtlFreeUnicodeString( &AccountName );
  3079. if (NtStatus != STATUS_USER_EXISTS) {
  3080. printf("Failed\n");
  3081. printf(" Completion status should be STATUS_USER_EXISTS\n");
  3082. printf(" Completion status is 0x%lx\n", NtStatus);
  3083. TestStatus = FALSE;
  3084. } else {
  3085. printf("Succeeded\n");
  3086. }
  3087. printf(" Create Group With Same Name As User . . . . . . . . . ");
  3088. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  3089. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3090. TST_SUCCESS_ASSERT(NtStatus);
  3091. GroupRid = 0;
  3092. GroupHandle = NULL;
  3093. NtStatus = SamCreateGroupInDomain(
  3094. DomainHandle,
  3095. &AccountName,
  3096. GROUP_ALL_ACCESS,
  3097. &GroupHandle,
  3098. &GroupRid
  3099. );
  3100. RtlFreeUnicodeString( &AccountName );
  3101. if (NtStatus != STATUS_USER_EXISTS) {
  3102. printf("Failed\n");
  3103. printf(" Completion status should be STATUS_USER_EXISTS\n");
  3104. printf(" Completion status is 0x%lx\n", NtStatus);
  3105. TestStatus = FALSE;
  3106. } else {
  3107. printf("Succeeded\n");
  3108. }
  3109. printf(" Create Group With Same Name As Alias. . . . . . . . . ");
  3110. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  3111. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3112. TST_SUCCESS_ASSERT(NtStatus);
  3113. GroupRid = 0;
  3114. GroupHandle = NULL;
  3115. NtStatus = SamCreateGroupInDomain(
  3116. DomainHandle,
  3117. &AccountName,
  3118. GROUP_ALL_ACCESS,
  3119. &GroupHandle,
  3120. &GroupRid
  3121. );
  3122. RtlFreeUnicodeString( &AccountName );
  3123. if (NtStatus != STATUS_ALIAS_EXISTS) {
  3124. printf("Failed\n");
  3125. printf(" Completion status should be STATUS_ALIAS_EXISTS\n");
  3126. printf(" Completion status is 0x%lx\n", NtStatus);
  3127. TestStatus = FALSE;
  3128. } else {
  3129. printf("Succeeded\n");
  3130. }
  3131. printf(" Create Alias With Same Name As Group. . . . . . . . . ");
  3132. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  3133. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3134. TST_SUCCESS_ASSERT(NtStatus);
  3135. AliasRid = 0;
  3136. AliasHandle = NULL;
  3137. NtStatus = SamCreateAliasInDomain(
  3138. DomainHandle,
  3139. &AccountName,
  3140. GROUP_ALL_ACCESS,
  3141. &AliasHandle,
  3142. &AliasRid
  3143. );
  3144. RtlFreeUnicodeString( &AccountName );
  3145. if (NtStatus != STATUS_GROUP_EXISTS) {
  3146. printf("Failed\n");
  3147. printf(" Completion status should be STATUS_GROUP_EXISTS\n");
  3148. printf(" Completion status is 0x%lx\n", NtStatus);
  3149. TestStatus = FALSE;
  3150. } else {
  3151. printf("Succeeded\n");
  3152. }
  3153. printf(" Create User With Same Name As Group . . . . . . . . . ");
  3154. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  3155. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3156. TST_SUCCESS_ASSERT(NtStatus);
  3157. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  3158. UserRid = 0;
  3159. UserHandle = NULL;
  3160. NtStatus = SamCreateUserInDomain(
  3161. DomainHandle,
  3162. &AccountName,
  3163. USER_ALL_ACCESS,
  3164. &UserHandle,
  3165. &UserRid
  3166. );
  3167. RtlFreeUnicodeString( &AccountName );
  3168. if (NtStatus != STATUS_GROUP_EXISTS) {
  3169. printf("Failed\n");
  3170. printf(" Completion status should be STATUS_GROUP_EXISTS\n");
  3171. printf(" Completion status is 0x%lx\n", NtStatus);
  3172. TestStatus = FALSE;
  3173. } else {
  3174. printf("Succeeded\n");
  3175. }
  3176. printf(" Create User With Same Name As Alias . . . . . . . . . ");
  3177. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  3178. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  3179. TST_SUCCESS_ASSERT(NtStatus);
  3180. UserRid = 0;
  3181. UserHandle = NULL;
  3182. NtStatus = SamCreateUserInDomain(
  3183. DomainHandle,
  3184. &AccountName,
  3185. USER_ALL_ACCESS,
  3186. &UserHandle,
  3187. &UserRid
  3188. );
  3189. RtlFreeUnicodeString( &AccountName );
  3190. if (NtStatus != STATUS_ALIAS_EXISTS) {
  3191. printf("Failed\n");
  3192. printf(" Completion status should be STATUS_ALIAS_EXISTS\n");
  3193. printf(" Completion status is 0x%lx\n", NtStatus);
  3194. TestStatus = FALSE;
  3195. } else {
  3196. printf("Succeeded\n");
  3197. }
  3198. ///////////////////////////////////////////////////////////////////////////
  3199. // //
  3200. // Call server to test internal functions //
  3201. // //
  3202. ///////////////////////////////////////////////////////////////////////////
  3203. printf("\n");
  3204. printf(" Test internal functions . . . . . . . . . . . . . . . Suite\n");
  3205. printf(" Test internal domain functions . . . . . . . . . . ");
  3206. NtStatus = SamTestPrivateFunctionsDomain( DomainHandle );
  3207. if ( NT_SUCCESS( NtStatus ) ) {
  3208. printf("Succeeded.\n");
  3209. } else {
  3210. if ( NtStatus == STATUS_NOT_IMPLEMENTED ) {
  3211. printf("Not Implemented\n");
  3212. } else {
  3213. printf("Failed.\n");
  3214. printf(" Status = %lx\n", NtStatus );
  3215. TestStatus = FALSE;
  3216. }
  3217. }
  3218. printf(" Test internal user functions . . . . . . . . . . . ");
  3219. if (ValidUserHandle == NULL) {
  3220. printf("Test omitted - Valid User handle not available\n");
  3221. TestStatus = FALSE;
  3222. } else {
  3223. NtStatus = SamTestPrivateFunctionsUser( ValidUserHandle );
  3224. IgnoreStatus = SamCloseHandle( ValidUserHandle );
  3225. ASSERT( NT_SUCCESS(IgnoreStatus) );
  3226. if ( NT_SUCCESS( NtStatus ) ) {
  3227. printf("Succeeded.\n");
  3228. } else {
  3229. if ( NtStatus == STATUS_NOT_IMPLEMENTED ) {
  3230. printf("Not Implemented\n");
  3231. } else {
  3232. printf("Failed.\n");
  3233. printf(" Status = %lx\n", NtStatus );
  3234. TestStatus = FALSE;
  3235. }
  3236. }
  3237. }
  3238. ///////////////////////////////////////////////////////////////////////////
  3239. // //
  3240. // Enumerate Users/Groups Suite //
  3241. // //
  3242. ///////////////////////////////////////////////////////////////////////////
  3243. printf(" Enumerate Users/Groups/Aliases. . . . . . . . . . . . Suite\n");
  3244. printf(" Enumerate Groups - large prefered length . . . . . . ");
  3245. EnumerationContext = 0;
  3246. NtStatus = SamEnumerateGroupsInDomain(
  3247. DomainHandle,
  3248. &EnumerationContext,
  3249. &Buffer,
  3250. 12000, // PreferedMaximumLength
  3251. &CountReturned
  3252. );
  3253. AccountCount = CountReturned; // Save for future test
  3254. if (NT_SUCCESS(NtStatus)) {
  3255. if (Buffer != NULL) {
  3256. if (NtStatus == STATUS_SUCCESS) {
  3257. if (CountReturned > 1) {
  3258. printf("Succeeded\n");
  3259. for (i=0; i<CountReturned; i++) {
  3260. printf(" Rid/Name(%ld): 0x%lx / %wZ\n",i,
  3261. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  3262. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name
  3263. );
  3264. }
  3265. } else {
  3266. printf("Failed\n");
  3267. printf(" Completion status is 0x%lx\n", NtStatus);
  3268. printf(" Expected several entries to be returned.\n");
  3269. printf(" Received 0x%lx entries instead.\n", CountReturned);
  3270. TestStatus = FALSE;
  3271. }
  3272. } else {
  3273. printf("Failed\n");
  3274. printf(" Expected STATUS_MORE_ENTRIES to be returned.\n");
  3275. printf(" Received 0x%lx instead.\n", NtStatus);
  3276. printf(" Buffer = 0x%lx\n", (ULONG)Buffer);
  3277. printf(" CountReturned = 0x%lx\n", CountReturned);
  3278. TestStatus = FALSE;
  3279. }
  3280. SamFreeMemory( Buffer );
  3281. } else {
  3282. printf("Failed\n");
  3283. printf(" Buffer address not set on return.\n");
  3284. printf(" RPC should have allocated a buffer.\n");
  3285. printf(" Completion status is 0x%lx\n", NtStatus);
  3286. TestStatus = FALSE;
  3287. }
  3288. } else {
  3289. printf("Failed\n");
  3290. printf(" Completion status is 0x%lx\n", NtStatus);
  3291. TestStatus = FALSE;
  3292. }
  3293. printf(" Enumerate Groups - small prefered length . . . . . . ");
  3294. for ( i=0; i<AccountCount; i++) {
  3295. EnumerationContext = i;
  3296. NtStatus = SamEnumerateGroupsInDomain(
  3297. DomainHandle,
  3298. &EnumerationContext,
  3299. &Buffer,
  3300. 0, // PreferedMaximumLength
  3301. &CountReturned
  3302. );
  3303. if (NT_SUCCESS(NtStatus)) {
  3304. if (Buffer != NULL) {
  3305. if ( ((i >= AccountCount -1) && (NtStatus == STATUS_SUCCESS)) ||
  3306. ((i <= AccountCount -1) && (NtStatus == STATUS_MORE_ENTRIES)) ) {
  3307. if (CountReturned != 1) {
  3308. printf("Failed\n");
  3309. printf(" Completion status is 0x%lx\n", NtStatus);
  3310. printf(" Expected one entry to be returned.\n");
  3311. printf(" Received 0x%lx entries instead.\n", CountReturned);
  3312. TestStatus = FALSE;
  3313. i = AccountCount + 100;
  3314. }
  3315. } else {
  3316. printf("Failed\n");
  3317. if (i < AccountCount -1 ) {
  3318. printf(" Expected STATUS_MORE_ENTRIES to be returned.\n");
  3319. } else {
  3320. printf(" Expected STATUS_SUCCESS to be returned.\n");
  3321. }
  3322. printf(" Received 0x%lx instead.\n", NtStatus);
  3323. printf(" Buffer = 0x%lx\n", (ULONG)Buffer);
  3324. printf(" CountReturned = 0x%lx\n", CountReturned);
  3325. TestStatus = FALSE;
  3326. i = AccountCount + 100;
  3327. }
  3328. SamFreeMemory( Buffer );
  3329. } else {
  3330. printf("Failed\n");
  3331. printf(" Buffer address not set on return.\n");
  3332. printf(" RPC should have allocated a buffer.\n");
  3333. printf(" Completion status is 0x%lx\n", NtStatus);
  3334. TestStatus = FALSE;
  3335. i = AccountCount + 100;
  3336. }
  3337. } else {
  3338. printf("Failed\n");
  3339. printf(" Completion status is 0x%lx\n", NtStatus);
  3340. TestStatus = FALSE;
  3341. i = AccountCount + 100;
  3342. }
  3343. }
  3344. if ( i == AccountCount) {
  3345. printf("Succeeded\n");
  3346. }
  3347. printf(" Enumerate Aliases - large prefered length . . . . . . ");
  3348. EnumerationContext = 0;
  3349. NtStatus = SamEnumerateAliasesInDomain(
  3350. DomainHandle,
  3351. &EnumerationContext,
  3352. &Buffer,
  3353. 12000, // PreferedMaximumLength
  3354. &CountReturned
  3355. );
  3356. AccountCount = CountReturned; // Save for future test
  3357. if (NT_SUCCESS(NtStatus)) {
  3358. if (Buffer != NULL) {
  3359. if (NtStatus == STATUS_SUCCESS) {
  3360. if (CountReturned > 1) {
  3361. printf("Succeeded\n");
  3362. for (i=0; i<CountReturned; i++) {
  3363. printf(" Rid/Name(%ld): 0x%lx / %wZ\n",i,
  3364. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  3365. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name
  3366. );
  3367. }
  3368. } else {
  3369. printf("Failed\n");
  3370. printf(" Completion status is 0x%lx\n", NtStatus);
  3371. printf(" Expected several entries to be returned.\n");
  3372. printf(" Received 0x%lx entries instead.\n", CountReturned);
  3373. TestStatus = FALSE;
  3374. }
  3375. } else {
  3376. printf("Failed\n");
  3377. printf(" Expected STATUS_MORE_ENTRIES to be returned.\n");
  3378. printf(" Received 0x%lx instead.\n", NtStatus);
  3379. printf(" Buffer = 0x%lx\n", (ULONG)Buffer);
  3380. printf(" CountReturned = 0x%lx\n", CountReturned);
  3381. TestStatus = FALSE;
  3382. }
  3383. SamFreeMemory( Buffer );
  3384. } else {
  3385. printf("Failed\n");
  3386. printf(" Buffer address not set on return.\n");
  3387. printf(" RPC should have allocated a buffer.\n");
  3388. printf(" Completion status is 0x%lx\n", NtStatus);
  3389. TestStatus = FALSE;
  3390. }
  3391. } else {
  3392. printf("Failed\n");
  3393. printf(" Completion status is 0x%lx\n", NtStatus);
  3394. TestStatus = FALSE;
  3395. }
  3396. printf(" Enumerate Aliases - small prefered length . . . . . . ");
  3397. for ( i=0; i<AccountCount; i++) {
  3398. EnumerationContext = i;
  3399. NtStatus = SamEnumerateAliasesInDomain(
  3400. DomainHandle,
  3401. &EnumerationContext,
  3402. &Buffer,
  3403. 0, // PreferedMaximumLength
  3404. &CountReturned
  3405. );
  3406. if (NT_SUCCESS(NtStatus)) {
  3407. if (Buffer != NULL) {
  3408. if ( ((i >= AccountCount -1) && (NtStatus == STATUS_SUCCESS)) ||
  3409. ((i <= AccountCount -1) && (NtStatus == STATUS_MORE_ENTRIES)) ) {
  3410. if (CountReturned != 1) {
  3411. printf("Failed\n");
  3412. printf(" Completion status is 0x%lx\n", NtStatus);
  3413. printf(" Expected one entry to be returned.\n");
  3414. printf(" Received 0x%lx entries instead.\n", CountReturned);
  3415. TestStatus = FALSE;
  3416. i = AccountCount + 100;
  3417. }
  3418. } else {
  3419. printf("Failed\n");
  3420. if (i < AccountCount -1 ) {
  3421. printf(" Expected STATUS_MORE_ENTRIES to be returned.\n");
  3422. } else {
  3423. printf(" Expected STATUS_SUCCESS to be returned.\n");
  3424. }
  3425. printf(" Received 0x%lx instead.\n", NtStatus);
  3426. printf(" Buffer = 0x%lx\n", (ULONG)Buffer);
  3427. printf(" CountReturned = 0x%lx\n", CountReturned);
  3428. TestStatus = FALSE;
  3429. i = AccountCount + 100;
  3430. }
  3431. SamFreeMemory( Buffer );
  3432. } else {
  3433. printf("Failed\n");
  3434. printf(" Buffer address not set on return.\n");
  3435. printf(" RPC should have allocated a buffer.\n");
  3436. printf(" Completion status is 0x%lx\n", NtStatus);
  3437. TestStatus = FALSE;
  3438. i = AccountCount + 100;
  3439. }
  3440. } else {
  3441. printf("Failed\n");
  3442. printf(" Completion status is 0x%lx\n", NtStatus);
  3443. TestStatus = FALSE;
  3444. i = AccountCount + 100;
  3445. }
  3446. }
  3447. if ( i == AccountCount) {
  3448. printf("Succeeded\n");
  3449. }
  3450. printf(" Enumerate Users - large prefered length . . . . . . ");
  3451. EnumerationContext = 0;
  3452. NtStatus = SamEnumerateUsersInDomain(
  3453. DomainHandle,
  3454. &EnumerationContext,
  3455. 0,
  3456. &Buffer,
  3457. 12000, // PreferedMaximumLength
  3458. &CountReturned
  3459. );
  3460. AccountCount = CountReturned; // Save for future test
  3461. if (NT_SUCCESS(NtStatus)) {
  3462. if (Buffer != NULL) {
  3463. if (NtStatus == STATUS_SUCCESS) {
  3464. if (CountReturned > 1) {
  3465. printf("Succeeded\n");
  3466. for (i=0; i<CountReturned; i++) {
  3467. printf(" Rid/Name(%ld): 0x%lx / %wZ\n",i,
  3468. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  3469. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name
  3470. );
  3471. }
  3472. } else {
  3473. printf("Failed\n");
  3474. printf(" Completion status is 0x%lx\n", NtStatus);
  3475. printf(" Expected several entries to be returned.\n");
  3476. printf(" Received 0x%lx entries instead.\n", CountReturned);
  3477. TestStatus = FALSE;
  3478. }
  3479. } else {
  3480. printf("Failed\n");
  3481. printf(" Expected STATUS_MORE_ENTRIES to be returned.\n");
  3482. printf(" Received 0x%lx instead.\n", NtStatus);
  3483. printf(" Buffer = 0x%lx\n", (ULONG)Buffer);
  3484. printf(" CountReturned = 0x%lx\n", CountReturned);
  3485. TestStatus = FALSE;
  3486. }
  3487. SamFreeMemory( Buffer );
  3488. } else {
  3489. printf("Failed\n");
  3490. printf(" Buffer address not set on return.\n");
  3491. printf(" RPC should have allocated a buffer.\n");
  3492. printf(" Completion status is 0x%lx\n", NtStatus);
  3493. TestStatus = FALSE;
  3494. }
  3495. } else {
  3496. printf("Failed\n");
  3497. printf(" Completion status is 0x%lx\n", NtStatus);
  3498. TestStatus = FALSE;
  3499. }
  3500. printf(" Enumerate Users - small prefered length . . . . . . ");
  3501. for ( i=0; i<AccountCount; i++) {
  3502. EnumerationContext = i;
  3503. NtStatus = SamEnumerateUsersInDomain(
  3504. DomainHandle,
  3505. &EnumerationContext,
  3506. 0,
  3507. &Buffer,
  3508. 0, // PreferedMaximumLength
  3509. &CountReturned
  3510. );
  3511. if (NT_SUCCESS(NtStatus)) {
  3512. if (Buffer != NULL) {
  3513. if ( ((i >= AccountCount -1) && (NtStatus == STATUS_SUCCESS)) ||
  3514. ((i <= AccountCount -1) && (NtStatus == STATUS_MORE_ENTRIES)) ) {
  3515. if (CountReturned != 1) {
  3516. printf("Failed\n");
  3517. printf(" Completion status is 0x%lx\n", NtStatus);
  3518. printf(" Expected one entry to be returned.\n");
  3519. printf(" Received 0x%lx entries instead.\n", CountReturned);
  3520. TestStatus = FALSE;
  3521. i = AccountCount + 100;
  3522. }
  3523. } else {
  3524. printf("Failed\n");
  3525. if (i < AccountCount -1 ) {
  3526. printf(" Expected STATUS_MORE_ENTRIES to be returned.\n");
  3527. } else {
  3528. printf(" Expected STATUS_SUCCESS to be returned.\n");
  3529. }
  3530. printf(" Received 0x%lx instead.\n", NtStatus);
  3531. printf(" Buffer = 0x%lx\n", (ULONG)Buffer);
  3532. printf(" CountReturned = 0x%lx\n", CountReturned);
  3533. TestStatus = FALSE;
  3534. i = AccountCount + 100;
  3535. }
  3536. SamFreeMemory( Buffer );
  3537. } else {
  3538. printf("Failed\n");
  3539. printf(" Buffer address not set on return.\n");
  3540. printf(" RPC should have allocated a buffer.\n");
  3541. printf(" Completion status is 0x%lx\n", NtStatus);
  3542. TestStatus = FALSE;
  3543. i = AccountCount + 100;
  3544. }
  3545. } else {
  3546. printf("Failed\n");
  3547. printf(" Completion status is 0x%lx\n", NtStatus);
  3548. TestStatus = FALSE;
  3549. i = AccountCount + 100;
  3550. }
  3551. }
  3552. if ( i == AccountCount) {
  3553. printf("Succeeded\n");
  3554. }
  3555. ///////////////////////////////////////////////////////////////////////////
  3556. // //
  3557. // Lookup Names/IDs Suite //
  3558. // //
  3559. ///////////////////////////////////////////////////////////////////////////
  3560. // LATER add alias search to lookup name suite.....
  3561. printf("\n");
  3562. printf(" Lookup Names/IDs . . . . . . . . . . . . . . . . . . Suite\n");
  3563. printf(" Lookup Names (all existing) . . . . . . . . . . . . . ");
  3564. NtStatus = SamLookupNamesInDomain(
  3565. DomainHandle,
  3566. ALL_NAMES_COUNT,
  3567. &AllNames[0],
  3568. &LookedUpRids,
  3569. &LookedUpUses
  3570. );
  3571. if (NT_SUCCESS(NtStatus)) {
  3572. ASSERT( LookedUpRids != NULL );
  3573. ASSERT( LookedUpUses != NULL );
  3574. if (
  3575. (LookedUpRids[0] == AllRids[0]) && (LookedUpUses[0] == AllUses[0])
  3576. &&
  3577. (LookedUpRids[1] == AllRids[1]) && (LookedUpUses[1] == AllUses[1])
  3578. &&
  3579. (LookedUpRids[2] == AllRids[2]) && (LookedUpUses[2] == AllUses[2])
  3580. ) {
  3581. printf("Succeeded\n");
  3582. } else {
  3583. printf("Failed\n");
  3584. printf(" Rids or Uses dont match expected values.\n");
  3585. printf(" Expected Rids: 0x%lx, 0x%lx, 0x%lx\n",
  3586. AllRids[0], AllRids[1], AllRids[2]);
  3587. printf(" Received Rids: 0x%lx, 0x%lx, 0x%lx\n",
  3588. LookedUpRids[0], LookedUpRids[1], LookedUpRids[2]);
  3589. printf(" Expected Uses: 0x%lx, 0x%lx, 0x%lx\n",
  3590. AllUses[0], AllUses[1], AllUses[2]);
  3591. printf(" Received Uses: 0x%lx, 0x%lx, 0x%lx\n",
  3592. LookedUpUses[0], LookedUpUses[1], LookedUpUses[2]);
  3593. TestStatus = FALSE;
  3594. }
  3595. SamFreeMemory( LookedUpRids );
  3596. SamFreeMemory( LookedUpUses );
  3597. } else {
  3598. printf("Failed\n");
  3599. printf(" Completion status is 0x%lx\n", NtStatus);
  3600. TestStatus = FALSE;
  3601. }
  3602. printf(" Lookup Names (Some existing) . . . . . . . . . . . . ");
  3603. NtStatus = SamLookupNamesInDomain(
  3604. DomainHandle,
  3605. SOME_NAMES_COUNT,
  3606. &SomeNames[0],
  3607. &LookedUpRids,
  3608. &LookedUpUses
  3609. );
  3610. if (NtStatus == STATUS_SOME_NOT_MAPPED) {
  3611. ASSERT( LookedUpRids != NULL );
  3612. ASSERT( LookedUpUses != NULL );
  3613. if (
  3614. (LookedUpRids[0] == SomeRids[0]) && (LookedUpUses[0] == SomeUses[0])
  3615. &&
  3616. (LookedUpRids[1] == SomeRids[1]) && (LookedUpUses[1] == SomeUses[1])
  3617. &&
  3618. (LookedUpRids[2] == SomeRids[2]) && (LookedUpUses[2] == SomeUses[2])
  3619. &&
  3620. (LookedUpRids[3] == SomeRids[3]) && (LookedUpUses[3] == SomeUses[3])
  3621. &&
  3622. (LookedUpRids[4] == SomeRids[4]) && (LookedUpUses[4] == SomeUses[4])
  3623. &&
  3624. (LookedUpRids[5] == SomeRids[5]) && (LookedUpUses[5] == SomeUses[5])
  3625. &&
  3626. (LookedUpRids[6] == SomeRids[6]) && (LookedUpUses[6] == SomeUses[6])
  3627. ) {
  3628. printf("Succeeded\n");
  3629. } else {
  3630. printf("Failed\n");
  3631. printf(" Rids or Uses dont match expected values.\n");
  3632. printf(" Expected Rids: 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
  3633. SomeRids[0], SomeRids[1], SomeRids[2], SomeRids[3], SomeRids[4], SomeRids[5], SomeRids[6]);
  3634. printf(" Received Rids: 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
  3635. LookedUpRids[0], LookedUpRids[1], LookedUpRids[2], LookedUpRids[3], LookedUpRids[4], LookedUpRids[5], LookedUpRids[6]);
  3636. printf(" Expected Uses: 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
  3637. SomeUses[0], SomeUses[1], SomeUses[2], SomeUses[3], SomeUses[4], SomeUses[5], SomeUses[6]);
  3638. printf(" Received Uses: 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
  3639. LookedUpUses[0], LookedUpUses[1], LookedUpUses[2], LookedUpUses[3], LookedUpUses[4], LookedUpUses[5], LookedUpUses[2]);
  3640. TestStatus = FALSE;
  3641. }
  3642. SamFreeMemory( LookedUpRids );
  3643. SamFreeMemory( LookedUpUses );
  3644. } else {
  3645. printf("Failed\n");
  3646. printf(" Completion status is 0x%lx\n", NtStatus);
  3647. TestStatus = FALSE;
  3648. }
  3649. printf(" Lookup Names (None existing) . . . . . . . . . . . . ");
  3650. NtStatus = SamLookupNamesInDomain(
  3651. DomainHandle,
  3652. NO_NAMES_COUNT,
  3653. &NoNames[0],
  3654. &LookedUpRids,
  3655. &LookedUpUses
  3656. );
  3657. if (NtStatus == STATUS_NONE_MAPPED) {
  3658. ASSERT( LookedUpRids == NULL );
  3659. ASSERT( LookedUpUses == NULL );
  3660. printf("Succeeded\n");
  3661. } else {
  3662. printf("Failed\n");
  3663. printf(" Completion status is 0x%lx\n", NtStatus);
  3664. TestStatus = FALSE;
  3665. }
  3666. printf(" Lookup SIDs (all existing) . . . . . . . . . . . . . ");
  3667. NtStatus = SamLookupIdsInDomain(
  3668. DomainHandle,
  3669. ALL_NAMES_COUNT,
  3670. &AllRids[0],
  3671. &LookedUpNames,
  3672. &LookedUpUses
  3673. );
  3674. if (NT_SUCCESS(NtStatus)) {
  3675. ASSERT( LookedUpUses != NULL );
  3676. ASSERT( LookedUpNames != NULL );
  3677. ASSERT( LookedUpNames[0].Buffer != NULL );
  3678. ASSERT( LookedUpNames[1].Buffer != NULL );
  3679. ASSERT( LookedUpNames[2].Buffer != NULL );
  3680. if (
  3681. (LookedUpUses[0] == AllUses[0]) &&
  3682. (LookedUpUses[1] == AllUses[1]) &&
  3683. (LookedUpUses[2] == AllUses[2]) &&
  3684. !RtlCompareString( (PSTRING)&LookedUpNames[0], (PSTRING)&AllNames[0], TRUE ) &&
  3685. !RtlCompareString( (PSTRING)&LookedUpNames[1], (PSTRING)&AllNames[1], TRUE ) &&
  3686. !RtlCompareString( (PSTRING)&LookedUpNames[2], (PSTRING)&AllNames[2], TRUE )
  3687. ) {
  3688. printf("Succeeded\n");
  3689. } else {
  3690. printf("Failed\n");
  3691. printf(" Names or Uses dont match expected values.\n");
  3692. printf(" Expected Name[0]: %wZ\n", &AllNames[0] );
  3693. printf(" Received Name[0]: %wZ\n", &LookedUpNames[0] );
  3694. printf(" Expected Name[1]: %wZ\n", &AllNames[1] );
  3695. printf(" Received Name[1]: %wZ\n", &LookedUpNames[1] );
  3696. printf(" Expected Name[2]: %wZ\n", &AllNames[2] );
  3697. printf(" Received Name[2]: %wZ\n", &LookedUpNames[2] );
  3698. printf(" Expected Uses: 0x%lx, 0x%lx, 0x%lx\n",
  3699. AllUses[0], AllUses[1], AllUses[2]);
  3700. printf(" Received Uses: 0x%lx, 0x%lx, 0x%lx\n",
  3701. LookedUpUses[0], LookedUpUses[1], LookedUpUses[2]);
  3702. TestStatus = FALSE;
  3703. }
  3704. SamFreeMemory( LookedUpUses );
  3705. SamFreeMemory( LookedUpNames );
  3706. } else {
  3707. printf("Failed\n");
  3708. printf(" Completion status is 0x%lx\n", NtStatus);
  3709. TestStatus = FALSE;
  3710. }
  3711. printf(" Lookup SIDs (Some existing) . . . . . . . . . . . . . ");
  3712. NtStatus = SamLookupIdsInDomain(
  3713. DomainHandle,
  3714. SOME_NAMES_COUNT,
  3715. &SomeRids[0],
  3716. &LookedUpNames,
  3717. &LookedUpUses
  3718. );
  3719. if (NtStatus == STATUS_SOME_NOT_MAPPED) {
  3720. ASSERT( LookedUpUses != NULL );
  3721. ASSERT( LookedUpNames != NULL );
  3722. ASSERT( LookedUpNames[0].Buffer != NULL );
  3723. ASSERT( LookedUpNames[1].Buffer != NULL );
  3724. ASSERT( LookedUpNames[2].Buffer == NULL ); // Unknown
  3725. ASSERT( LookedUpNames[3].Buffer == NULL ); // Unknown
  3726. ASSERT( LookedUpNames[4].Buffer == NULL ); // Unknown
  3727. ASSERT( LookedUpNames[5].Buffer != NULL );
  3728. ASSERT( LookedUpNames[6].Buffer == NULL ); // Unknown
  3729. if (
  3730. (LookedUpUses[0] == SomeUses[0]) &&
  3731. (LookedUpUses[1] == SomeUses[1]) &&
  3732. (LookedUpUses[2] == SomeUses[2]) &&
  3733. !RtlCompareString( (PSTRING)&LookedUpNames[0], (PSTRING)&SomeNames[0], TRUE ) &&
  3734. !RtlCompareString( (PSTRING)&LookedUpNames[1], (PSTRING)&SomeNames[1], TRUE ) &&
  3735. !RtlCompareString( (PSTRING)&LookedUpNames[5], (PSTRING)&SomeNames[5], TRUE )
  3736. ) {
  3737. printf("Succeeded\n");
  3738. } else {
  3739. printf("Failed\n");
  3740. printf(" Names or Uses dont match expected values.\n");
  3741. printf(" Expected Name[0]: %wZ\n", &SomeNames[0] );
  3742. printf(" Received Name[0]: %wZ\n", &LookedUpNames[0] );
  3743. printf(" Expected Name[1]: %wZ\n", &SomeNames[1] );
  3744. printf(" Received Name[1]: %wZ\n", &LookedUpNames[1] );
  3745. printf(" Name[2]: (Unknown)\n");
  3746. printf(" Name[3]: (Unknown)\n");
  3747. printf(" Name[4]: (Unknown)\n");
  3748. printf(" Expected Name[5]: %wZ\n", &SomeNames[5] );
  3749. printf(" Received Name[5]: %wZ\n", &LookedUpNames[5] );
  3750. printf(" Name[6]: (Unknown)\n");
  3751. printf(" Expected Uses: 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
  3752. SomeUses[0], SomeUses[1], SomeUses[2], SomeUses[3], SomeUses[4], SomeUses[5], SomeUses[6]);
  3753. printf(" Received Uses: 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
  3754. LookedUpUses[0], LookedUpUses[1], LookedUpUses[2], LookedUpUses[3], LookedUpUses[4], LookedUpUses[5], LookedUpUses[2]);
  3755. TestStatus = FALSE;
  3756. }
  3757. SamFreeMemory( LookedUpUses );
  3758. SamFreeMemory( LookedUpNames );
  3759. } else {
  3760. printf("Failed\n");
  3761. printf(" Completion status is 0x%lx\n", NtStatus);
  3762. TestStatus = FALSE;
  3763. }
  3764. printf(" Lookup SIDs (None existing) . . . . . . . . . . . . . ");
  3765. NtStatus = SamLookupIdsInDomain(
  3766. DomainHandle,
  3767. NO_NAMES_COUNT,
  3768. &NoRids[0],
  3769. &LookedUpNames,
  3770. &LookedUpUses
  3771. );
  3772. if (NtStatus == STATUS_NONE_MAPPED) {
  3773. ASSERT( LookedUpUses == NULL );
  3774. ASSERT( LookedUpNames == NULL );
  3775. printf("Succeeded\n");
  3776. } else {
  3777. printf("Failed\n");
  3778. printf(" Completion status is 0x%lx\n", NtStatus);
  3779. TestStatus = FALSE;
  3780. }
  3781. return TestStatus;
  3782. }
  3783. ///////////////////////////////////////////////////////////////////////////////
  3784. // //
  3785. // Group Object Test Suite //
  3786. // //
  3787. ///////////////////////////////////////////////////////////////////////////////
  3788. BOOLEAN
  3789. GroupTestSuite(
  3790. HANDLE DomainHandle,
  3791. ULONG Pass
  3792. )
  3793. {
  3794. NTSTATUS NtStatus, IgnoreStatus;
  3795. HANDLE GroupHandle1, GroupHandle2, UserHandle1;
  3796. ULONG CountReturned, NameLength, i, MemberCount;
  3797. ULONG UserRid, GroupRid;
  3798. PVOID Buffer, Buffer1, Buffer2;
  3799. SAM_ENUMERATE_HANDLE EnumerationContext;
  3800. PULONG Members, Attributes;
  3801. PSID_NAME_USE LookedUpUses;
  3802. PULONG LookedUpRids;
  3803. UNICODE_STRING AccountNames[10], AccountName;
  3804. STRING AccountNameAnsi;
  3805. BOOLEAN IndividualTestSucceeded, DeleteUser;
  3806. BOOLEAN TestStatus = TRUE;
  3807. if (Pass == 1) {
  3808. //
  3809. // This test suite assumes that lookup and enumeration API funciton
  3810. // properly.
  3811. //
  3812. printf("\n");
  3813. printf("\n");
  3814. printf(" Group (Pass #1) . . . . . . . . . . . . . . . . . . . Test\n");
  3815. ///////////////////////////////////////////////////////////////////////////
  3816. // //
  3817. // Open Group Suite //
  3818. // //
  3819. ///////////////////////////////////////////////////////////////////////////
  3820. printf(" Open Group . . . . . . . . . . . . . . . . . . . . . Suite\n");
  3821. printf(" Open Groups . . . . . . . . . . . . . . . . . . . . . ");
  3822. IndividualTestSucceeded = TRUE;
  3823. EnumerationContext = 0;
  3824. NtStatus = SamEnumerateGroupsInDomain(
  3825. DomainHandle,
  3826. &EnumerationContext,
  3827. &Buffer,
  3828. 12000, // PreferedMaximumLength
  3829. &CountReturned
  3830. );
  3831. TST_SUCCESS_ASSERT(NtStatus);
  3832. ASSERT(Buffer != NULL);
  3833. ASSERT(CountReturned > 0);
  3834. for (i=0; i<CountReturned; i++) {
  3835. NtStatus = SamOpenGroup(
  3836. DomainHandle,
  3837. GROUP_ALL_ACCESS,
  3838. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  3839. &GroupHandle1
  3840. );
  3841. if (NT_SUCCESS(NtStatus)) {
  3842. NtStatus = SamOpenGroup(
  3843. DomainHandle,
  3844. GENERIC_READ,
  3845. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  3846. &GroupHandle2
  3847. );
  3848. if (NT_SUCCESS(NtStatus)) {
  3849. IgnoreStatus = SamCloseHandle( GroupHandle2 );
  3850. ASSERT( NT_SUCCESS(IgnoreStatus) );
  3851. } else {
  3852. printf("Failed\n");
  3853. printf(" Completion status is 0x%lx\n", NtStatus);
  3854. printf(" Failed opening group second time.\n");
  3855. printf(" Rid of account is: 0x%lx\n",
  3856. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId);
  3857. printf(" Name of account is: %wZ\n",
  3858. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name );
  3859. TestStatus = FALSE;
  3860. IndividualTestSucceeded = FALSE;
  3861. }
  3862. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  3863. ASSERT( NT_SUCCESS(IgnoreStatus) );
  3864. } else {
  3865. printf("Failed\n");
  3866. printf(" Completion status is 0x%lx\n", NtStatus);
  3867. printf(" Failed opening group for first time.\n");
  3868. printf(" Rid of account is: 0x%lx\n",
  3869. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId);
  3870. printf(" Name of account is: %wZ\n",
  3871. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name );
  3872. TestStatus = FALSE;
  3873. IndividualTestSucceeded = FALSE;
  3874. }
  3875. if (!IndividualTestSucceeded) {
  3876. printf(" ");
  3877. }
  3878. }
  3879. SamFreeMemory( Buffer );
  3880. if (IndividualTestSucceeded) {
  3881. printf("Succeeded\n");
  3882. }
  3883. ///////////////////////////////////////////////////////////////////////////
  3884. // //
  3885. // Query Group Suite //
  3886. // //
  3887. ///////////////////////////////////////////////////////////////////////////
  3888. printf("\n");
  3889. printf(" Query Group . . . . . . . . . . . . . . . . . . . . . Suite\n");
  3890. printf(" Query Group General Information . . . . . . . . . . . ");
  3891. NtStatus = SamOpenGroup(
  3892. DomainHandle,
  3893. GROUP_READ_INFORMATION,
  3894. DOMAIN_GROUP_RID_USERS,
  3895. &GroupHandle1
  3896. );
  3897. ASSERT(NT_SUCCESS(NtStatus) );
  3898. Buffer = NULL;
  3899. NtStatus = SamQueryInformationGroup(
  3900. GroupHandle1,
  3901. GroupGeneralInformation,
  3902. &Buffer
  3903. );
  3904. if (NT_SUCCESS(NtStatus)) {
  3905. if (Buffer != NULL) {
  3906. if ( (((GROUP_GENERAL_INFORMATION *)Buffer)->Name.MaximumLength > 0) &&
  3907. (((GROUP_GENERAL_INFORMATION *)Buffer)->Name.Buffer != NULL) ) {
  3908. printf("Succeeded\n");
  3909. printf(" Member Count is: 0x%lx\n",
  3910. (((GROUP_GENERAL_INFORMATION *)Buffer)->MemberCount) );
  3911. printf(" Attributes are: 0x%lx\n",
  3912. (((GROUP_GENERAL_INFORMATION *)Buffer)->Attributes) );
  3913. printf(" Group Name is: %wZ\n",
  3914. &(((GROUP_GENERAL_INFORMATION *)Buffer)->Name) );
  3915. } else {
  3916. printf("Failed\n");
  3917. printf(" Group Name not returned.\n");
  3918. TestStatus = FALSE;
  3919. }
  3920. SamFreeMemory( Buffer );
  3921. } else {
  3922. printf("Failed\n");
  3923. printf(" Buffer address not set on return.\n");
  3924. printf(" RPC should have allocated a buffer.\n");
  3925. TestStatus = FALSE;
  3926. }
  3927. } else {
  3928. printf("Failed\n");
  3929. printf(" Completion status is 0x%lx\n", NtStatus);
  3930. TestStatus = FALSE;
  3931. }
  3932. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  3933. ASSERT( NT_SUCCESS(IgnoreStatus) );
  3934. printf(" Query Group Name Information . . . . . . . . . . . . ");
  3935. NtStatus = SamOpenGroup(
  3936. DomainHandle,
  3937. GROUP_READ_INFORMATION,
  3938. DOMAIN_GROUP_RID_USERS,
  3939. &GroupHandle1
  3940. );
  3941. ASSERT(NT_SUCCESS(NtStatus) );
  3942. Buffer = NULL;
  3943. NtStatus = SamQueryInformationGroup(
  3944. GroupHandle1,
  3945. GroupNameInformation,
  3946. &Buffer
  3947. );
  3948. if (NT_SUCCESS(NtStatus)) {
  3949. if (Buffer != NULL) {
  3950. if ( (((GROUP_NAME_INFORMATION *)Buffer)->Name.MaximumLength > 0) &&
  3951. (((GROUP_NAME_INFORMATION *)Buffer)->Name.Buffer != NULL) ) {
  3952. printf("Succeeded\n");
  3953. printf(" Group Name is: %wZ\n",
  3954. &(((GROUP_NAME_INFORMATION *)Buffer)->Name) );
  3955. } else {
  3956. printf("Failed\n");
  3957. printf(" Group Name not returned.\n");
  3958. TestStatus = FALSE;
  3959. }
  3960. SamFreeMemory( Buffer );
  3961. } else {
  3962. printf("Failed\n");
  3963. printf(" Buffer address not set on return.\n");
  3964. printf(" RPC should have allocated a buffer.\n");
  3965. TestStatus = FALSE;
  3966. }
  3967. } else {
  3968. printf("Failed\n");
  3969. printf(" Completion status is 0x%lx\n", NtStatus);
  3970. TestStatus = FALSE;
  3971. }
  3972. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  3973. ASSERT( NT_SUCCESS(IgnoreStatus) );
  3974. printf(" Query Group Admin Comment Information . . . . . . . . ");
  3975. NtStatus = SamOpenGroup(
  3976. DomainHandle,
  3977. GROUP_READ_INFORMATION,
  3978. DOMAIN_GROUP_RID_USERS,
  3979. &GroupHandle1
  3980. );
  3981. ASSERT(NT_SUCCESS(NtStatus) );
  3982. Buffer = NULL;
  3983. NtStatus = SamQueryInformationGroup(
  3984. GroupHandle1,
  3985. GroupAdminCommentInformation,
  3986. &Buffer
  3987. );
  3988. if (NT_SUCCESS(NtStatus)) {
  3989. if (Buffer != NULL) {
  3990. if ( (((GROUP_ADM_COMMENT_INFORMATION *)Buffer)->AdminComment.MaximumLength >= 0) ) {
  3991. printf("Succeeded\n");
  3992. printf(" Group Admin Comment is: %wZ\n",
  3993. &(((GROUP_ADM_COMMENT_INFORMATION *)Buffer)->AdminComment) );
  3994. } else {
  3995. printf("Failed\n");
  3996. printf(" Group Admin Comment not returned.\n");
  3997. TestStatus = FALSE;
  3998. }
  3999. SamFreeMemory( Buffer );
  4000. } else {
  4001. printf("Failed\n");
  4002. printf(" Buffer address not set on return.\n");
  4003. printf(" RPC should have allocated a buffer.\n");
  4004. TestStatus = FALSE;
  4005. }
  4006. } else {
  4007. printf("Failed\n");
  4008. printf(" Completion status is 0x%lx\n", NtStatus);
  4009. TestStatus = FALSE;
  4010. }
  4011. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  4012. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4013. printf(" Query Group Attribute Information . . . . . . . . . . ");
  4014. NtStatus = SamOpenGroup(
  4015. DomainHandle,
  4016. GROUP_READ_INFORMATION,
  4017. DOMAIN_GROUP_RID_USERS,
  4018. &GroupHandle1
  4019. );
  4020. ASSERT(NT_SUCCESS(NtStatus) );
  4021. Buffer = NULL;
  4022. NtStatus = SamQueryInformationGroup(
  4023. GroupHandle1,
  4024. GroupAttributeInformation,
  4025. &Buffer
  4026. );
  4027. if (NT_SUCCESS(NtStatus)) {
  4028. if (Buffer != NULL) {
  4029. printf("Succeeded\n");
  4030. printf(" Attributes are: 0x%lx\n",
  4031. (((GROUP_ATTRIBUTE_INFORMATION *)Buffer)->Attributes) );
  4032. SamFreeMemory( Buffer );
  4033. } else {
  4034. printf("Failed\n");
  4035. printf(" Buffer address not set on return.\n");
  4036. printf(" RPC should have allocated a buffer.\n");
  4037. TestStatus = FALSE;
  4038. }
  4039. } else {
  4040. printf("Failed\n");
  4041. printf(" Completion status is 0x%lx\n", NtStatus);
  4042. TestStatus = FALSE;
  4043. }
  4044. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  4045. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4046. ///////////////////////////////////////////////////////////////////////////
  4047. // //
  4048. // Get Members Of Group Suite //
  4049. // //
  4050. ///////////////////////////////////////////////////////////////////////////
  4051. printf("\n");
  4052. printf(" Get Members . . . . . . . . . . . . . . . . . . . . . Suite\n");
  4053. printf(" Get Members of Well-Known Account . . . . . . . . . . ");
  4054. NtStatus = SamOpenGroup(
  4055. DomainHandle,
  4056. GROUP_LIST_MEMBERS,
  4057. DOMAIN_GROUP_RID_USERS,
  4058. &GroupHandle1
  4059. );
  4060. ASSERT(NT_SUCCESS(NtStatus) );
  4061. Buffer = NULL;
  4062. NtStatus = SamGetMembersInGroup(
  4063. GroupHandle1,
  4064. &Members,
  4065. &Attributes,
  4066. &MemberCount
  4067. );
  4068. if (NT_SUCCESS(NtStatus)) {
  4069. if (Members != NULL || Attributes != NULL) {
  4070. printf("Succeeded\n");
  4071. printf(" Member Count: %d Users\n", MemberCount);
  4072. for ( i=0; i<MemberCount; i++) {
  4073. printf(" User[%d] Rid/Attributes: 0x%lx/0x%lx\n",
  4074. i, Members[i], Attributes[i]);
  4075. }
  4076. SamFreeMemory( Members );
  4077. SamFreeMemory( Attributes );
  4078. } else {
  4079. printf("Failed\n");
  4080. printf(" Buffer address not set on return.\n");
  4081. printf(" RPC should have allocated a buffer.\n");
  4082. TestStatus = FALSE;
  4083. }
  4084. } else {
  4085. printf("Failed\n");
  4086. printf(" Completion status is 0x%lx\n", NtStatus);
  4087. TestStatus = FALSE;
  4088. }
  4089. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  4090. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4091. printf(" Get Members of Empty Group. . . . . . . . . . . . . . ");
  4092. //
  4093. // This group was created earlier in the test
  4094. //
  4095. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  4096. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  4097. TST_SUCCESS_ASSERT(NtStatus);
  4098. NtStatus = SamLookupNamesInDomain(
  4099. DomainHandle,
  4100. 1,
  4101. &AccountNames[0],
  4102. &LookedUpRids,
  4103. &LookedUpUses
  4104. );
  4105. TST_SUCCESS_ASSERT(NtStatus);
  4106. ASSERT(LookedUpUses[0] == SidTypeGroup);
  4107. RtlFreeUnicodeString( &AccountNames[0] );
  4108. GroupHandle1 = NULL;
  4109. NtStatus = SamOpenGroup( DomainHandle, GROUP_LIST_MEMBERS, LookedUpRids[0], &GroupHandle1 );
  4110. TST_SUCCESS_ASSERT(NtStatus);
  4111. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  4112. NtStatus = SamGetMembersInGroup(
  4113. GroupHandle1,
  4114. &Members,
  4115. &Attributes,
  4116. &MemberCount
  4117. );
  4118. if (NT_SUCCESS(NtStatus)) {
  4119. if (MemberCount == 0) {
  4120. printf("Succeeded\n");
  4121. } else {
  4122. printf("Failed\n");
  4123. printf(" Buffer addresses set on return.\n");
  4124. printf(" RPC should have allocated a buffer.\n");
  4125. printf(" Member Count: %d\n", MemberCount);
  4126. for ( i=0; i<MemberCount; i++) {
  4127. printf(" User[%d] Rid/Attributes: 0x%lx/0x%lx\n",
  4128. i, Members[i], Attributes[i]);
  4129. }
  4130. SamFreeMemory( Members );
  4131. SamFreeMemory( Attributes );
  4132. TestStatus = FALSE;
  4133. }
  4134. } else {
  4135. printf("Failed\n");
  4136. printf(" Completion status is 0x%lx\n", NtStatus);
  4137. TestStatus = FALSE;
  4138. }
  4139. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  4140. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4141. ///////////////////////////////////////////////////////////////////////////
  4142. // //
  4143. // Set Group Suite (pass 1) //
  4144. // //
  4145. ///////////////////////////////////////////////////////////////////////////
  4146. printf("\n");
  4147. printf(" Set Group . . . . . . . . . . . . . . . . . . . . . . Suite\n");
  4148. printf(" Set Attribute . . . . . . . . . . . . . . . . . . . . ");
  4149. NtStatus = SamOpenGroup(
  4150. DomainHandle,
  4151. GROUP_WRITE_ACCOUNT | GROUP_READ_INFORMATION,
  4152. DOMAIN_GROUP_RID_USERS,
  4153. &GroupHandle1
  4154. );
  4155. ASSERT(NT_SUCCESS(NtStatus) );
  4156. Buffer1 = NULL;
  4157. NtStatus = SamQueryInformationGroup(
  4158. GroupHandle1,
  4159. GroupAttributeInformation,
  4160. &Buffer1
  4161. );
  4162. TST_SUCCESS_ASSERT(NtStatus);
  4163. ASSERT(Buffer1 != NULL);
  4164. //
  4165. // Change the value and write it back
  4166. //
  4167. ((GROUP_ATTRIBUTE_INFORMATION *)Buffer1)->Attributes ^=
  4168. SE_GROUP_ENABLED_BY_DEFAULT;
  4169. NtStatus = SamSetInformationGroup(
  4170. GroupHandle1,
  4171. GroupAttributeInformation,
  4172. Buffer1
  4173. );
  4174. if (NT_SUCCESS(NtStatus)) {
  4175. //
  4176. // Check the written value to make sure it stuck
  4177. //
  4178. Buffer2 = NULL;
  4179. NtStatus = SamQueryInformationGroup(
  4180. GroupHandle1,
  4181. GroupAttributeInformation,
  4182. &Buffer2
  4183. );
  4184. TST_SUCCESS_ASSERT(NtStatus);
  4185. ASSERT(Buffer2 != NULL);
  4186. if (((GROUP_ATTRIBUTE_INFORMATION *)Buffer1)->Attributes ==
  4187. ((GROUP_ATTRIBUTE_INFORMATION *)Buffer2)->Attributes ) {
  4188. printf("Succeeded\n");
  4189. SamFreeMemory( Buffer2 );
  4190. } else {
  4191. printf("Failed\n");
  4192. printf(" Returned Value Doesn't Match Set Value.\n");
  4193. TestStatus = FALSE;
  4194. }
  4195. } else {
  4196. printf("Failed\n");
  4197. printf(" Completion status is 0x%lx\n", NtStatus);
  4198. TestStatus = FALSE;
  4199. }
  4200. SamFreeMemory( Buffer1 );
  4201. IgnoreStatus = SamCloseHandle( GroupHandle1 );
  4202. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4203. printf(" Set Admin Comment . . . . . . . . . . . . . . . . . . ");
  4204. NtStatus = SamOpenGroup(
  4205. DomainHandle,
  4206. GROUP_WRITE_ACCOUNT | GROUP_READ_INFORMATION,
  4207. DOMAIN_GROUP_RID_USERS,
  4208. &GroupHandle1
  4209. );
  4210. ASSERT(NT_SUCCESS(NtStatus) );
  4211. //
  4212. // Get the current value...
  4213. //
  4214. Buffer1 = NULL;
  4215. NtStatus = SamQueryInformationGroup(
  4216. GroupHandle1,
  4217. GroupAdminCommentInformation,
  4218. &Buffer1
  4219. );
  4220. TST_SUCCESS_ASSERT(NtStatus);
  4221. ASSERT(Buffer1 != NULL);
  4222. //
  4223. // Change the field to a new value and write it out.
  4224. //
  4225. NameLength = ((GROUP_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment.Length;
  4226. if ( NameLength == DummyString1.Length ) {
  4227. ((GROUP_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment = DummyString2;
  4228. } else {
  4229. ((GROUP_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment = DummyString1;
  4230. }
  4231. NtStatus = SamSetInformationGroup(
  4232. GroupHandle1,
  4233. GroupAdminCommentInformation,
  4234. Buffer1
  4235. );
  4236. if ( NT_SUCCESS(NtStatus) ) {
  4237. //
  4238. // Now check that the change was really made...
  4239. //
  4240. Buffer2 = NULL;
  4241. NtStatus = SamQueryInformationGroup(
  4242. GroupHandle1,
  4243. GroupAdminCommentInformation,
  4244. &Buffer2
  4245. );
  4246. ASSERT(NT_SUCCESS( NtStatus ) );
  4247. if (
  4248. !RtlCompareString(
  4249. (PSTRING)&((GROUP_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment,
  4250. (PSTRING)&((GROUP_ADM_COMMENT_INFORMATION *)Buffer2)->AdminComment,
  4251. TRUE)
  4252. ) {
  4253. printf("Succeeded\n");
  4254. } else {
  4255. printf("Failed\n");
  4256. printf(" Value queried doesn't match value written\n");
  4257. printf(" Value Written is %wZ\n",
  4258. (PUNICODE_STRING)&((GROUP_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment);
  4259. printf(" Value Retrieved is %wZ\n",
  4260. (PUNICODE_STRING)&((GROUP_ADM_COMMENT_INFORMATION *)Buffer2)->AdminComment);
  4261. TestStatus = FALSE;
  4262. }
  4263. SamFreeMemory( Buffer1 );
  4264. SamFreeMemory( Buffer2 );
  4265. } else {
  4266. printf("Failed\n");
  4267. printf(" Completion status is 0x%lx\n", NtStatus);
  4268. TestStatus = FALSE;
  4269. SamFreeMemory( Buffer1 );
  4270. }
  4271. } // END PASS #1
  4272. if (Pass == 2) {
  4273. printf("\n");
  4274. printf("\n");
  4275. printf(" Group (Pass #2) . . . . . . . . . . . . . . . . . . . Test\n");
  4276. ///////////////////////////////////////////////////////////////////////////
  4277. // //
  4278. // Delete Group Suite //
  4279. // //
  4280. ///////////////////////////////////////////////////////////////////////////
  4281. printf("\n");
  4282. printf(" Delete Group . . . . . . . . . . . . . . . . . . . . Suite\n");
  4283. printf(" Delete Normal Group . . . . . . . . . . . . . . . . . ");
  4284. //
  4285. // This group was created in pass #1
  4286. //
  4287. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  4288. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  4289. TST_SUCCESS_ASSERT(NtStatus);
  4290. NtStatus = SamLookupNamesInDomain(
  4291. DomainHandle,
  4292. 1,
  4293. &AccountNames[0],
  4294. &LookedUpRids,
  4295. &LookedUpUses
  4296. );
  4297. TST_SUCCESS_ASSERT(NtStatus);
  4298. ASSERT(LookedUpUses[0] == SidTypeGroup);
  4299. RtlFreeUnicodeString( &AccountNames[0] );
  4300. GroupHandle1 = NULL;
  4301. NtStatus = SamOpenGroup( DomainHandle, DELETE, LookedUpRids[0], &GroupHandle1 );
  4302. TST_SUCCESS_ASSERT(NtStatus);
  4303. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  4304. NtStatus = SamDeleteGroup( GroupHandle1 );
  4305. if (NT_SUCCESS(NtStatus)) {
  4306. printf("Succeeded\n");
  4307. } else {
  4308. printf("Failed\n");
  4309. printf(" Completion status is 0x%lx\n", NtStatus);
  4310. TestStatus = FALSE;
  4311. }
  4312. printf(" Delete Well Known Group . . . . . . . . . . . . . . . ");
  4313. GroupHandle1 = NULL;
  4314. NtStatus = SamOpenGroup( DomainHandle, DELETE, DOMAIN_GROUP_RID_USERS, &GroupHandle1 );
  4315. TST_SUCCESS_ASSERT(NtStatus);
  4316. NtStatus = SamDeleteGroup( GroupHandle1 );
  4317. if (NtStatus == STATUS_SPECIAL_ACCOUNT) {
  4318. printf("Succeeded\n");
  4319. } else {
  4320. printf("Failed\n");
  4321. printf(" Completion status is 0x%lx\n", NtStatus);
  4322. TestStatus = FALSE;
  4323. }
  4324. NtStatus = SamCloseHandle( GroupHandle1 );
  4325. ASSERT(NT_SUCCESS(NtStatus));
  4326. printf(" Delete Primary Group Of A User. . . . . . . . . . . . ");
  4327. //
  4328. // Make a user (might already exist)
  4329. // Make a group
  4330. // Make the group the user's primary group
  4331. // Attempt to delete the group
  4332. // Change the user so the group isn't the primary group
  4333. // delete the group
  4334. // If we created the user, delete it.
  4335. //
  4336. // The following user might already exist (from earlier in the test)
  4337. //
  4338. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  4339. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4340. TST_SUCCESS_ASSERT(NtStatus);
  4341. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4342. UserRid = 0;
  4343. UserHandle1 = NULL;
  4344. NtStatus = SamCreateUserInDomain(
  4345. DomainHandle,
  4346. &AccountName,
  4347. USER_ALL_ACCESS,
  4348. &UserHandle1,
  4349. &UserRid
  4350. );
  4351. RtlFreeUnicodeString( &AccountName );
  4352. DeleteUser = TRUE;
  4353. if (NtStatus == STATUS_USER_EXISTS) {
  4354. DeleteUser = FALSE;
  4355. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  4356. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  4357. TST_SUCCESS_ASSERT(NtStatus);
  4358. NtStatus = SamLookupNamesInDomain(
  4359. DomainHandle,
  4360. 1,
  4361. &AccountNames[0],
  4362. &LookedUpRids,
  4363. &LookedUpUses
  4364. );
  4365. RtlFreeUnicodeString( &AccountNames[0] );
  4366. TST_SUCCESS_ASSERT(NtStatus);
  4367. ASSERT(LookedUpUses[0] == SidTypeUser);
  4368. UserRid = LookedUpRids[0];
  4369. NtStatus = SamOpenUser(
  4370. DomainHandle,
  4371. USER_ALL_ACCESS,
  4372. UserRid,
  4373. &UserHandle1);
  4374. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  4375. }
  4376. ASSERT(NT_SUCCESS(NtStatus));
  4377. //
  4378. // create the group
  4379. //
  4380. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  4381. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4382. TST_SUCCESS_ASSERT(NtStatus);
  4383. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4384. GroupRid = 0;
  4385. GroupHandle1 = NULL;
  4386. NtStatus = SamCreateGroupInDomain(
  4387. DomainHandle,
  4388. &AccountName,
  4389. GROUP_ALL_ACCESS,
  4390. &GroupHandle1,
  4391. &GroupRid
  4392. );
  4393. RtlFreeUnicodeString( &AccountName );
  4394. ASSERT(NT_SUCCESS(NtStatus));
  4395. //
  4396. // Make the user a member of this group
  4397. //
  4398. NtStatus = SamAddMemberToGroup(
  4399. GroupHandle1,
  4400. UserRid,
  4401. SE_GROUP_MANDATORY |
  4402. SE_GROUP_ENABLED_BY_DEFAULT |
  4403. SE_GROUP_ENABLED
  4404. );
  4405. ASSERT(NT_SUCCESS(NtStatus));
  4406. //
  4407. // Now try to delete the group
  4408. //
  4409. NtStatus = SamDeleteGroup( GroupHandle1 );
  4410. if (NtStatus == STATUS_MEMBER_IN_GROUP) {
  4411. printf("Succeeded\n");
  4412. } else {
  4413. printf("Failed\n");
  4414. printf(" Completion status is 0x%lx\n", NtStatus);
  4415. TestStatus = FALSE;
  4416. }
  4417. //
  4418. // Now get rid of the group and possibly the user account
  4419. //
  4420. NtStatus = SamRemoveMemberFromGroup(GroupHandle1, UserRid);
  4421. ASSERT(NT_SUCCESS(NtStatus));
  4422. NtStatus = SamDeleteGroup( GroupHandle1 );
  4423. ASSERT(NT_SUCCESS(NtStatus));
  4424. if (DeleteUser == TRUE) {
  4425. NtStatus = SamDeleteUser( UserHandle1 );
  4426. ASSERT(NT_SUCCESS(NtStatus));
  4427. } else {
  4428. NtStatus = SamCloseHandle( UserHandle1 );
  4429. ASSERT(NT_SUCCESS(NtStatus));
  4430. }
  4431. ///////////////////////////////////////////////////////////////////////////
  4432. // //
  4433. // Add/Remove Member Suite //
  4434. // //
  4435. ///////////////////////////////////////////////////////////////////////////
  4436. printf("\n");
  4437. printf(" Add/Remove Member Suite . . . . . . . . . . . . . . . Suite\n");
  4438. printf(" Add Member . . . . . . . . . . . . . . . . . . . . . ");
  4439. //
  4440. // This test sets things up for the next test
  4441. //
  4442. //
  4443. // The following user might already exist (from earlier in the test)
  4444. //
  4445. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  4446. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4447. TST_SUCCESS_ASSERT(NtStatus);
  4448. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4449. UserRid = 0;
  4450. UserHandle1 = NULL;
  4451. NtStatus = SamCreateUserInDomain(
  4452. DomainHandle,
  4453. &AccountName,
  4454. USER_ALL_ACCESS,
  4455. &UserHandle1,
  4456. &UserRid
  4457. );
  4458. RtlFreeUnicodeString( &AccountName );
  4459. DeleteUser = TRUE;
  4460. if (NtStatus == STATUS_USER_EXISTS) {
  4461. DeleteUser = FALSE;
  4462. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  4463. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  4464. TST_SUCCESS_ASSERT(NtStatus);
  4465. NtStatus = SamLookupNamesInDomain(
  4466. DomainHandle,
  4467. 1,
  4468. &AccountNames[0],
  4469. &LookedUpRids,
  4470. &LookedUpUses
  4471. );
  4472. RtlFreeUnicodeString( &AccountNames[0] );
  4473. TST_SUCCESS_ASSERT(NtStatus);
  4474. ASSERT(LookedUpUses[0] == SidTypeUser);
  4475. UserRid = LookedUpRids[0];
  4476. NtStatus = SamOpenUser(
  4477. DomainHandle,
  4478. USER_ALL_ACCESS,
  4479. UserRid,
  4480. &UserHandle1);
  4481. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  4482. }
  4483. ASSERT(NT_SUCCESS(NtStatus));
  4484. //
  4485. // create the group
  4486. //
  4487. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  4488. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4489. TST_SUCCESS_ASSERT(NtStatus);
  4490. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4491. GroupRid = 0;
  4492. GroupHandle1 = NULL;
  4493. NtStatus = SamCreateGroupInDomain(
  4494. DomainHandle,
  4495. &AccountName,
  4496. GROUP_ALL_ACCESS,
  4497. &GroupHandle1,
  4498. &GroupRid
  4499. );
  4500. RtlFreeUnicodeString( &AccountName );
  4501. ASSERT(NT_SUCCESS(NtStatus));
  4502. //
  4503. // Make the user a member of this group
  4504. //
  4505. NtStatus = SamAddMemberToGroup(
  4506. GroupHandle1,
  4507. UserRid,
  4508. SE_GROUP_MANDATORY |
  4509. SE_GROUP_ENABLED_BY_DEFAULT |
  4510. SE_GROUP_ENABLED
  4511. );
  4512. if (NT_SUCCESS(NtStatus)) {
  4513. NtStatus = SamGetMembersInGroup(
  4514. GroupHandle1,
  4515. &Members,
  4516. &Attributes,
  4517. &MemberCount
  4518. );
  4519. ASSERT(NT_SUCCESS(NtStatus));
  4520. NtStatus = STATUS_MEMBER_NOT_IN_GROUP;
  4521. for ( i=0; i<MemberCount; i++) {
  4522. if (Members[i] == UserRid) {
  4523. NtStatus = STATUS_SUCCESS;
  4524. break;
  4525. }
  4526. }
  4527. if (NT_SUCCESS(NtStatus)) {
  4528. if (Attributes[i] == SE_GROUP_MANDATORY |
  4529. SE_GROUP_ENABLED_BY_DEFAULT |
  4530. SE_GROUP_ENABLED) {
  4531. printf("Succeeded\n");
  4532. } else {
  4533. printf("Failed\n");
  4534. printf("Member Added but attributes don't match expected value.\n");
  4535. printf("Expected value: 0x%lx\n",(SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED));
  4536. printf("Retrieved value: 0x%lx\n",Attributes[i]);
  4537. TestStatus = FALSE;
  4538. }
  4539. } else {
  4540. printf("Failed\n");
  4541. printf("Service returned SUCCESS, but user not in member list for group.\n");
  4542. TestStatus = FALSE;
  4543. }
  4544. if (Members != NULL) {
  4545. SamFreeMemory( Members );
  4546. SamFreeMemory( Attributes );
  4547. }
  4548. } else {
  4549. printf("Failed\n");
  4550. printf(" Completion status is 0x%lx\n", NtStatus);
  4551. TestStatus = FALSE;
  4552. }
  4553. printf(" Remove Member . . . . . . . . . . . . . . . . . . . . ");
  4554. //
  4555. // The previous test sets this one up.
  4556. //
  4557. //
  4558. // Now try to remove the user from the group
  4559. //
  4560. NtStatus = SamRemoveMemberFromGroup(GroupHandle1, UserRid);
  4561. if (NT_SUCCESS(NtStatus)) {
  4562. NtStatus = SamGetMembersInGroup(
  4563. GroupHandle1,
  4564. &Members,
  4565. &Attributes,
  4566. &MemberCount
  4567. );
  4568. ASSERT(NT_SUCCESS(NtStatus));
  4569. for ( i=0; i<MemberCount; i++) {
  4570. if (Members[i] == UserRid) {
  4571. NtStatus = STATUS_MEMBER_IN_GROUP;
  4572. break;
  4573. }
  4574. }
  4575. if (NT_SUCCESS(NtStatus)) {
  4576. printf("Succeeded\n");
  4577. } else {
  4578. printf("Failed\n");
  4579. printf("Service returned SUCCESS, but user still in member list for group.\n");
  4580. TestStatus = FALSE;
  4581. }
  4582. SamFreeMemory( Members );
  4583. SamFreeMemory( Attributes );
  4584. } else {
  4585. printf("Failed\n");
  4586. printf(" Completion status is 0x%lx\n", NtStatus);
  4587. TestStatus = FALSE;
  4588. }
  4589. //
  4590. // and clean up the user and group accounts
  4591. //
  4592. NtStatus = SamDeleteGroup( GroupHandle1 );
  4593. ASSERT(NT_SUCCESS(NtStatus));
  4594. if (DeleteUser == TRUE) {
  4595. NtStatus = SamDeleteUser( UserHandle1 );
  4596. ASSERT(NT_SUCCESS(NtStatus));
  4597. } else {
  4598. NtStatus = SamCloseHandle( UserHandle1 );
  4599. ASSERT(NT_SUCCESS(NtStatus));
  4600. }
  4601. printf(" Add Non-Existant Member . . . . . . . . . . . . . . . ");
  4602. //
  4603. // create the group
  4604. //
  4605. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  4606. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4607. TST_SUCCESS_ASSERT(NtStatus);
  4608. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4609. GroupRid = 0;
  4610. GroupHandle1 = NULL;
  4611. NtStatus = SamCreateGroupInDomain(
  4612. DomainHandle,
  4613. &AccountName,
  4614. GROUP_ALL_ACCESS,
  4615. &GroupHandle1,
  4616. &GroupRid
  4617. );
  4618. RtlFreeUnicodeString( &AccountName );
  4619. ASSERT(NT_SUCCESS(NtStatus));
  4620. //
  4621. // Specify a non-existant user be added to this group
  4622. //
  4623. UserRid = 30732579; // Pretty sure this user doesn't exist.
  4624. NtStatus = SamAddMemberToGroup(
  4625. GroupHandle1,
  4626. UserRid,
  4627. SE_GROUP_MANDATORY |
  4628. SE_GROUP_ENABLED_BY_DEFAULT |
  4629. SE_GROUP_ENABLED
  4630. );
  4631. if (NtStatus == STATUS_NO_SUCH_USER) {
  4632. printf("Succeeded\n");
  4633. } else {
  4634. printf("Failed\n");
  4635. printf(" Completion status is 0x%lx\n", NtStatus);
  4636. TestStatus = FALSE;
  4637. }
  4638. NtStatus = SamDeleteGroup( GroupHandle1 );
  4639. ASSERT(NT_SUCCESS(NtStatus));
  4640. printf(" Remove Non-existant Member . . . . . . . . . . . . . ");
  4641. //
  4642. // create the group
  4643. //
  4644. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  4645. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4646. TST_SUCCESS_ASSERT(NtStatus);
  4647. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4648. GroupRid = 0;
  4649. GroupHandle1 = NULL;
  4650. NtStatus = SamCreateGroupInDomain(
  4651. DomainHandle,
  4652. &AccountName,
  4653. GROUP_ALL_ACCESS,
  4654. &GroupHandle1,
  4655. &GroupRid
  4656. );
  4657. RtlFreeUnicodeString( &AccountName );
  4658. ASSERT(NT_SUCCESS(NtStatus));
  4659. //
  4660. // Specify a non-existant user be removed from this group
  4661. //
  4662. UserRid = 30732579; // Pretty sure this user doesn't exist.
  4663. NtStatus = SamRemoveMemberFromGroup( GroupHandle1, UserRid );
  4664. if (NtStatus == STATUS_NO_SUCH_USER) {
  4665. printf("Succeeded\n");
  4666. } else {
  4667. printf("Failed\n");
  4668. printf(" Completion status is 0x%lx\n", NtStatus);
  4669. TestStatus = FALSE;
  4670. }
  4671. NtStatus = SamDeleteGroup( GroupHandle1 );
  4672. ASSERT(NT_SUCCESS(NtStatus));
  4673. printf(" Remove Primary Group Of Member . . . . . . . . . . . ");
  4674. //
  4675. // Make a user (might already exist)
  4676. // Make a group
  4677. // Make the group the user's primary group
  4678. // Attempt to remove the group (should fail)
  4679. // Change the user so the group isn't the primary group
  4680. // remove the group
  4681. // delete the group
  4682. // If we created the user, delete it.
  4683. //
  4684. // The following user might already exist (from earlier in the test)
  4685. //
  4686. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  4687. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4688. TST_SUCCESS_ASSERT(NtStatus);
  4689. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4690. UserRid = 0;
  4691. UserHandle1 = NULL;
  4692. NtStatus = SamCreateUserInDomain(
  4693. DomainHandle,
  4694. &AccountName,
  4695. USER_ALL_ACCESS,
  4696. &UserHandle1,
  4697. &UserRid
  4698. );
  4699. RtlFreeUnicodeString( &AccountName );
  4700. DeleteUser = TRUE;
  4701. if (NtStatus == STATUS_USER_EXISTS) {
  4702. DeleteUser = FALSE;
  4703. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  4704. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  4705. TST_SUCCESS_ASSERT(NtStatus);
  4706. NtStatus = SamLookupNamesInDomain(
  4707. DomainHandle,
  4708. 1,
  4709. &AccountNames[0],
  4710. &LookedUpRids,
  4711. &LookedUpUses
  4712. );
  4713. RtlFreeUnicodeString( &AccountNames[0] );
  4714. TST_SUCCESS_ASSERT(NtStatus);
  4715. ASSERT(LookedUpUses[0] == SidTypeUser);
  4716. UserRid = LookedUpRids[0];
  4717. NtStatus = SamOpenUser(
  4718. DomainHandle,
  4719. USER_ALL_ACCESS,
  4720. UserRid,
  4721. &UserHandle1);
  4722. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  4723. }
  4724. ASSERT(NT_SUCCESS(NtStatus));
  4725. //
  4726. // create the group
  4727. //
  4728. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  4729. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  4730. TST_SUCCESS_ASSERT(NtStatus);
  4731. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  4732. GroupRid = 0;
  4733. GroupHandle1 = NULL;
  4734. NtStatus = SamCreateGroupInDomain(
  4735. DomainHandle,
  4736. &AccountName,
  4737. GROUP_ALL_ACCESS,
  4738. &GroupHandle1,
  4739. &GroupRid
  4740. );
  4741. RtlFreeUnicodeString( &AccountName );
  4742. ASSERT(NT_SUCCESS(NtStatus));
  4743. //
  4744. // Make the user a member of this group
  4745. //
  4746. NtStatus = SamAddMemberToGroup(
  4747. GroupHandle1,
  4748. UserRid,
  4749. SE_GROUP_MANDATORY |
  4750. SE_GROUP_ENABLED_BY_DEFAULT |
  4751. SE_GROUP_ENABLED
  4752. );
  4753. ASSERT(NT_SUCCESS(NtStatus));
  4754. //
  4755. // Set the user's primary group Id to be this group
  4756. //
  4757. NtStatus = SamSetInformationUser(
  4758. UserHandle1,
  4759. UserPrimaryGroupInformation,
  4760. &GroupRid
  4761. );
  4762. ASSERT(NT_SUCCESS(NtStatus));
  4763. //
  4764. // Now try to remove the user from the group
  4765. //
  4766. NtStatus = SamRemoveMemberFromGroup(GroupHandle1, UserRid);
  4767. if (NtStatus == STATUS_MEMBERS_PRIMARY_GROUP) {
  4768. printf("Succeeded\n");
  4769. } else {
  4770. printf("Failed\n");
  4771. printf(" Completion status is 0x%lx\n", NtStatus);
  4772. TestStatus = FALSE;
  4773. }
  4774. //
  4775. // Set the user's primary group Id back and remove the user
  4776. // from the group
  4777. //
  4778. GroupRid = DOMAIN_GROUP_RID_USERS;
  4779. NtStatus = SamSetInformationUser(
  4780. UserHandle1,
  4781. UserPrimaryGroupInformation,
  4782. &GroupRid
  4783. );
  4784. ASSERT(NT_SUCCESS(NtStatus));
  4785. NtStatus = SamRemoveMemberFromGroup(GroupHandle1, UserRid);
  4786. ASSERT(NT_SUCCESS(NtStatus));
  4787. //
  4788. // Now get rid of the group and possibly the user account
  4789. //
  4790. NtStatus = SamDeleteGroup( GroupHandle1 );
  4791. ASSERT(NT_SUCCESS(NtStatus));
  4792. if (DeleteUser == TRUE) {
  4793. NtStatus = SamDeleteUser( UserHandle1 );
  4794. ASSERT(NT_SUCCESS(NtStatus));
  4795. } else {
  4796. NtStatus = SamCloseHandle( UserHandle1 );
  4797. ASSERT(NT_SUCCESS(NtStatus));
  4798. }
  4799. ///////////////////////////////////////////////////////////////////////////
  4800. // //
  4801. // Set Group Suite (pass 2) //
  4802. // //
  4803. ///////////////////////////////////////////////////////////////////////////
  4804. printf("\n");
  4805. printf(" Set Group . . . . . . . . . . . . . . . . . . . . . . Suite\n");
  4806. printf(" Set Name . . . . . . . . . . . . . . . . . . . . . . ");
  4807. printf("(Untested)\n");
  4808. printf(" Set Name Of Well-Known Account . . . . . . . . . . . ");
  4809. printf("(Untested)\n");
  4810. }
  4811. return(TestStatus);
  4812. }
  4813. ///////////////////////////////////////////////////////////////////////////////
  4814. // //
  4815. // Alias Object Test Suite //
  4816. // //
  4817. ///////////////////////////////////////////////////////////////////////////////
  4818. BOOLEAN
  4819. AliasTestSuite(
  4820. HANDLE DomainHandle,
  4821. HANDLE BuiltinDomainHandle,
  4822. PSID DomainSid,
  4823. ULONG Pass
  4824. )
  4825. {
  4826. NTSTATUS NtStatus, IgnoreStatus;
  4827. HANDLE AdminAliasHandle, AliasHandle1, AliasHandle2, UserHandle1, UserHandle2, UserHandle3;
  4828. ULONG CountReturned, i, MemberCount;
  4829. ULONG UserRid, UserRid2, UserRid3, AliasRid, AliasRid2;
  4830. PVOID Buffer, Buffer1, Buffer2;
  4831. ULONG NameLength;
  4832. SAM_ENUMERATE_HANDLE EnumerationContext;
  4833. PULONG Members;
  4834. PSID *AliasMembers;
  4835. PSID_NAME_USE LookedUpUses;
  4836. PULONG LookedUpRids;
  4837. UNICODE_STRING AccountNames[10], AccountName;
  4838. STRING AccountNameAnsi;
  4839. PSID UserSid1, UserSid2, GroupSid;
  4840. BOOLEAN IndividualTestSucceeded, DeleteUser;
  4841. BOOLEAN TestStatus = TRUE;
  4842. if (Pass == 1) {
  4843. //
  4844. // This test suite assumes that lookup and enumeration API funciton
  4845. // properly.
  4846. //
  4847. printf("\n");
  4848. printf("\n");
  4849. printf(" Alias (Pass #1) . . . . . . . . . . . . . . . . . . . Test\n");
  4850. ///////////////////////////////////////////////////////////////////////////
  4851. // //
  4852. // Open Alias Suite //
  4853. // //
  4854. ///////////////////////////////////////////////////////////////////////////
  4855. printf(" Open Alias . . . . . . . . . . . . . . . . . . . . . Suite\n");
  4856. printf(" Open Aliases . . . . . . . . . . . . . . . . . . . . . ");
  4857. IndividualTestSucceeded = TRUE;
  4858. EnumerationContext = 0;
  4859. NtStatus = SamEnumerateAliasesInDomain(
  4860. DomainHandle,
  4861. &EnumerationContext,
  4862. &Buffer,
  4863. 12000, // PreferedMaximumLength
  4864. &CountReturned
  4865. );
  4866. TST_SUCCESS_ASSERT(NtStatus);
  4867. ASSERT(Buffer != NULL);
  4868. ASSERT(CountReturned > 0);
  4869. for (i=0; i<CountReturned; i++) {
  4870. NtStatus = SamOpenAlias(
  4871. DomainHandle,
  4872. ALIAS_ALL_ACCESS,
  4873. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  4874. &AliasHandle1
  4875. );
  4876. if (NT_SUCCESS(NtStatus)) {
  4877. NtStatus = SamOpenAlias(
  4878. DomainHandle,
  4879. GENERIC_READ,
  4880. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  4881. &AliasHandle2
  4882. );
  4883. if (NT_SUCCESS(NtStatus)) {
  4884. IgnoreStatus = SamCloseHandle( AliasHandle2 );
  4885. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4886. } else {
  4887. printf("Failed\n");
  4888. printf(" Completion status is 0x%lx\n", NtStatus);
  4889. printf(" Failed opening alias second time.\n");
  4890. printf(" Rid of account is: 0x%lx\n",
  4891. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId);
  4892. printf(" Name of account is: %wZ\n",
  4893. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name );
  4894. TestStatus = FALSE;
  4895. IndividualTestSucceeded = FALSE;
  4896. }
  4897. IgnoreStatus = SamCloseHandle( AliasHandle1 );
  4898. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4899. } else {
  4900. printf("Failed\n");
  4901. printf(" Completion status is 0x%lx\n", NtStatus);
  4902. printf(" Failed opening alias for first time.\n");
  4903. printf(" Rid of account is: 0x%lx\n",
  4904. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId);
  4905. printf(" Name of account is: %wZ\n",
  4906. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name );
  4907. TestStatus = FALSE;
  4908. IndividualTestSucceeded = FALSE;
  4909. }
  4910. if (!IndividualTestSucceeded) {
  4911. printf(" ");
  4912. }
  4913. }
  4914. SamFreeMemory( Buffer );
  4915. if (IndividualTestSucceeded) {
  4916. printf("Succeeded\n");
  4917. }
  4918. ///////////////////////////////////////////////////////////////////////////
  4919. // //
  4920. // Query Alias Suite //
  4921. // //
  4922. ///////////////////////////////////////////////////////////////////////////
  4923. //
  4924. // Get the rid of an alias created earlier in the test
  4925. //
  4926. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  4927. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  4928. TST_SUCCESS_ASSERT(NtStatus);
  4929. NtStatus = SamLookupNamesInDomain(
  4930. DomainHandle,
  4931. 1,
  4932. &AccountNames[0],
  4933. &LookedUpRids,
  4934. &LookedUpUses
  4935. );
  4936. TST_SUCCESS_ASSERT(NtStatus);
  4937. ASSERT(LookedUpUses[0] == SidTypeAlias);
  4938. RtlFreeUnicodeString( &AccountNames[0] );
  4939. AliasRid = LookedUpRids[0];
  4940. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  4941. printf("\n");
  4942. printf(" Query Alias . . . . . . . . . . . . . . . . . . . . . Suite\n");
  4943. printf(" Query Alias General Information . . . . . . . . . . . ");
  4944. NtStatus = SamOpenAlias(
  4945. DomainHandle,
  4946. ALIAS_READ_INFORMATION,
  4947. AliasRid,
  4948. &AliasHandle1
  4949. );
  4950. ASSERT(NT_SUCCESS(NtStatus) );
  4951. Buffer = NULL;
  4952. NtStatus = SamQueryInformationAlias(
  4953. AliasHandle1,
  4954. AliasGeneralInformation,
  4955. &Buffer
  4956. );
  4957. if (NT_SUCCESS(NtStatus)) {
  4958. if (Buffer != NULL) {
  4959. if ( (((ALIAS_GENERAL_INFORMATION *)Buffer)->Name.MaximumLength > 0) &&
  4960. (((ALIAS_GENERAL_INFORMATION *)Buffer)->Name.Buffer != NULL) ) {
  4961. printf("Succeeded\n");
  4962. printf(" Member Count is: 0x%lx\n",
  4963. (((ALIAS_GENERAL_INFORMATION *)Buffer)->MemberCount) );
  4964. printf(" Alias Name is: %wZ\n",
  4965. &(((ALIAS_GENERAL_INFORMATION *)Buffer)->Name) );
  4966. } else {
  4967. printf("Failed\n");
  4968. printf(" Alias Name not returned.\n");
  4969. TestStatus = FALSE;
  4970. }
  4971. SamFreeMemory( Buffer );
  4972. } else {
  4973. printf("Failed\n");
  4974. printf(" Buffer address not set on return.\n");
  4975. printf(" RPC should have allocated a buffer.\n");
  4976. TestStatus = FALSE;
  4977. }
  4978. } else {
  4979. printf("Failed\n");
  4980. printf(" Completion status is 0x%lx\n", NtStatus);
  4981. TestStatus = FALSE;
  4982. }
  4983. IgnoreStatus = SamCloseHandle( AliasHandle1 );
  4984. ASSERT( NT_SUCCESS(IgnoreStatus) );
  4985. printf(" Query Alias Name Information . . . . . . . . . . . . ");
  4986. NtStatus = SamOpenAlias(
  4987. DomainHandle,
  4988. ALIAS_READ_INFORMATION,
  4989. AliasRid,
  4990. &AliasHandle1
  4991. );
  4992. ASSERT(NT_SUCCESS(NtStatus) );
  4993. Buffer = NULL;
  4994. NtStatus = SamQueryInformationAlias(
  4995. AliasHandle1,
  4996. AliasNameInformation,
  4997. &Buffer
  4998. );
  4999. if (NT_SUCCESS(NtStatus)) {
  5000. if (Buffer != NULL) {
  5001. if ( (((ALIAS_NAME_INFORMATION *)Buffer)->Name.MaximumLength > 0) &&
  5002. (((ALIAS_NAME_INFORMATION *)Buffer)->Name.Buffer != NULL) ) {
  5003. printf("Succeeded\n");
  5004. printf(" Alias Name is: %wZ\n",
  5005. &(((ALIAS_NAME_INFORMATION *)Buffer)->Name) );
  5006. } else {
  5007. printf("Failed\n");
  5008. printf(" Alias Name not returned.\n");
  5009. TestStatus = FALSE;
  5010. }
  5011. SamFreeMemory( Buffer );
  5012. } else {
  5013. printf("Failed\n");
  5014. printf(" Buffer address not set on return.\n");
  5015. printf(" RPC should have allocated a buffer.\n");
  5016. TestStatus = FALSE;
  5017. }
  5018. } else {
  5019. printf("Failed\n");
  5020. printf(" Completion status is 0x%lx\n", NtStatus);
  5021. TestStatus = FALSE;
  5022. }
  5023. IgnoreStatus = SamCloseHandle( AliasHandle1 );
  5024. ASSERT( NT_SUCCESS(IgnoreStatus) );
  5025. printf(" Query Alias Admin Comment Information . . . . . . . . ");
  5026. NtStatus = SamOpenAlias(
  5027. DomainHandle,
  5028. ALIAS_READ_INFORMATION,
  5029. AliasRid,
  5030. &AliasHandle1
  5031. );
  5032. ASSERT(NT_SUCCESS(NtStatus) );
  5033. Buffer = NULL;
  5034. NtStatus = SamQueryInformationAlias(
  5035. AliasHandle1,
  5036. AliasAdminCommentInformation,
  5037. &Buffer
  5038. );
  5039. if (NT_SUCCESS(NtStatus)) {
  5040. if (Buffer != NULL) {
  5041. if ( (((ALIAS_ADM_COMMENT_INFORMATION *)Buffer)->AdminComment.MaximumLength >= 0) ) {
  5042. printf("Succeeded\n");
  5043. printf(" Alias Admin Comment is: %wZ\n",
  5044. &(((ALIAS_ADM_COMMENT_INFORMATION *)Buffer)->AdminComment) );
  5045. } else {
  5046. printf("Failed\n");
  5047. printf(" Alias Admin Comment not returned.\n");
  5048. TestStatus = FALSE;
  5049. }
  5050. SamFreeMemory( Buffer );
  5051. } else {
  5052. printf("Failed\n");
  5053. printf(" Buffer address not set on return.\n");
  5054. printf(" RPC should have allocated a buffer.\n");
  5055. TestStatus = FALSE;
  5056. }
  5057. } else {
  5058. printf("Failed\n");
  5059. printf(" Completion status is 0x%lx\n", NtStatus);
  5060. TestStatus = FALSE;
  5061. }
  5062. IgnoreStatus = SamCloseHandle( AliasHandle1 );
  5063. ASSERT( NT_SUCCESS(IgnoreStatus) );
  5064. ///////////////////////////////////////////////////////////////////////////
  5065. // //
  5066. // Get Members Of Alias Suite //
  5067. // //
  5068. ///////////////////////////////////////////////////////////////////////////
  5069. printf("\n");
  5070. printf(" Get Members . . . . . . . . . . . . . . . . . . . . . Suite\n");
  5071. #ifdef LATER // ALIAS_LATER - well-know aliases ?
  5072. davidc/chads - this needs to access the builtin domain.
  5073. printf(" Get Members of Well-Known Account . . . . . . . . . . ");
  5074. NtStatus = SamOpenAlias(
  5075. DomainHandle,
  5076. ALIAS_LIST_MEMBERS,
  5077. DOMAIN_ALIAS_RID_ADMINS,
  5078. &AliasHandle1
  5079. );
  5080. ASSERT(NT_SUCCESS(NtStatus) );
  5081. Buffer = NULL;
  5082. NtStatus = SamGetMembersInAlias(
  5083. AliasHandle1,
  5084. &AliasMembers,
  5085. &Attributes,
  5086. &MemberCount
  5087. );
  5088. if (NT_SUCCESS(NtStatus)) {
  5089. if (Members != NULL || Attributes != NULL) {
  5090. printf("Succeeded\n");
  5091. printf(" Member Count: %d Users\n", MemberCount);
  5092. for ( i=0; i<MemberCount; i++) {
  5093. // printf(" User[%d] Sid: 0x%lx\n",
  5094. // i, Members[i]);
  5095. }
  5096. SamFreeMemory( AliasMembers );
  5097. SamFreeMemory( Attributes );
  5098. } else {
  5099. printf("Failed\n");
  5100. printf(" Buffer address not set on return.\n");
  5101. printf(" RPC should have allocated a buffer.\n");
  5102. TestStatus = FALSE;
  5103. }
  5104. } else {
  5105. printf("Failed\n");
  5106. printf(" Completion status is 0x%lx\n", NtStatus);
  5107. TestStatus = FALSE;
  5108. }
  5109. IgnoreStatus = SamCloseHandle( AliasHandle1 );
  5110. ASSERT( NT_SUCCESS(IgnoreStatus) );
  5111. #endif
  5112. printf(" Get Members of Empty Alias. . . . . . . . . . . . . . ");
  5113. //
  5114. // This alias was created earlier in the test
  5115. //
  5116. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  5117. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  5118. TST_SUCCESS_ASSERT(NtStatus);
  5119. NtStatus = SamLookupNamesInDomain(
  5120. DomainHandle,
  5121. 1,
  5122. &AccountNames[0],
  5123. &LookedUpRids,
  5124. &LookedUpUses
  5125. );
  5126. TST_SUCCESS_ASSERT(NtStatus);
  5127. ASSERT(LookedUpUses[0] == SidTypeAlias);
  5128. RtlFreeUnicodeString( &AccountNames[0] );
  5129. AliasHandle1 = NULL;
  5130. NtStatus = SamOpenAlias( DomainHandle, ALIAS_LIST_MEMBERS, LookedUpRids[0], &AliasHandle1 );
  5131. TST_SUCCESS_ASSERT(NtStatus);
  5132. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  5133. NtStatus = SamGetMembersInAlias(
  5134. AliasHandle1,
  5135. &AliasMembers,
  5136. &MemberCount
  5137. );
  5138. if (NT_SUCCESS(NtStatus)) {
  5139. if (MemberCount == 0) {
  5140. printf("Succeeded\n");
  5141. } else {
  5142. printf("Failed\n");
  5143. printf(" Member Count > 0 : %d\n", MemberCount);
  5144. for ( i=0; i<MemberCount; i++) {
  5145. // printf(" User[%d] Rid/Attributes: 0x%lx/0x%lx\n",
  5146. // i, Members[i], Attributes[i]);
  5147. }
  5148. SamFreeMemory( AliasMembers );
  5149. TestStatus = FALSE;
  5150. }
  5151. } else {
  5152. printf("Failed\n");
  5153. printf(" Completion status is 0x%lx\n", NtStatus);
  5154. TestStatus = FALSE;
  5155. }
  5156. IgnoreStatus = SamCloseHandle( AliasHandle1 );
  5157. ASSERT( NT_SUCCESS(IgnoreStatus) );
  5158. ///////////////////////////////////////////////////////////////////////////
  5159. // //
  5160. // Set Alias Suite (pass 1) //
  5161. // //
  5162. ///////////////////////////////////////////////////////////////////////////
  5163. printf("\n");
  5164. printf(" Set Alias . . . . . . . . . . . . . . . . . . . . . . Suite\n");
  5165. //
  5166. // Get the rid of an alias created earlier in the test
  5167. //
  5168. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  5169. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  5170. TST_SUCCESS_ASSERT(NtStatus);
  5171. NtStatus = SamLookupNamesInDomain(
  5172. DomainHandle,
  5173. 1,
  5174. &AccountNames[0],
  5175. &LookedUpRids,
  5176. &LookedUpUses
  5177. );
  5178. TST_SUCCESS_ASSERT(NtStatus);
  5179. ASSERT(LookedUpUses[0] == SidTypeAlias);
  5180. RtlFreeUnicodeString( &AccountNames[0] );
  5181. AliasRid = LookedUpRids[0];
  5182. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  5183. printf(" Set Admin Comment . . . . . . . . . . . . . . . . . . ");
  5184. NtStatus = SamOpenAlias(
  5185. DomainHandle,
  5186. ALIAS_WRITE_ACCOUNT | ALIAS_READ_INFORMATION,
  5187. AliasRid,
  5188. &AliasHandle1
  5189. );
  5190. ASSERT(NT_SUCCESS(NtStatus) );
  5191. //
  5192. // Get the current value...
  5193. //
  5194. Buffer1 = NULL;
  5195. NtStatus = SamQueryInformationAlias(
  5196. AliasHandle1,
  5197. AliasAdminCommentInformation,
  5198. &Buffer1
  5199. );
  5200. TST_SUCCESS_ASSERT(NtStatus);
  5201. ASSERT(Buffer1 != NULL);
  5202. //
  5203. // Change the field to a new value and write it out.
  5204. //
  5205. NameLength = ((ALIAS_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment.Length;
  5206. if ( NameLength == DummyString1.Length ) {
  5207. ((ALIAS_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment = DummyString2;
  5208. } else {
  5209. ((ALIAS_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment = DummyString1;
  5210. }
  5211. NtStatus = SamSetInformationAlias(
  5212. AliasHandle1,
  5213. AliasAdminCommentInformation,
  5214. Buffer1
  5215. );
  5216. if ( NT_SUCCESS(NtStatus) ) {
  5217. //
  5218. // Now check that the change was really made...
  5219. //
  5220. Buffer2 = NULL;
  5221. NtStatus = SamQueryInformationAlias(
  5222. AliasHandle1,
  5223. AliasAdminCommentInformation,
  5224. &Buffer2
  5225. );
  5226. ASSERT(NT_SUCCESS( NtStatus ) );
  5227. if (
  5228. !RtlCompareString(
  5229. (PSTRING)&((ALIAS_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment,
  5230. (PSTRING)&((ALIAS_ADM_COMMENT_INFORMATION *)Buffer2)->AdminComment,
  5231. TRUE)
  5232. ) {
  5233. printf("Succeeded\n");
  5234. } else {
  5235. printf("Failed\n");
  5236. printf(" Value queried doesn't match value written\n");
  5237. printf(" Value Written is %wZ\n",
  5238. (PUNICODE_STRING)&((ALIAS_ADM_COMMENT_INFORMATION *)Buffer1)->AdminComment);
  5239. printf(" Value Retrieved is %wZ\n",
  5240. (PUNICODE_STRING)&((ALIAS_ADM_COMMENT_INFORMATION *)Buffer2)->AdminComment);
  5241. TestStatus = FALSE;
  5242. }
  5243. SamFreeMemory( Buffer1 );
  5244. SamFreeMemory( Buffer2 );
  5245. } else {
  5246. printf("Failed\n");
  5247. printf(" Completion status is 0x%lx\n", NtStatus);
  5248. TestStatus = FALSE;
  5249. SamFreeMemory( Buffer1 );
  5250. }
  5251. } // END PASS #1
  5252. if (Pass == 2) {
  5253. printf("\n");
  5254. printf("\n");
  5255. printf(" Alias (Pass #2) . . . . . . . . . . . . . . . . . . . Test\n");
  5256. ///////////////////////////////////////////////////////////////////////////
  5257. // //
  5258. // Delete Alias Suite //
  5259. // //
  5260. ///////////////////////////////////////////////////////////////////////////
  5261. printf("\n");
  5262. printf(" Delete Alias . . . . . . . . . . . . . . . . . . . . Suite\n");
  5263. printf(" Delete Normal Alias . . . . . . . . . . . . . . . . . ");
  5264. //
  5265. // This alias was created in pass #1
  5266. //
  5267. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  5268. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  5269. TST_SUCCESS_ASSERT(NtStatus);
  5270. NtStatus = SamLookupNamesInDomain(
  5271. DomainHandle,
  5272. 1,
  5273. &AccountNames[0],
  5274. &LookedUpRids,
  5275. &LookedUpUses
  5276. );
  5277. TST_SUCCESS_ASSERT(NtStatus);
  5278. ASSERT(LookedUpUses[0] == SidTypeAlias);
  5279. RtlFreeUnicodeString( &AccountNames[0] );
  5280. AliasHandle1 = NULL;
  5281. NtStatus = SamOpenAlias( DomainHandle, DELETE, LookedUpRids[0], &AliasHandle1 );
  5282. TST_SUCCESS_ASSERT(NtStatus);
  5283. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  5284. NtStatus = SamDeleteAlias( AliasHandle1 );
  5285. if (NT_SUCCESS(NtStatus)) {
  5286. printf("Succeeded\n");
  5287. } else {
  5288. printf("Failed\n");
  5289. printf(" Completion status is 0x%lx\n", NtStatus);
  5290. TestStatus = FALSE;
  5291. }
  5292. #ifdef LATER // ALIAS_LATER - well know aliases ?
  5293. printf(" Delete Well Known Alias . . . . . . . . . . . . . . . ");
  5294. AliasHandle1 = NULL;
  5295. NtStatus = SamOpenAlias( DomainHandle, DELETE, DOMAIN_GROUP_RID_USERS, &AliasHandle1 );
  5296. TST_SUCCESS_ASSERT(NtStatus);
  5297. NtStatus = SamDeleteAlias( AliasHandle1 );
  5298. if (NtStatus == STATUS_SPECIAL_ACCOUNT) {
  5299. printf("Succeeded\n");
  5300. } else {
  5301. printf("Failed\n");
  5302. printf(" Completion status is 0x%lx\n", NtStatus);
  5303. TestStatus = FALSE;
  5304. }
  5305. NtStatus = SamCloseHandle( AliasHandle1 );
  5306. ASSERT(NT_SUCCESS(NtStatus));
  5307. printf(" Delete Admin Alias. . . . . . . . . . . . . . . . . . ");
  5308. AliasHandle1 = NULL;
  5309. NtStatus = SamOpenAlias( DomainHandle, DELETE, DOMAIN_ALIAS_RID_ADMINS, &AliasHandle1 );
  5310. TST_SUCCESS_ASSERT(NtStatus);
  5311. NtStatus = SamDeleteAlias( AliasHandle1 );
  5312. if (NtStatus == STATUS_SPECIAL_ACCOUNT) {
  5313. printf("Succeeded\n");
  5314. } else {
  5315. printf("Failed\n");
  5316. printf(" Completion status is 0x%lx\n", NtStatus);
  5317. TestStatus = FALSE;
  5318. }
  5319. NtStatus = SamCloseHandle( AliasHandle1 );
  5320. ASSERT(NT_SUCCESS(NtStatus));
  5321. #endif
  5322. ///////////////////////////////////////////////////////////////////////////
  5323. // //
  5324. // Add/Remove Member Suite //
  5325. // //
  5326. ///////////////////////////////////////////////////////////////////////////
  5327. printf("\n");
  5328. printf(" Add/Remove Member Suite . . . . . . . . . . . . . . . Suite\n");
  5329. printf(" Add Member . . . . . . . . . . . . . . . . . . . . . ");
  5330. //
  5331. // This test sets things up for the next test
  5332. //
  5333. //
  5334. // The following user might already exist (from earlier in the test)
  5335. //
  5336. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  5337. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  5338. TST_SUCCESS_ASSERT(NtStatus);
  5339. UserRid = 0;
  5340. UserHandle1 = NULL;
  5341. NtStatus = SamCreateUserInDomain(
  5342. DomainHandle,
  5343. &AccountName,
  5344. USER_ALL_ACCESS,
  5345. &UserHandle1,
  5346. &UserRid
  5347. );
  5348. RtlFreeUnicodeString( &AccountName );
  5349. DeleteUser = TRUE;
  5350. if (NtStatus == STATUS_USER_EXISTS) {
  5351. DeleteUser = FALSE;
  5352. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  5353. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  5354. TST_SUCCESS_ASSERT(NtStatus);
  5355. NtStatus = SamLookupNamesInDomain(
  5356. DomainHandle,
  5357. 1,
  5358. &AccountNames[0],
  5359. &LookedUpRids,
  5360. &LookedUpUses
  5361. );
  5362. RtlFreeUnicodeString( &AccountNames[0] );
  5363. TST_SUCCESS_ASSERT(NtStatus);
  5364. ASSERT(LookedUpUses[0] == SidTypeUser);
  5365. UserRid = LookedUpRids[0];
  5366. NtStatus = SamOpenUser(
  5367. DomainHandle,
  5368. USER_ALL_ACCESS,
  5369. UserRid,
  5370. &UserHandle1);
  5371. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  5372. }
  5373. ASSERT(NT_SUCCESS(NtStatus));
  5374. //
  5375. // This account won't exist yet
  5376. //
  5377. RtlInitString( &AccountNameAnsi, USER_NAME2 );
  5378. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  5379. TST_SUCCESS_ASSERT(NtStatus);
  5380. UserRid2 = 0;
  5381. UserHandle2 = NULL;
  5382. NtStatus = SamCreateUserInDomain(
  5383. DomainHandle,
  5384. &AccountName,
  5385. USER_ALL_ACCESS,
  5386. &UserHandle2,
  5387. &UserRid2
  5388. );
  5389. RtlFreeUnicodeString( &AccountName );
  5390. ASSERT(NT_SUCCESS(NtStatus));
  5391. //
  5392. // create the alias
  5393. //
  5394. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  5395. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  5396. TST_SUCCESS_ASSERT(NtStatus);
  5397. AliasRid = 0;
  5398. AliasHandle1 = NULL;
  5399. NtStatus = SamCreateAliasInDomain(
  5400. DomainHandle,
  5401. &AccountName,
  5402. ALIAS_ALL_ACCESS,
  5403. &AliasHandle1,
  5404. &AliasRid
  5405. );
  5406. RtlFreeUnicodeString( &AccountName );
  5407. ASSERT(NT_SUCCESS(NtStatus));
  5408. //
  5409. // Make user1 a member of this alias
  5410. //
  5411. UserSid1 = CreateUserSid(DomainSid, UserRid);
  5412. ASSERT(UserSid1 != NULL);
  5413. UserSid2 = CreateUserSid(DomainSid, UserRid2);
  5414. ASSERT(UserSid2 != NULL);
  5415. NtStatus = SamAddMemberToAlias(
  5416. AliasHandle1,
  5417. UserSid1
  5418. );
  5419. if (NT_SUCCESS(NtStatus)) {
  5420. NtStatus = SamGetMembersInAlias(
  5421. AliasHandle1,
  5422. &AliasMembers,
  5423. &MemberCount
  5424. );
  5425. ASSERT(NT_SUCCESS(NtStatus));
  5426. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  5427. for ( i=0; i<MemberCount; i++) {
  5428. if (RtlEqualSid(AliasMembers[i], UserSid1)) {
  5429. NtStatus = STATUS_SUCCESS;
  5430. break;
  5431. }
  5432. }
  5433. if (!NT_SUCCESS(NtStatus)) {
  5434. printf("Failed\n");
  5435. printf("Service returned SUCCESS, but user not in member list for alias.\n");
  5436. printf("Member list :\n");
  5437. for (i=0; i<MemberCount; i++) {
  5438. printfSid(AliasMembers[i]);
  5439. printf("\n");
  5440. }
  5441. DebugBreak();
  5442. TestStatus = FALSE;
  5443. }
  5444. if (AliasMembers != NULL) {
  5445. SamFreeMemory( AliasMembers );
  5446. }
  5447. if (NT_SUCCESS(NtStatus)) {
  5448. NtStatus = SamGetAliasMembership(
  5449. DomainHandle,
  5450. 1,
  5451. &UserSid1,
  5452. &MemberCount,
  5453. &Members
  5454. );
  5455. ASSERT(NT_SUCCESS(NtStatus));
  5456. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  5457. for ( i=0; i<MemberCount; i++) {
  5458. if (Members[i] == AliasRid) {
  5459. NtStatus = STATUS_SUCCESS;
  5460. break;
  5461. }
  5462. }
  5463. if (!NT_SUCCESS(NtStatus)) {
  5464. printf("Failed\n");
  5465. printf("Service returned SUCCESS, but alias not in account alias membership list.\n");
  5466. printf("Alias Membership :\n");
  5467. for (i=0; i<MemberCount; i++) {
  5468. printf("0x%lx\n", Members[i]);
  5469. }
  5470. DebugBreak();
  5471. TestStatus = FALSE;
  5472. }
  5473. if (Members != NULL) {
  5474. SamFreeMemory( Members );
  5475. }
  5476. //
  5477. // Check for correct alias membership for multiple accounts
  5478. // User1 should be in alias1
  5479. // User2 should be no aliases.
  5480. //
  5481. if (NT_SUCCESS(NtStatus)) {
  5482. PSID SidArray[2];
  5483. SidArray[0] = UserSid1;
  5484. SidArray[1] = UserSid2;
  5485. NtStatus = SamGetAliasMembership(
  5486. DomainHandle,
  5487. 2,
  5488. SidArray,
  5489. &MemberCount,
  5490. &Members
  5491. );
  5492. ASSERT(NT_SUCCESS(NtStatus));
  5493. if (MemberCount != 1) {
  5494. printf("Failed\n");
  5495. printf("Service returned SUCCESS, but combined alias membership count for 2 accounts not correct.\n");
  5496. printf("Combined Alias Membership :\n");
  5497. for (i=0; i<MemberCount; i++) {
  5498. printf("0x%lx\n", Members[i]);
  5499. }
  5500. DebugBreak();
  5501. TestStatus = FALSE;
  5502. } else {
  5503. if (Members[0] != AliasRid) {
  5504. printf("Failed\n");
  5505. printf("Service returned SUCCESS, but combined alias membership for 2 accounts not correct.\n");
  5506. printf("Combined Alias Membership :\n");
  5507. for (i=0; i<MemberCount; i++) {
  5508. printf("0x%lx\n", Members[i]);
  5509. }
  5510. DebugBreak();
  5511. TestStatus = FALSE;
  5512. } else {
  5513. printf("Succeeded\n");
  5514. }
  5515. }
  5516. if (Members != NULL) {
  5517. SamFreeMemory( Members );
  5518. }
  5519. }
  5520. }
  5521. } else {
  5522. printf("Failed\n");
  5523. printf(" Completion status is 0x%lx\n", NtStatus);
  5524. TestStatus = FALSE;
  5525. }
  5526. printf(" Add another member to another alias . . . . . . . . . ");
  5527. //
  5528. // Make user2 a member of alias2
  5529. //
  5530. //
  5531. // This alias was created in pass #1
  5532. //
  5533. RtlInitString( &AccountNameAnsi, ALIAS_NAME2 );
  5534. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  5535. TST_SUCCESS_ASSERT(NtStatus);
  5536. NtStatus = SamLookupNamesInDomain(
  5537. DomainHandle,
  5538. 1,
  5539. &AccountNames[0],
  5540. &LookedUpRids,
  5541. &LookedUpUses
  5542. );
  5543. TST_SUCCESS_ASSERT(NtStatus);
  5544. ASSERT(LookedUpUses[0] == SidTypeAlias);
  5545. RtlFreeUnicodeString( &AccountNames[0] );
  5546. AliasHandle2 = NULL;
  5547. AliasRid2 = LookedUpRids[0];
  5548. NtStatus = SamOpenAlias( DomainHandle, ALIAS_ALL_ACCESS, LookedUpRids[0], &AliasHandle2 );
  5549. TST_SUCCESS_ASSERT(NtStatus);
  5550. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  5551. NtStatus = SamAddMemberToAlias(
  5552. AliasHandle2,
  5553. UserSid2
  5554. );
  5555. if (NT_SUCCESS(NtStatus)) {
  5556. NtStatus = SamGetMembersInAlias(
  5557. AliasHandle2,
  5558. &AliasMembers,
  5559. &MemberCount
  5560. );
  5561. ASSERT(NT_SUCCESS(NtStatus));
  5562. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  5563. for ( i=0; i<MemberCount; i++) {
  5564. if (RtlEqualSid(AliasMembers[i], UserSid2)) {
  5565. NtStatus = STATUS_SUCCESS;
  5566. break;
  5567. }
  5568. }
  5569. if (!NT_SUCCESS(NtStatus)) {
  5570. printf("Failed\n");
  5571. printf("Service returned SUCCESS, but user not in member list for alias.\n");
  5572. printf("Member list :\n");
  5573. for (i=0; i<MemberCount; i++) {
  5574. printfSid(AliasMembers[i]);
  5575. printf("\n");
  5576. }
  5577. DebugBreak();
  5578. TestStatus = FALSE;
  5579. }
  5580. if (AliasMembers != NULL) {
  5581. SamFreeMemory( AliasMembers );
  5582. }
  5583. if (NT_SUCCESS(NtStatus)) {
  5584. NtStatus = SamGetAliasMembership(
  5585. DomainHandle,
  5586. 1,
  5587. &UserSid2,
  5588. &MemberCount,
  5589. &Members
  5590. );
  5591. ASSERT(NT_SUCCESS(NtStatus));
  5592. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  5593. for ( i=0; i<MemberCount; i++) {
  5594. if (Members[i] == AliasRid2) {
  5595. NtStatus = STATUS_SUCCESS;
  5596. break;
  5597. }
  5598. }
  5599. if (!NT_SUCCESS(NtStatus)) {
  5600. printf("Failed\n");
  5601. printf("Service returned SUCCESS, but alias not in account alias membership list.\n");
  5602. printf("Alias Membership :\n");
  5603. for (i=0; i<MemberCount; i++) {
  5604. printf("0x%lx\n", Members[i]);
  5605. }
  5606. DebugBreak();
  5607. TestStatus = FALSE;
  5608. }
  5609. if (Members != NULL) {
  5610. SamFreeMemory( Members );
  5611. }
  5612. //
  5613. // Check for correct alias membership for multiple accounts
  5614. // User1 should be in alias1
  5615. // User2 should be in alias2.
  5616. //
  5617. if (NT_SUCCESS(NtStatus)) {
  5618. PSID SidArray[2];
  5619. SidArray[0] = UserSid1;
  5620. SidArray[1] = UserSid2;
  5621. NtStatus = SamGetAliasMembership(
  5622. DomainHandle,
  5623. 2,
  5624. SidArray,
  5625. &MemberCount,
  5626. &Members
  5627. );
  5628. ASSERT(NT_SUCCESS(NtStatus));
  5629. if (MemberCount != 2) {
  5630. printf("Failed\n");
  5631. printf("Service returned SUCCESS, but combined alias membership count for 2 accounts not correct.\n");
  5632. printf("Combined Alias Membership :\n");
  5633. for (i=0; i<MemberCount; i++) {
  5634. printf("0x%lx\n", Members[i]);
  5635. }
  5636. DebugBreak();
  5637. TestStatus = FALSE;
  5638. } else {
  5639. if (((Members[0] == AliasRid) && (Members[1] == AliasRid2)) ||
  5640. ((Members[0] == AliasRid2) && (Members[1] == AliasRid)) ) {
  5641. printf("Succeeded\n");
  5642. } else {
  5643. printf("Failed\n");
  5644. printf("Service returned SUCCESS, but combined alias membership for 2 accounts not correct.\n");
  5645. printf("Combined Alias Membership :\n");
  5646. for (i=0; i<MemberCount; i++) {
  5647. printf("0x%lx\n", Members[i]);
  5648. }
  5649. DebugBreak();
  5650. TestStatus = FALSE;
  5651. }
  5652. }
  5653. if (Members != NULL) {
  5654. SamFreeMemory( Members );
  5655. }
  5656. }
  5657. }
  5658. } else {
  5659. printf("Failed\n");
  5660. printf(" Completion status is 0x%lx\n", NtStatus);
  5661. TestStatus = FALSE;
  5662. }
  5663. //
  5664. // Remove user2 from alias2 again
  5665. //
  5666. NtStatus = SamRemoveMemberFromAlias(
  5667. AliasHandle2,
  5668. UserSid2
  5669. );
  5670. if (NT_SUCCESS(NtStatus)) {
  5671. NtStatus = SamGetMembersInAlias(
  5672. AliasHandle2,
  5673. &AliasMembers,
  5674. &MemberCount
  5675. );
  5676. ASSERT(NT_SUCCESS(NtStatus));
  5677. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  5678. for ( i=0; i<MemberCount; i++) {
  5679. if (RtlEqualSid(AliasMembers[i], UserSid2)) {
  5680. NtStatus = STATUS_SUCCESS;
  5681. break;
  5682. }
  5683. }
  5684. if (NtStatus != STATUS_MEMBER_NOT_IN_ALIAS) {
  5685. printf("Failed\n");
  5686. printf("Service returned SUCCESS, but user still in member list for alias.\n");
  5687. printf("Member list :\n");
  5688. for (i=0; i<MemberCount; i++) {
  5689. printfSid(AliasMembers[i]);
  5690. printf("\n");
  5691. }
  5692. DebugBreak();
  5693. TestStatus = FALSE;
  5694. }
  5695. if (AliasMembers != NULL) {
  5696. SamFreeMemory( AliasMembers );
  5697. }
  5698. if (NT_SUCCESS(NtStatus)) {
  5699. NtStatus = SamGetAliasMembership(
  5700. DomainHandle,
  5701. 1,
  5702. &UserSid2,
  5703. &MemberCount,
  5704. &Members
  5705. );
  5706. ASSERT(NT_SUCCESS(NtStatus));
  5707. for ( i=0; i<MemberCount; i++) {
  5708. if (Members[i] == AliasRid2) {
  5709. NtStatus = STATUS_MEMBER_IN_ALIAS;
  5710. break;
  5711. }
  5712. }
  5713. if (!NT_SUCCESS(NtStatus)) {
  5714. printf("Failed\n");
  5715. printf("Service returned SUCCESS, but alias still in account alias membership list.\n");
  5716. printf("Alias Membership :\n");
  5717. for (i=0; i<MemberCount; i++) {
  5718. printf("0x%lx\n", Members[i]);
  5719. }
  5720. DebugBreak();
  5721. TestStatus = FALSE;
  5722. }
  5723. if (Members != NULL) {
  5724. SamFreeMemory( Members );
  5725. }
  5726. //
  5727. // Check for correct alias membership for multiple accounts
  5728. // User1 should be in alias1
  5729. // User2 should be in no aliases.
  5730. //
  5731. if (NT_SUCCESS(NtStatus)) {
  5732. PSID SidArray[2];
  5733. SidArray[0] = UserSid1;
  5734. SidArray[1] = UserSid2;
  5735. NtStatus = SamGetAliasMembership(
  5736. DomainHandle,
  5737. 2,
  5738. SidArray,
  5739. &MemberCount,
  5740. &Members
  5741. );
  5742. ASSERT(NT_SUCCESS(NtStatus));
  5743. if (MemberCount != 1) {
  5744. printf("Failed\n");
  5745. printf("Service returned SUCCESS, but combined alias membership count for 2 accounts not correct.\n");
  5746. printf("Combined Alias Membership :\n");
  5747. for (i=0; i<MemberCount; i++) {
  5748. printf("0x%lx\n", Members[i]);
  5749. }
  5750. DebugBreak();
  5751. TestStatus = FALSE;
  5752. } else {
  5753. if (Members[0] == AliasRid) {
  5754. printf("Succeeded\n");
  5755. } else {
  5756. printf("Failed\n");
  5757. printf("Service returned SUCCESS, but combined alias membership for 2 accounts not correct.\n");
  5758. printf("Combined Alias Membership :\n");
  5759. for (i=0; i<MemberCount; i++) {
  5760. printf("0x%lx\n", Members[i]);
  5761. }
  5762. DebugBreak();
  5763. TestStatus = FALSE;
  5764. }
  5765. }
  5766. if (Members != NULL) {
  5767. SamFreeMemory( Members );
  5768. }
  5769. }
  5770. }
  5771. } else {
  5772. printf("Failed\n");
  5773. printf(" Completion status is 0x%lx\n", NtStatus);
  5774. TestStatus = FALSE;
  5775. }
  5776. NtStatus = SamCloseHandle( AliasHandle2 );
  5777. ASSERT(NT_SUCCESS(NtStatus));
  5778. printf(" Add Another Member . . . . . . . . . . . . . . . . . ");
  5779. //
  5780. // Make user2 a member of this alias
  5781. //
  5782. NtStatus = SamAddMemberToAlias(
  5783. AliasHandle1,
  5784. UserSid2
  5785. );
  5786. if (NT_SUCCESS(NtStatus)) {
  5787. NtStatus = SamGetMembersInAlias(
  5788. AliasHandle1,
  5789. &AliasMembers,
  5790. &MemberCount
  5791. );
  5792. ASSERT(NT_SUCCESS(NtStatus));
  5793. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  5794. for ( i=0; i<MemberCount; i++) {
  5795. if (RtlEqualSid(AliasMembers[i], UserSid2)) {
  5796. NtStatus = STATUS_SUCCESS;
  5797. break;
  5798. }
  5799. }
  5800. if (!NT_SUCCESS(NtStatus)) {
  5801. printf("Failed\n");
  5802. printf("Service returned SUCCESS, but user not in member list for alias.\n");
  5803. printf("Member list :\n");
  5804. for (i=0; i<MemberCount; i++) {
  5805. printfSid(AliasMembers[i]);
  5806. printf("\n");
  5807. }
  5808. DebugBreak();
  5809. TestStatus = FALSE;
  5810. }
  5811. if (AliasMembers != NULL) {
  5812. SamFreeMemory( AliasMembers );
  5813. }
  5814. if (NT_SUCCESS(NtStatus)) {
  5815. NtStatus = SamGetAliasMembership(
  5816. DomainHandle,
  5817. 1,
  5818. &UserSid2,
  5819. &MemberCount,
  5820. &Members
  5821. );
  5822. ASSERT(NT_SUCCESS(NtStatus));
  5823. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  5824. for ( i=0; i<MemberCount; i++) {
  5825. if (Members[i] == AliasRid) {
  5826. NtStatus = STATUS_SUCCESS;
  5827. break;
  5828. }
  5829. }
  5830. if (!NT_SUCCESS(NtStatus)) {
  5831. printf("Failed\n");
  5832. printf("Service returned SUCCESS, but alias not in account alias membership list.\n");
  5833. printf("Alias Membership :\n");
  5834. for (i=0; i<MemberCount; i++) {
  5835. printf("0x%lx\n", Members[i]);
  5836. }
  5837. DebugBreak();
  5838. TestStatus = FALSE;
  5839. }
  5840. if (Members != NULL) {
  5841. SamFreeMemory( Members );
  5842. }
  5843. //
  5844. // Check for correct alias membership for multiple accounts
  5845. // User1 should be in alias1
  5846. // User2 should be in alias1.
  5847. //
  5848. if (NT_SUCCESS(NtStatus)) {
  5849. PSID SidArray[2];
  5850. SidArray[0] = UserSid1;
  5851. SidArray[1] = UserSid2;
  5852. NtStatus = SamGetAliasMembership(
  5853. DomainHandle,
  5854. 2,
  5855. SidArray,
  5856. &MemberCount,
  5857. &Members
  5858. );
  5859. ASSERT(NT_SUCCESS(NtStatus));
  5860. if (MemberCount != 1) {
  5861. printf("Failed\n");
  5862. printf("Service returned SUCCESS, but combined alias membership count for 2 accounts not correct.\n");
  5863. printf("Combined Alias Membership :\n");
  5864. for (i=0; i<MemberCount; i++) {
  5865. printf("0x%lx\n", Members[i]);
  5866. }
  5867. DebugBreak();
  5868. TestStatus = FALSE;
  5869. } else {
  5870. if (Members[0] != AliasRid) {
  5871. printf("Failed\n");
  5872. printf("Service returned SUCCESS, but combined alias membership for 2 accounts not correct.\n");
  5873. printf("Combined Alias Membership :\n");
  5874. for (i=0; i<MemberCount; i++) {
  5875. printf("0x%lx\n", Members[i]);
  5876. }
  5877. DebugBreak();
  5878. TestStatus = FALSE;
  5879. } else {
  5880. printf("Succeeded\n");
  5881. }
  5882. }
  5883. if (Members != NULL) {
  5884. SamFreeMemory( Members );
  5885. }
  5886. }
  5887. }
  5888. } else {
  5889. printf("Failed\n");
  5890. printf(" Completion status is 0x%lx\n", NtStatus);
  5891. TestStatus = FALSE;
  5892. }
  5893. printf(" Remove Member . . . . . . . . . . . . . . . . . . . . ");
  5894. //
  5895. // The previous test sets this one up.
  5896. //
  5897. //
  5898. // Now try to remove the user from the alias
  5899. //
  5900. NtStatus = SamRemoveMemberFromAlias(AliasHandle1, UserSid1);
  5901. if (NT_SUCCESS(NtStatus)) {
  5902. NtStatus = SamGetMembersInAlias(
  5903. AliasHandle1,
  5904. &AliasMembers,
  5905. &MemberCount
  5906. );
  5907. ASSERT(NT_SUCCESS(NtStatus));
  5908. for ( i=0; i<MemberCount; i++) {
  5909. if (RtlEqualSid(AliasMembers[i], UserSid1)) {
  5910. NtStatus = STATUS_MEMBER_IN_ALIAS;
  5911. break;
  5912. }
  5913. }
  5914. if (!NT_SUCCESS(NtStatus)) {
  5915. printf("Failed\n");
  5916. printf("Service returned SUCCESS, but user still in member list for alias.\n");
  5917. printf("Member list :\n");
  5918. for (i=0; i<MemberCount; i++) {
  5919. printfSid(AliasMembers[i]);
  5920. printf("\n");
  5921. }
  5922. DebugBreak();
  5923. TestStatus = FALSE;
  5924. }
  5925. SamFreeMemory( AliasMembers );
  5926. if (NT_SUCCESS(NtStatus)) {
  5927. NtStatus = SamGetAliasMembership(
  5928. DomainHandle,
  5929. 1,
  5930. &UserSid1,
  5931. &MemberCount,
  5932. &Members
  5933. );
  5934. ASSERT(NT_SUCCESS(NtStatus));
  5935. for ( i=0; i<MemberCount; i++) {
  5936. if (Members[i] == AliasRid) {
  5937. NtStatus = STATUS_MEMBER_IN_ALIAS;
  5938. break;
  5939. }
  5940. }
  5941. if (!NT_SUCCESS(NtStatus)) {
  5942. printf("Failed\n");
  5943. printf("Service returned SUCCESS, but alias still in account alias membership list.\n");
  5944. printf("Alias Membership :\n");
  5945. for (i=0; i<MemberCount; i++) {
  5946. printf("0x%lx\n", Members[i]);
  5947. }
  5948. DebugBreak();
  5949. TestStatus = FALSE;
  5950. }
  5951. if (Members != NULL) {
  5952. SamFreeMemory( Members );
  5953. }
  5954. //
  5955. // Check for correct alias membership for multiple accounts
  5956. // User1 should be in no aliases
  5957. // User2 should be in alias1.
  5958. //
  5959. if (NT_SUCCESS(NtStatus)) {
  5960. PSID SidArray[2];
  5961. SidArray[0] = UserSid1;
  5962. SidArray[1] = UserSid2;
  5963. NtStatus = SamGetAliasMembership(
  5964. DomainHandle,
  5965. 2,
  5966. SidArray,
  5967. &MemberCount,
  5968. &Members
  5969. );
  5970. ASSERT(NT_SUCCESS(NtStatus));
  5971. if (MemberCount != 1) {
  5972. printf("Failed\n");
  5973. printf("Service returned SUCCESS, but combined alias membership count for 2 accounts not correct.\n");
  5974. printf("Combined Alias Membership :\n");
  5975. for (i=0; i<MemberCount; i++) {
  5976. printf("0x%lx\n", Members[i]);
  5977. }
  5978. DebugBreak();
  5979. TestStatus = FALSE;
  5980. } else {
  5981. if (Members[0] != AliasRid) {
  5982. printf("Failed\n");
  5983. printf("Service returned SUCCESS, but combined alias membership for 2 accounts not correct.\n");
  5984. printf("Combined Alias Membership :\n");
  5985. for (i=0; i<MemberCount; i++) {
  5986. printf("0x%lx\n", Members[i]);
  5987. }
  5988. DebugBreak();
  5989. TestStatus = FALSE;
  5990. } else {
  5991. printf("Succeeded\n");
  5992. }
  5993. }
  5994. if (Members != NULL) {
  5995. SamFreeMemory( Members );
  5996. }
  5997. }
  5998. }
  5999. } else {
  6000. printf("Failed\n");
  6001. printf(" Completion status is 0x%lx\n", NtStatus);
  6002. TestStatus = FALSE;
  6003. }
  6004. printf(" Add A User to ADMIN Alias . . . . . . . . . . . . . . ");
  6005. //
  6006. // Make user2 a member of the ADMIN alias
  6007. //
  6008. NtStatus = SamOpenAlias(
  6009. BuiltinDomainHandle,
  6010. ALIAS_ALL_ACCESS,
  6011. DOMAIN_ALIAS_RID_ADMINS,
  6012. &AdminAliasHandle
  6013. );
  6014. ASSERT( NT_SUCCESS( NtStatus ) );
  6015. NtStatus = SamAddMemberToAlias(
  6016. AdminAliasHandle,
  6017. UserSid2
  6018. );
  6019. if (NT_SUCCESS(NtStatus)) {
  6020. NtStatus = SamGetMembersInAlias(
  6021. AdminAliasHandle,
  6022. &AliasMembers,
  6023. &MemberCount
  6024. );
  6025. ASSERT(NT_SUCCESS(NtStatus));
  6026. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  6027. for ( i=0; i<MemberCount; i++) {
  6028. if (RtlEqualSid(AliasMembers[i], UserSid2)) {
  6029. NtStatus = STATUS_SUCCESS;
  6030. break;
  6031. }
  6032. }
  6033. if (!NT_SUCCESS(NtStatus)) {
  6034. printf("Failed\n");
  6035. printf("Service returned SUCCESS, but user not in member list for alias.\n");
  6036. printf("Member list :\n");
  6037. for (i=0; i<MemberCount; i++) {
  6038. printfSid(AliasMembers[i]);
  6039. printf("\n");
  6040. }
  6041. DebugBreak();
  6042. TestStatus = FALSE;
  6043. }
  6044. if (AliasMembers != NULL) {
  6045. SamFreeMemory( AliasMembers );
  6046. }
  6047. if (NT_SUCCESS(NtStatus)) {
  6048. NtStatus = SamGetAliasMembership(
  6049. BuiltinDomainHandle,
  6050. 1,
  6051. &UserSid2,
  6052. &MemberCount,
  6053. &Members
  6054. );
  6055. ASSERT(NT_SUCCESS(NtStatus));
  6056. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  6057. for ( i=0; i<MemberCount; i++) {
  6058. if (Members[i] == DOMAIN_ALIAS_RID_ADMINS) {
  6059. NtStatus = STATUS_SUCCESS;
  6060. break;
  6061. }
  6062. }
  6063. if (!NT_SUCCESS(NtStatus)) {
  6064. printf("Failed\n");
  6065. printf("Service returned SUCCESS, but alias not in account alias membership list.\n");
  6066. printf("Alias Membership :\n");
  6067. for (i=0; i<MemberCount; i++) {
  6068. printf("0x%lx\n", Members[i]);
  6069. }
  6070. DebugBreak();
  6071. TestStatus = FALSE;
  6072. } else {
  6073. printf("Succeeded\n");
  6074. }
  6075. if (Members != NULL) {
  6076. SamFreeMemory( Members );
  6077. }
  6078. }
  6079. } else {
  6080. printf("Failed\n");
  6081. printf(" Completion status is 0x%lx\n", NtStatus);
  6082. TestStatus = FALSE;
  6083. }
  6084. printf(" Add A Group to ADMIN Alias . . . . . . . . . . . . . . ");
  6085. //
  6086. // Make a group a member of the ADMIN alias
  6087. //
  6088. GroupSid = CreateUserSid(DomainSid, DOMAIN_GROUP_RID_USERS );
  6089. ASSERT(GroupSid != NULL);
  6090. NtStatus = SamAddMemberToAlias(
  6091. AdminAliasHandle,
  6092. GroupSid
  6093. );
  6094. if (NT_SUCCESS(NtStatus)) {
  6095. NtStatus = SamGetMembersInAlias(
  6096. AdminAliasHandle,
  6097. &AliasMembers,
  6098. &MemberCount
  6099. );
  6100. ASSERT(NT_SUCCESS(NtStatus));
  6101. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  6102. for ( i=0; i<MemberCount; i++) {
  6103. if (RtlEqualSid(AliasMembers[i], GroupSid)) {
  6104. NtStatus = STATUS_SUCCESS;
  6105. break;
  6106. }
  6107. }
  6108. if (!NT_SUCCESS(NtStatus)) {
  6109. printf("Failed\n");
  6110. printf("Service returned SUCCESS, but user not in member list for alias.\n");
  6111. printf("Member list :\n");
  6112. for (i=0; i<MemberCount; i++) {
  6113. printfSid(AliasMembers[i]);
  6114. printf("\n");
  6115. }
  6116. DebugBreak();
  6117. TestStatus = FALSE;
  6118. }
  6119. if (AliasMembers != NULL) {
  6120. SamFreeMemory( AliasMembers );
  6121. }
  6122. if (NT_SUCCESS(NtStatus)) {
  6123. NtStatus = SamGetAliasMembership(
  6124. BuiltinDomainHandle,
  6125. 1,
  6126. &GroupSid,
  6127. &MemberCount,
  6128. &Members
  6129. );
  6130. ASSERT(NT_SUCCESS(NtStatus));
  6131. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  6132. for ( i=0; i<MemberCount; i++) {
  6133. if (Members[i] == DOMAIN_ALIAS_RID_ADMINS) {
  6134. NtStatus = STATUS_SUCCESS;
  6135. break;
  6136. }
  6137. }
  6138. if (!NT_SUCCESS(NtStatus)) {
  6139. printf("Failed\n");
  6140. printf("Service returned SUCCESS, but alias not in account alias membership list.\n");
  6141. printf("Alias Membership :\n");
  6142. for (i=0; i<MemberCount; i++) {
  6143. printf("0x%lx\n", Members[i]);
  6144. }
  6145. DebugBreak();
  6146. TestStatus = FALSE;
  6147. } else {
  6148. printf("Succeeded\n");
  6149. }
  6150. if (Members != NULL) {
  6151. SamFreeMemory( Members );
  6152. }
  6153. }
  6154. } else {
  6155. printf("Failed\n");
  6156. printf(" Completion status is 0x%lx\n", NtStatus);
  6157. TestStatus = FALSE;
  6158. }
  6159. // NOTE: user is already created in the group below. Should keep this
  6160. // test, AND add another with an all-new group that's been added to the ADMIN
  6161. // alias (then ADD user to group, rather than create in it).
  6162. printf(" Create user in ADMIN ALIAS'd Group. . . . . . . . . . . ");
  6163. RtlInitString( &AccountNameAnsi, USER_NAME3 );
  6164. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  6165. TST_SUCCESS_ASSERT(NtStatus);
  6166. UserRid3 = 0;
  6167. UserHandle3 = NULL;
  6168. NtStatus = SamCreateUserInDomain(
  6169. DomainHandle,
  6170. &AccountName,
  6171. USER_ALL_ACCESS,
  6172. &UserHandle3,
  6173. &UserRid3
  6174. );
  6175. RtlFreeUnicodeString( &AccountName );
  6176. if ( NT_SUCCESS( NtStatus ) ) {
  6177. printf("Succeeded\n");
  6178. } else {
  6179. printf("Failed\n");
  6180. printf(" Completion status is 0x%lx\n", NtStatus);
  6181. TestStatus = FALSE;
  6182. }
  6183. //NOTE: doesn't work because this is primary group.
  6184. //put back in when all-new group is created, above
  6185. // printf(" Remove user from ADMIN ALIAS'd Group. . . . . . . . . . . ");
  6186. //
  6187. // NtStatus = SamOpenGroup(
  6188. // DomainHandle,
  6189. // GROUP_ALL_ACCESS,
  6190. // DOMAIN_GROUP_RID_USERS,
  6191. // &GroupHandle
  6192. // );
  6193. //
  6194. // ASSERT(NT_SUCCESS(NtStatus));
  6195. //
  6196. // NtStatus = SamRemoveMemberFromGroup(
  6197. // GroupHandle,
  6198. // UserRid3
  6199. // );
  6200. //
  6201. // if ( NT_SUCCESS( NtStatus ) ) {
  6202. //
  6203. // printf("Succeeded\n");
  6204. //
  6205. // } else {
  6206. //
  6207. // printf("Failed\n");
  6208. // printf(" Completion status is 0x%lx\n", NtStatus);
  6209. // TestStatus = FALSE;
  6210. // }
  6211. //
  6212. // IgnoreStatus = SamCloseHandle( GroupHandle );
  6213. // ASSERT(NT_SUCCESS(IgnoreStatus));
  6214. IgnoreStatus = SamCloseHandle( UserHandle3 );
  6215. ASSERT(NT_SUCCESS(IgnoreStatus));
  6216. printf(" Remove User from ADMIN alias. . . . . . . . . . . ");
  6217. //
  6218. // The previous test sets this one up.
  6219. //
  6220. // Now try to remove the user from the alias
  6221. //
  6222. NtStatus = SamRemoveMemberFromAlias(AdminAliasHandle, UserSid2);
  6223. if (NT_SUCCESS(NtStatus)) {
  6224. NtStatus = SamGetMembersInAlias(
  6225. AdminAliasHandle,
  6226. &AliasMembers,
  6227. &MemberCount
  6228. );
  6229. ASSERT(NT_SUCCESS(NtStatus));
  6230. for ( i=0; i<MemberCount; i++) {
  6231. if (RtlEqualSid(AliasMembers[i], UserSid2)) {
  6232. NtStatus = STATUS_MEMBER_IN_ALIAS;
  6233. break;
  6234. }
  6235. }
  6236. if (!NT_SUCCESS(NtStatus)) {
  6237. printf("Failed\n");
  6238. printf("Service returned SUCCESS, but user still in member list for alias.\n");
  6239. printf("Member list :\n");
  6240. for (i=0; i<MemberCount; i++) {
  6241. printfSid(AliasMembers[i]);
  6242. printf("\n");
  6243. }
  6244. DebugBreak();
  6245. TestStatus = FALSE;
  6246. }
  6247. SamFreeMemory( AliasMembers );
  6248. if (NT_SUCCESS(NtStatus)) {
  6249. NtStatus = SamGetAliasMembership(
  6250. BuiltinDomainHandle,
  6251. 1,
  6252. &UserSid2,
  6253. &MemberCount,
  6254. &Members
  6255. );
  6256. ASSERT(NT_SUCCESS(NtStatus));
  6257. for ( i=0; i<MemberCount; i++) {
  6258. if (Members[i] == DOMAIN_ALIAS_RID_ADMINS) {
  6259. NtStatus = STATUS_MEMBER_IN_ALIAS;
  6260. break;
  6261. }
  6262. }
  6263. if (!NT_SUCCESS(NtStatus)) {
  6264. printf("Failed\n");
  6265. printf("Service returned SUCCESS, but alias still in account alias membership list.\n");
  6266. printf("Alias Membership :\n");
  6267. for (i=0; i<MemberCount; i++) {
  6268. printf("0x%lx\n", Members[i]);
  6269. }
  6270. DebugBreak();
  6271. TestStatus = FALSE;
  6272. } else {
  6273. printf("Succeeded\n");
  6274. }
  6275. if (Members != NULL) {
  6276. SamFreeMemory( Members );
  6277. }
  6278. }
  6279. } else {
  6280. printf("Failed\n");
  6281. printf(" Completion status is 0x%lx\n", NtStatus);
  6282. TestStatus = FALSE;
  6283. }
  6284. //
  6285. // Make user2 a member of the ADMIN alias again, so we can test
  6286. // the new function SamRemoveMemberFromForeignDomain().
  6287. // NOTE: we should make this a real test item.
  6288. //
  6289. NtStatus = SamAddMemberToAlias(
  6290. AdminAliasHandle,
  6291. UserSid2
  6292. );
  6293. ASSERT (NT_SUCCESS(NtStatus));
  6294. NtStatus = SamRemoveMemberFromForeignDomain(
  6295. BuiltinDomainHandle,
  6296. UserSid2 );
  6297. ASSERT (NT_SUCCESS(NtStatus));
  6298. printf(" Remove Group from ADMIN alias. . . . . . . . . . . ");
  6299. //
  6300. // The previous test sets this one up.
  6301. //
  6302. // Now try to remove the group from the alias
  6303. //
  6304. NtStatus = SamRemoveMemberFromAlias(AdminAliasHandle, GroupSid);
  6305. if (NT_SUCCESS(NtStatus)) {
  6306. NtStatus = SamGetMembersInAlias(
  6307. AdminAliasHandle,
  6308. &AliasMembers,
  6309. &MemberCount
  6310. );
  6311. ASSERT(NT_SUCCESS(NtStatus));
  6312. for ( i=0; i<MemberCount; i++) {
  6313. if (RtlEqualSid(AliasMembers[i], GroupSid)) {
  6314. NtStatus = STATUS_MEMBER_IN_ALIAS;
  6315. break;
  6316. }
  6317. }
  6318. if (!NT_SUCCESS(NtStatus)) {
  6319. printf("Failed\n");
  6320. printf("Service returned SUCCESS, but user still in member list for alias.\n");
  6321. printf("Member list :\n");
  6322. for (i=0; i<MemberCount; i++) {
  6323. printfSid(AliasMembers[i]);
  6324. printf("\n");
  6325. }
  6326. DebugBreak();
  6327. TestStatus = FALSE;
  6328. }
  6329. SamFreeMemory( AliasMembers );
  6330. if (NT_SUCCESS(NtStatus)) {
  6331. NtStatus = SamGetAliasMembership(
  6332. BuiltinDomainHandle,
  6333. 1,
  6334. &GroupSid,
  6335. &MemberCount,
  6336. &Members
  6337. );
  6338. ASSERT(NT_SUCCESS(NtStatus));
  6339. for ( i=0; i<MemberCount; i++) {
  6340. if (Members[i] == DOMAIN_ALIAS_RID_ADMINS) {
  6341. NtStatus = STATUS_MEMBER_IN_ALIAS;
  6342. break;
  6343. }
  6344. }
  6345. if (!NT_SUCCESS(NtStatus)) {
  6346. printf("Failed\n");
  6347. printf("Service returned SUCCESS, but alias still in account alias membership list.\n");
  6348. printf("Alias Membership :\n");
  6349. for (i=0; i<MemberCount; i++) {
  6350. printf("0x%lx\n", Members[i]);
  6351. }
  6352. DebugBreak();
  6353. TestStatus = FALSE;
  6354. } else {
  6355. printf("Succeeded\n");
  6356. }
  6357. if (Members != NULL) {
  6358. SamFreeMemory( Members );
  6359. }
  6360. }
  6361. } else {
  6362. printf("Failed\n");
  6363. printf(" Completion status is 0x%lx\n", NtStatus);
  6364. TestStatus = FALSE;
  6365. }
  6366. IgnoreStatus = SamCloseHandle( AdminAliasHandle );
  6367. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6368. printf(" Delete account while member of alias. . . . . . . . . ");
  6369. //
  6370. // Now delete user2 and check the alias member list is updated
  6371. //
  6372. NtStatus = SamDeleteUser( UserHandle2 );
  6373. ASSERT(NT_SUCCESS(NtStatus));
  6374. NtStatus = SamGetMembersInAlias(
  6375. AliasHandle1,
  6376. &AliasMembers,
  6377. &MemberCount
  6378. );
  6379. ASSERT(NT_SUCCESS(NtStatus));
  6380. for ( i=0; i<MemberCount; i++) {
  6381. if (RtlEqualSid(AliasMembers[i], UserSid2)) {
  6382. NtStatus = STATUS_MEMBER_IN_ALIAS;
  6383. break;
  6384. }
  6385. }
  6386. if (!NT_SUCCESS(NtStatus)) {
  6387. printf("Failed\n");
  6388. printf("Service returned SUCCESS, but user still in member list for alias.\n");
  6389. printf("Member list :\n");
  6390. for (i=0; i<MemberCount; i++) {
  6391. printfSid(AliasMembers[i]);
  6392. printf("\n");
  6393. }
  6394. DebugBreak();
  6395. TestStatus = FALSE;
  6396. }
  6397. SamFreeMemory( AliasMembers );
  6398. if (NT_SUCCESS(NtStatus)) {
  6399. NtStatus = SamGetAliasMembership(
  6400. DomainHandle,
  6401. 1,
  6402. &UserSid2,
  6403. &MemberCount,
  6404. &Members
  6405. );
  6406. ASSERT(NT_SUCCESS(NtStatus));
  6407. if (MemberCount != 0) {
  6408. printf("Failed\n");
  6409. printf("Service returned SUCCESS, but alias still in alias membership list for account.\n");
  6410. printf("Alias Membership :\n");
  6411. for (i=0; i<MemberCount; i++) {
  6412. printf("0x%lx\n", Members[i]);
  6413. }
  6414. DebugBreak();
  6415. TestStatus = FALSE;
  6416. }
  6417. if (Members != NULL) {
  6418. SamFreeMemory( Members );
  6419. }
  6420. //
  6421. // Check for correct alias membership for multiple accounts
  6422. // User1 should be in no aliases
  6423. // User2 should be in no aliases.
  6424. //
  6425. if (NT_SUCCESS(NtStatus)) {
  6426. PSID SidArray[2];
  6427. SidArray[0] = UserSid1;
  6428. SidArray[1] = UserSid2;
  6429. NtStatus = SamGetAliasMembership(
  6430. DomainHandle,
  6431. 2,
  6432. SidArray,
  6433. &MemberCount,
  6434. &Members
  6435. );
  6436. ASSERT(NT_SUCCESS(NtStatus));
  6437. if (MemberCount != 0) {
  6438. printf("Failed\n");
  6439. printf("Service returned SUCCESS, but combined alias membership count for 2 accounts not correct.\n");
  6440. printf("Combined Alias Membership :\n");
  6441. for (i=0; i<MemberCount; i++) {
  6442. printf("0x%lx\n", Members[i]);
  6443. }
  6444. DebugBreak();
  6445. TestStatus = FALSE;
  6446. } else {
  6447. printf("Succeeded\n");
  6448. }
  6449. if (Members != NULL) {
  6450. SamFreeMemory( Members );
  6451. }
  6452. }
  6453. }
  6454. printf(" Delete alias with members . . . . . . . . . . . . . . ");
  6455. //
  6456. // Make the user a member of this alias (again)
  6457. //
  6458. NtStatus = SamAddMemberToAlias(
  6459. AliasHandle1,
  6460. UserSid1
  6461. );
  6462. ASSERT(NT_SUCCESS(NtStatus));
  6463. //
  6464. // Now delete the alias and check the membership list for user is updated
  6465. //
  6466. NtStatus = SamDeleteAlias( AliasHandle1 );
  6467. ASSERT(NT_SUCCESS(NtStatus));
  6468. NtStatus = SamGetAliasMembership(
  6469. DomainHandle,
  6470. 1,
  6471. &UserSid1,
  6472. &MemberCount,
  6473. &Members
  6474. );
  6475. ASSERT(NT_SUCCESS(NtStatus));
  6476. for ( i=0; i<MemberCount; i++) {
  6477. if (Members[i] == AliasRid) {
  6478. NtStatus = STATUS_MEMBER_IN_ALIAS;
  6479. break;
  6480. }
  6481. }
  6482. if (NT_SUCCESS(NtStatus)) {
  6483. printf("Succeeded\n");
  6484. } else {
  6485. printf("Failed\n");
  6486. printf("Service returned SUCCESS, but alias still in account alias membership list.\n");
  6487. printf("Alias Membership :\n");
  6488. for (i=0; i<MemberCount; i++) {
  6489. printf("0x%lx\n", Members[i]);
  6490. }
  6491. DebugBreak();
  6492. TestStatus = FALSE;
  6493. }
  6494. if (Members != NULL) {
  6495. SamFreeMemory( Members );
  6496. }
  6497. DeleteUserSid(UserSid1);
  6498. DeleteUserSid(UserSid2);
  6499. //
  6500. // and clean up
  6501. //
  6502. if (DeleteUser == TRUE) {
  6503. NtStatus = SamDeleteUser( UserHandle1 );
  6504. ASSERT(NT_SUCCESS(NtStatus));
  6505. } else {
  6506. NtStatus = SamCloseHandle( UserHandle1 );
  6507. ASSERT(NT_SUCCESS(NtStatus));
  6508. }
  6509. printf(" Add Foreign Domain Member . . . . . . . . . . . . . . ");
  6510. //
  6511. // create the alias
  6512. //
  6513. RtlInitString( &AccountNameAnsi, ALIAS_NAME1 );
  6514. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  6515. TST_SUCCESS_ASSERT(NtStatus);
  6516. AliasRid = 0;
  6517. AliasHandle1 = NULL;
  6518. NtStatus = SamCreateAliasInDomain(
  6519. DomainHandle,
  6520. &AccountName,
  6521. ALIAS_ALL_ACCESS,
  6522. &AliasHandle1,
  6523. &AliasRid
  6524. );
  6525. RtlFreeUnicodeString( &AccountName );
  6526. ASSERT(NT_SUCCESS(NtStatus));
  6527. //
  6528. // Specify a non-existant user be added to this alias
  6529. //
  6530. {
  6531. PSID ForeignDomainSid;
  6532. ForeignDomainSid = CreateUserSid(DomainSid, 307333); // random domain sub-authority
  6533. ASSERT(ForeignDomainSid != NULL);
  6534. UserRid = 45728; // Random user rid
  6535. UserSid1 = CreateUserSid(ForeignDomainSid, UserRid);
  6536. ASSERT(UserSid1 != NULL);
  6537. DeleteUserSid(ForeignDomainSid);
  6538. }
  6539. NtStatus = SamAddMemberToAlias(
  6540. AliasHandle1,
  6541. UserSid1
  6542. );
  6543. if (NtStatus == STATUS_SUCCESS) {
  6544. NtStatus = SamGetMembersInAlias(
  6545. AliasHandle1,
  6546. &AliasMembers,
  6547. &MemberCount
  6548. );
  6549. ASSERT(NT_SUCCESS(NtStatus));
  6550. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  6551. for ( i=0; i<MemberCount; i++) {
  6552. if (RtlEqualSid(AliasMembers[i], UserSid1)) {
  6553. NtStatus = STATUS_SUCCESS;
  6554. break;
  6555. }
  6556. }
  6557. if (!NT_SUCCESS(NtStatus)) {
  6558. printf("Failed\n");
  6559. printf("Service returned SUCCESS, but user not in member list for alias.\n");
  6560. printf("Member list :\n");
  6561. for (i=0; i<MemberCount; i++) {
  6562. printfSid(AliasMembers[i]);
  6563. printf("\n");
  6564. }
  6565. DebugBreak();
  6566. TestStatus = FALSE;
  6567. }
  6568. if (AliasMembers != NULL) {
  6569. SamFreeMemory( AliasMembers );
  6570. }
  6571. if (NT_SUCCESS(NtStatus)) {
  6572. NtStatus = SamGetAliasMembership(
  6573. DomainHandle,
  6574. 1,
  6575. &UserSid1,
  6576. &MemberCount,
  6577. &Members
  6578. );
  6579. ASSERT(NT_SUCCESS(NtStatus));
  6580. NtStatus = STATUS_MEMBER_NOT_IN_ALIAS;
  6581. for ( i=0; i<MemberCount; i++) {
  6582. if (Members[i] == AliasRid) {
  6583. NtStatus = STATUS_SUCCESS;
  6584. break;
  6585. }
  6586. }
  6587. if (NT_SUCCESS(NtStatus)) {
  6588. printf("Succeeded\n");
  6589. } else {
  6590. printf("Failed\n");
  6591. printf("Service returned SUCCESS, but alias not in account alias membership list.\n");
  6592. printf("Alias Membership :\n");
  6593. for (i=0; i<MemberCount; i++) {
  6594. printf("0x%lx\n", Members[i]);
  6595. }
  6596. DebugBreak();
  6597. TestStatus = FALSE;
  6598. }
  6599. if (Members != NULL) {
  6600. SamFreeMemory( Members );
  6601. }
  6602. }
  6603. } else {
  6604. printf("Failed\n");
  6605. printf(" Completion status is 0x%lx\n", NtStatus);
  6606. TestStatus = FALSE;
  6607. }
  6608. DeleteUserSid(UserSid1);
  6609. printf(" Add alias as member . . . . . . . . . . . . . . . . . ");
  6610. //
  6611. // Specify an alias in the current domain be added to this alias
  6612. //
  6613. UserSid1 = CreateUserSid(DomainSid, AliasRid2);
  6614. ASSERT(UserSid1 != NULL);
  6615. NtStatus = SamAddMemberToAlias(
  6616. AliasHandle1,
  6617. UserSid1
  6618. );
  6619. if (NtStatus != STATUS_INVALID_MEMBER) {
  6620. printf("Failed\n");
  6621. printf("Expected service to return STATUS_INVALID_MEMBER, actually returned 0x%lx.\n", NtStatus);
  6622. DebugBreak();
  6623. TestStatus = FALSE;
  6624. } else {
  6625. printf("Succeeded\n");
  6626. }
  6627. DeleteUserSid(UserSid1);
  6628. printf(" Add non-existant account in this domain as member . . ");
  6629. //
  6630. // Specify a non-existant account in the current domain be added to this alias
  6631. //
  6632. UserSid1 = CreateUserSid(DomainSid, 32567); // Random rid
  6633. ASSERT(UserSid1 != NULL);
  6634. NtStatus = SamAddMemberToAlias(
  6635. AliasHandle1,
  6636. UserSid1
  6637. );
  6638. if (NtStatus != STATUS_NO_SUCH_MEMBER) {
  6639. printf("Failed\n");
  6640. printf("Expected service to return STATUS_NO_SUCH_MEMBER, actually returned 0x%lx.\n", NtStatus);
  6641. DebugBreak();
  6642. TestStatus = FALSE;
  6643. } else {
  6644. printf("Succeeded\n");
  6645. }
  6646. DeleteUserSid(UserSid1);
  6647. printf(" Remove Non-member . . . . . . . . . . . . . . . . . . ");
  6648. //
  6649. // Specify a non-existant user be removed from this alias
  6650. //
  6651. {
  6652. PSID ForeignDomainSid;
  6653. ForeignDomainSid = CreateUserSid(DomainSid, 35775); // random domain sub-authority
  6654. ASSERT(ForeignDomainSid != NULL);
  6655. UserRid = 623545; // Random user rid
  6656. UserSid1 = CreateUserSid(ForeignDomainSid, UserRid);
  6657. ASSERT(UserSid1 != NULL);
  6658. DeleteUserSid(ForeignDomainSid);
  6659. }
  6660. NtStatus = SamRemoveMemberFromAlias( AliasHandle1, UserSid1 );
  6661. if (NtStatus == STATUS_MEMBER_NOT_IN_ALIAS) {
  6662. printf("Succeeded\n");
  6663. } else {
  6664. printf("Failed\n");
  6665. printf(" Completion status is 0x%lx\n", NtStatus);
  6666. TestStatus = FALSE;
  6667. }
  6668. DeleteUserSid(UserSid1);
  6669. NtStatus = SamDeleteAlias( AliasHandle1 );
  6670. ASSERT(NT_SUCCESS(NtStatus));
  6671. }
  6672. return(TestStatus);
  6673. }
  6674. ///////////////////////////////////////////////////////////////////////////////
  6675. // //
  6676. // User Object Test Suite //
  6677. // //
  6678. ///////////////////////////////////////////////////////////////////////////////
  6679. BOOLEAN
  6680. UserTestSuite(
  6681. HANDLE DomainHandle,
  6682. ULONG Pass
  6683. )
  6684. {
  6685. PUSER_ALL_INFORMATION All, All2;
  6686. NTSTATUS NtStatus, IgnoreStatus, TmpStatus;
  6687. HANDLE UserHandle1, UserHandle2, GroupHandle1;
  6688. ULONG CountReturned, NameLength, MembershipCount, i;
  6689. ULONG UserRid, GroupRid;
  6690. PVOID Buffer, Buffer1, Buffer2;
  6691. SAM_ENUMERATE_HANDLE EnumerationContext;
  6692. USER_GENERAL_INFORMATION GeneralInformation;
  6693. USER_LOGON_INFORMATION LogonInformation;
  6694. USER_ACCOUNT_INFORMATION AccountInformation;
  6695. PSID_NAME_USE LookedUpUses;
  6696. PULONG LookedUpRids;
  6697. UNICODE_STRING AccountNames[10], AccountName;
  6698. STRING AccountNameAnsi, TmpAnsiString;
  6699. BOOLEAN IndividualTestSucceeded, DeleteUser;
  6700. BOOLEAN TestStatus = TRUE;
  6701. if (Pass == 1) {
  6702. // This test suite assumes that lookup and enumeration API funciton
  6703. // properly.
  6704. //
  6705. printf("\n");
  6706. printf("\n");
  6707. printf(" User (Pass #1) . . . . . . . . . . . . . . . . . . . Test\n");
  6708. ///////////////////////////////////////////////////////////////////////////
  6709. // //
  6710. // Open User Suite //
  6711. // //
  6712. ///////////////////////////////////////////////////////////////////////////
  6713. printf(" Open User . . . . . . . . . . . . . . . . . . . . . Suite\n");
  6714. printf(" Open Users . . . . . . . . . . . . . . . . . . . . . ");
  6715. IndividualTestSucceeded = TRUE;
  6716. EnumerationContext = 0;
  6717. NtStatus = SamEnumerateUsersInDomain(
  6718. DomainHandle,
  6719. &EnumerationContext,
  6720. 0,
  6721. &Buffer,
  6722. 12000, // PreferedMaximumLength
  6723. &CountReturned
  6724. );
  6725. TST_SUCCESS_ASSERT(NtStatus);
  6726. ASSERT(Buffer != NULL);
  6727. ASSERT(CountReturned > 0);
  6728. for (i=0; i<CountReturned; i++) {
  6729. NtStatus = SamOpenUser(
  6730. DomainHandle,
  6731. USER_ALL_ACCESS,
  6732. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  6733. &UserHandle1
  6734. );
  6735. if (NT_SUCCESS(NtStatus)) {
  6736. NtStatus = SamOpenUser(
  6737. DomainHandle,
  6738. GENERIC_READ,
  6739. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId,
  6740. &UserHandle2
  6741. );
  6742. if (NT_SUCCESS(NtStatus)) {
  6743. IgnoreStatus = SamCloseHandle( UserHandle2 );
  6744. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6745. } else {
  6746. printf("Failed\n");
  6747. printf(" Completion status is 0x%lx\n", NtStatus);
  6748. printf(" Failed opening User second time.\n");
  6749. printf(" Rid of account is: 0x%lx\n",
  6750. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId);
  6751. printf(" Name of account is: %wZ\n",
  6752. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name );
  6753. TestStatus = FALSE;
  6754. IndividualTestSucceeded = FALSE;
  6755. }
  6756. IgnoreStatus = SamCloseHandle( UserHandle1 );
  6757. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6758. } else {
  6759. printf("Failed\n");
  6760. printf(" Completion status is 0x%lx\n", NtStatus);
  6761. printf(" Failed opening User for first time.\n");
  6762. printf(" Rid of account is: 0x%lx\n",
  6763. ((PSAM_RID_ENUMERATION)(Buffer))[i].RelativeId);
  6764. printf(" Name of account is: %wZ\n",
  6765. &((PSAM_RID_ENUMERATION)(Buffer))[i].Name );
  6766. TestStatus = FALSE;
  6767. IndividualTestSucceeded = FALSE;
  6768. }
  6769. }
  6770. SamFreeMemory( Buffer );
  6771. if (IndividualTestSucceeded) {
  6772. printf("Succeeded\n");
  6773. }
  6774. ///////////////////////////////////////////////////////////////////////////
  6775. // //
  6776. // Query User Suite //
  6777. // //
  6778. ///////////////////////////////////////////////////////////////////////////
  6779. printf("\n");
  6780. printf(" Query User . . . . . . . . . . . . . . . . . . . . . Suite\n");
  6781. printf(" Query User General Information . . . . . . . . . . . ");
  6782. NtStatus = SamOpenUser(
  6783. DomainHandle,
  6784. USER_READ_GENERAL,
  6785. DOMAIN_USER_RID_ADMIN,
  6786. &UserHandle1
  6787. );
  6788. ASSERT(NT_SUCCESS(NtStatus) );
  6789. Buffer = NULL;
  6790. NtStatus = SamQueryInformationUser(
  6791. UserHandle1,
  6792. UserGeneralInformation,
  6793. &Buffer
  6794. );
  6795. if (NT_SUCCESS(NtStatus)) {
  6796. if (Buffer != NULL) {
  6797. if ( (((USER_GENERAL_INFORMATION *)Buffer)->UserName.MaximumLength
  6798. >= 0) &&
  6799. (((USER_GENERAL_INFORMATION *)Buffer)->UserName.Buffer != NULL)
  6800. ) {
  6801. printf("Succeeded\n");
  6802. printf(" Primary Group is: 0x%lx\n",
  6803. (((USER_GENERAL_INFORMATION *)Buffer)->PrimaryGroupId) );
  6804. printf(" User Name is: *%wZ*\n",
  6805. &(((USER_GENERAL_INFORMATION *)Buffer)->UserName) );
  6806. printf(" Full Name is: *%wZ*\n",
  6807. &(((USER_GENERAL_INFORMATION *)Buffer)->FullName) );
  6808. printf(" Admin Comment is: *%wZ*\n",
  6809. &(((USER_GENERAL_INFORMATION *)Buffer)->AdminComment) );
  6810. printf(" User Comment is: *%wZ*\n",
  6811. &(((USER_GENERAL_INFORMATION *)Buffer)->UserComment) );
  6812. } else {
  6813. printf("Failed\n");
  6814. printf(" One of the UNICODE_STRINGs not returned.\n");
  6815. TestStatus = FALSE;
  6816. }
  6817. SamFreeMemory( Buffer );
  6818. } else {
  6819. printf("Failed\n");
  6820. printf(" Buffer address not set on return.\n");
  6821. printf(" RPC should have allocated a buffer.\n");
  6822. TestStatus = FALSE;
  6823. }
  6824. } else {
  6825. printf("Failed\n");
  6826. printf(" Completion status is 0x%lx\n", NtStatus);
  6827. TestStatus = FALSE;
  6828. }
  6829. IgnoreStatus = SamCloseHandle( UserHandle1 );
  6830. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6831. printf(" Query User Name Information . . . . . . . . . . . . . ");
  6832. NtStatus = SamOpenUser(
  6833. DomainHandle,
  6834. USER_READ_GENERAL,
  6835. DOMAIN_USER_RID_ADMIN,
  6836. &UserHandle1
  6837. );
  6838. ASSERT(NT_SUCCESS(NtStatus) );
  6839. Buffer = NULL;
  6840. NtStatus = SamQueryInformationUser(
  6841. UserHandle1,
  6842. UserNameInformation,
  6843. &Buffer
  6844. );
  6845. if (NT_SUCCESS(NtStatus)) {
  6846. if (Buffer != NULL) {
  6847. if ( (((USER_NAME_INFORMATION *)Buffer)->UserName.MaximumLength > 0) &&
  6848. (((USER_NAME_INFORMATION *)Buffer)->UserName.Buffer != NULL)
  6849. ) {
  6850. printf("Succeeded\n");
  6851. printf(" User Name is: *%wZ*\n",
  6852. &(((USER_NAME_INFORMATION *)Buffer)->UserName) );
  6853. printf(" Full Name is: *%wZ*\n",
  6854. &(((USER_NAME_INFORMATION *)Buffer)->FullName) );
  6855. } else {
  6856. printf("Failed\n");
  6857. printf(" One of the UNICODE_STRINGs not returned.\n");
  6858. TestStatus = FALSE;
  6859. }
  6860. SamFreeMemory( Buffer );
  6861. } else {
  6862. printf("Failed\n");
  6863. printf(" Buffer address not set on return.\n");
  6864. printf(" RPC should have allocated a buffer.\n");
  6865. TestStatus = FALSE;
  6866. }
  6867. } else {
  6868. printf("Failed\n");
  6869. printf(" Completion status is 0x%lx\n", NtStatus);
  6870. TestStatus = FALSE;
  6871. }
  6872. IgnoreStatus = SamCloseHandle( UserHandle1 );
  6873. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6874. printf(" Query User Account Name Information . . . . . . . . . ");
  6875. NtStatus = SamOpenUser(
  6876. DomainHandle,
  6877. USER_READ_GENERAL,
  6878. DOMAIN_USER_RID_ADMIN,
  6879. &UserHandle1
  6880. );
  6881. ASSERT(NT_SUCCESS(NtStatus) );
  6882. Buffer = NULL;
  6883. NtStatus = SamQueryInformationUser(
  6884. UserHandle1,
  6885. UserAccountNameInformation,
  6886. &Buffer
  6887. );
  6888. if (NT_SUCCESS(NtStatus)) {
  6889. if (Buffer != NULL) {
  6890. if ( (((USER_ACCOUNT_NAME_INFORMATION *)Buffer)->UserName.MaximumLength > 0) &&
  6891. (((USER_ACCOUNT_NAME_INFORMATION *)Buffer)->UserName.Buffer != NULL)
  6892. ) {
  6893. printf("Succeeded\n");
  6894. printf(" User Name is: *%wZ*\n",
  6895. &(((USER_ACCOUNT_NAME_INFORMATION *)Buffer)->UserName) );
  6896. } else {
  6897. printf("Failed\n");
  6898. printf(" UNICODE_STRING not returned.\n");
  6899. TestStatus = FALSE;
  6900. }
  6901. SamFreeMemory( Buffer );
  6902. } else {
  6903. printf("Failed\n");
  6904. printf(" Buffer address not set on return.\n");
  6905. printf(" RPC should have allocated a buffer.\n");
  6906. TestStatus = FALSE;
  6907. }
  6908. } else {
  6909. printf("Failed\n");
  6910. printf(" Completion status is 0x%lx\n", NtStatus);
  6911. TestStatus = FALSE;
  6912. }
  6913. IgnoreStatus = SamCloseHandle( UserHandle1 );
  6914. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6915. printf(" Query User Full Name Information . . . . . . . . . . ");
  6916. NtStatus = SamOpenUser(
  6917. DomainHandle,
  6918. USER_READ_GENERAL,
  6919. DOMAIN_USER_RID_ADMIN,
  6920. &UserHandle1
  6921. );
  6922. ASSERT(NT_SUCCESS(NtStatus) );
  6923. Buffer = NULL;
  6924. NtStatus = SamQueryInformationUser(
  6925. UserHandle1,
  6926. UserFullNameInformation,
  6927. &Buffer
  6928. );
  6929. if (NT_SUCCESS(NtStatus)) {
  6930. if (Buffer != NULL) {
  6931. if ( (((USER_FULL_NAME_INFORMATION *)Buffer)->FullName.MaximumLength
  6932. >= 0)
  6933. ) {
  6934. printf("Succeeded\n");
  6935. printf(" Full Name is: *%wZ*\n",
  6936. &(((USER_FULL_NAME_INFORMATION *)Buffer)->FullName) );
  6937. } else {
  6938. printf("Failed\n");
  6939. printf(" UNICODE_STRING not returned.\n");
  6940. TestStatus = FALSE;
  6941. }
  6942. SamFreeMemory( Buffer );
  6943. } else {
  6944. printf("Failed\n");
  6945. printf(" Buffer address not set on return.\n");
  6946. printf(" RPC should have allocated a buffer.\n");
  6947. TestStatus = FALSE;
  6948. }
  6949. } else {
  6950. printf("Failed\n");
  6951. printf(" Completion status is 0x%lx\n", NtStatus);
  6952. TestStatus = FALSE;
  6953. }
  6954. IgnoreStatus = SamCloseHandle( UserHandle1 );
  6955. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6956. printf(" Query User Admin Comment Information . . . . . . . . ");
  6957. NtStatus = SamOpenUser(
  6958. DomainHandle,
  6959. USER_READ_GENERAL,
  6960. DOMAIN_USER_RID_ADMIN,
  6961. &UserHandle1
  6962. );
  6963. ASSERT(NT_SUCCESS(NtStatus) );
  6964. Buffer = NULL;
  6965. NtStatus = SamQueryInformationUser(
  6966. UserHandle1,
  6967. UserAdminCommentInformation,
  6968. &Buffer
  6969. );
  6970. if (NT_SUCCESS(NtStatus)) {
  6971. if (Buffer != NULL) {
  6972. if ( (((USER_ADMIN_COMMENT_INFORMATION *)Buffer)->AdminComment.MaximumLength
  6973. >= 0)
  6974. ) {
  6975. printf("Succeeded\n");
  6976. printf(" Admin Comment is: *%wZ*\n",
  6977. &(((USER_ADMIN_COMMENT_INFORMATION *)Buffer)->AdminComment) );
  6978. } else {
  6979. printf("Failed\n");
  6980. printf(" User Admin Comment not returned.\n");
  6981. TestStatus = FALSE;
  6982. }
  6983. SamFreeMemory( Buffer );
  6984. } else {
  6985. printf("Failed\n");
  6986. printf(" Buffer address not set on return.\n");
  6987. printf(" RPC should have allocated a buffer.\n");
  6988. TestStatus = FALSE;
  6989. }
  6990. } else {
  6991. printf("Failed\n");
  6992. printf(" Completion status is 0x%lx\n", NtStatus);
  6993. TestStatus = FALSE;
  6994. }
  6995. IgnoreStatus = SamCloseHandle( UserHandle1 );
  6996. ASSERT( NT_SUCCESS(IgnoreStatus) );
  6997. printf(" Query User Primary Group Information . . . . . . . . ");
  6998. NtStatus = SamOpenUser(
  6999. DomainHandle,
  7000. USER_READ_GENERAL,
  7001. DOMAIN_USER_RID_ADMIN,
  7002. &UserHandle1
  7003. );
  7004. ASSERT(NT_SUCCESS(NtStatus) );
  7005. Buffer = NULL;
  7006. NtStatus = SamQueryInformationUser(
  7007. UserHandle1,
  7008. UserPrimaryGroupInformation,
  7009. &Buffer
  7010. );
  7011. if (NT_SUCCESS(NtStatus)) {
  7012. if (Buffer != NULL) {
  7013. printf("Succeeded\n");
  7014. printf(" Primary Group is: 0x%lx\n",
  7015. (((USER_PRIMARY_GROUP_INFORMATION *)Buffer)->PrimaryGroupId) );
  7016. SamFreeMemory( Buffer );
  7017. } else {
  7018. printf("Failed\n");
  7019. printf(" Buffer address not set on return.\n");
  7020. printf(" RPC should have allocated a buffer.\n");
  7021. TestStatus = FALSE;
  7022. }
  7023. } else {
  7024. printf("Failed\n");
  7025. printf(" Completion status is 0x%lx\n", NtStatus);
  7026. TestStatus = FALSE;
  7027. }
  7028. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7029. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7030. printf(" Query User Control Information . . . . . . . . . . . ");
  7031. NtStatus = SamOpenUser(
  7032. DomainHandle,
  7033. USER_READ_ACCOUNT,
  7034. DOMAIN_USER_RID_ADMIN,
  7035. &UserHandle1
  7036. );
  7037. ASSERT(NT_SUCCESS(NtStatus) );
  7038. Buffer = NULL;
  7039. NtStatus = SamQueryInformationUser(
  7040. UserHandle1,
  7041. UserControlInformation,
  7042. &Buffer
  7043. );
  7044. if (NT_SUCCESS(NtStatus)) {
  7045. if (Buffer != NULL) {
  7046. printf("Succeeded\n");
  7047. printf(" Account Control is: 0x%lx\n",
  7048. (((USER_CONTROL_INFORMATION *)Buffer)->UserAccountControl) );
  7049. SamFreeMemory( Buffer );
  7050. } else {
  7051. printf("Failed\n");
  7052. printf(" Buffer address not set on return.\n");
  7053. printf(" RPC should have allocated a buffer.\n");
  7054. TestStatus = FALSE;
  7055. }
  7056. } else {
  7057. printf("Failed\n");
  7058. printf(" Completion status is 0x%lx\n", NtStatus);
  7059. TestStatus = FALSE;
  7060. }
  7061. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7062. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7063. printf(" Query User Expiration Information . . . . . . . . . . ");
  7064. NtStatus = SamOpenUser(
  7065. DomainHandle,
  7066. USER_READ_ACCOUNT,
  7067. DOMAIN_USER_RID_ADMIN,
  7068. &UserHandle1
  7069. );
  7070. ASSERT(NT_SUCCESS(NtStatus) );
  7071. Buffer = NULL;
  7072. NtStatus = SamQueryInformationUser(
  7073. UserHandle1,
  7074. UserExpiresInformation,
  7075. &Buffer
  7076. );
  7077. if (NT_SUCCESS(NtStatus)) {
  7078. if (Buffer != NULL) {
  7079. printf("Succeeded\n");
  7080. printf(" Account Expires on: (0x%lx, 0x%lx)\n",
  7081. (((USER_EXPIRES_INFORMATION *)Buffer)->AccountExpires.HighPart),
  7082. (((USER_EXPIRES_INFORMATION *)Buffer)->AccountExpires.LowPart) );
  7083. SamFreeMemory( Buffer );
  7084. } else {
  7085. printf("Failed\n");
  7086. printf(" Buffer address not set on return.\n");
  7087. printf(" RPC should have allocated a buffer.\n");
  7088. TestStatus = FALSE;
  7089. }
  7090. } else {
  7091. printf("Failed\n");
  7092. printf(" Completion status is 0x%lx\n", NtStatus);
  7093. TestStatus = FALSE;
  7094. }
  7095. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7096. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7097. printf(" Query User Preferences Information . . . . . . . . . ");
  7098. NtStatus = SamOpenUser(
  7099. DomainHandle,
  7100. USER_READ_PREFERENCES | USER_READ_GENERAL,
  7101. DOMAIN_USER_RID_ADMIN,
  7102. &UserHandle1
  7103. );
  7104. ASSERT(NT_SUCCESS(NtStatus) );
  7105. Buffer = NULL;
  7106. NtStatus = SamQueryInformationUser(
  7107. UserHandle1,
  7108. UserPreferencesInformation,
  7109. &Buffer
  7110. );
  7111. if (NT_SUCCESS(NtStatus)) {
  7112. if (Buffer != NULL) {
  7113. if ( (((USER_PREFERENCES_INFORMATION *)Buffer)->UserComment.MaximumLength
  7114. >= 0)
  7115. ) {
  7116. printf("Succeeded\n");
  7117. printf(" User Comment is: *%wZ*\n",
  7118. &(((USER_PREFERENCES_INFORMATION *)Buffer)->UserComment) );
  7119. } else {
  7120. printf("Failed\n");
  7121. printf(" One of the UNICODE_STRINGs not returned.\n");
  7122. TestStatus = FALSE;
  7123. }
  7124. SamFreeMemory( Buffer );
  7125. } else {
  7126. printf("Failed\n");
  7127. printf(" Buffer address not set on return.\n");
  7128. printf(" RPC should have allocated a buffer.\n");
  7129. TestStatus = FALSE;
  7130. }
  7131. } else {
  7132. printf("Failed\n");
  7133. printf(" Completion status is 0x%lx\n", NtStatus);
  7134. TestStatus = FALSE;
  7135. }
  7136. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7137. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7138. printf(" Query User Home Directory Information . . . . . . . . ");
  7139. NtStatus = SamOpenUser(
  7140. DomainHandle,
  7141. USER_READ_LOGON,
  7142. DOMAIN_USER_RID_ADMIN,
  7143. &UserHandle1
  7144. );
  7145. ASSERT(NT_SUCCESS(NtStatus) );
  7146. Buffer = NULL;
  7147. NtStatus = SamQueryInformationUser(
  7148. UserHandle1,
  7149. UserHomeInformation,
  7150. &Buffer
  7151. );
  7152. if (NT_SUCCESS(NtStatus)) {
  7153. if (Buffer != NULL) {
  7154. if ( (((USER_HOME_INFORMATION *)Buffer)->HomeDirectory.MaximumLength
  7155. >= 0) &&
  7156. (((USER_HOME_INFORMATION *)Buffer)->HomeDirectoryDrive.MaximumLength
  7157. >= 0)
  7158. ) {
  7159. printf("Succeeded\n");
  7160. printf(" Home Directory is: *%wZ*\n",
  7161. &(((USER_HOME_INFORMATION *)Buffer)->HomeDirectory) );
  7162. printf(" Home Directory Drive is: *%wZ*\n",
  7163. &(((USER_HOME_INFORMATION *)Buffer)->HomeDirectoryDrive) );
  7164. } else {
  7165. printf("Failed\n");
  7166. printf(" String not returned.\n");
  7167. TestStatus = FALSE;
  7168. }
  7169. SamFreeMemory( Buffer );
  7170. } else {
  7171. printf("Failed\n");
  7172. printf(" Buffer address not set on return.\n");
  7173. printf(" RPC should have allocated a buffer.\n");
  7174. TestStatus = FALSE;
  7175. }
  7176. } else {
  7177. printf("Failed\n");
  7178. printf(" Completion status is 0x%lx\n", NtStatus);
  7179. TestStatus = FALSE;
  7180. }
  7181. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7182. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7183. printf(" Query User Script Path Information . . . . . . . . . ");
  7184. NtStatus = SamOpenUser(
  7185. DomainHandle,
  7186. USER_READ_LOGON,
  7187. DOMAIN_USER_RID_ADMIN,
  7188. &UserHandle1
  7189. );
  7190. ASSERT(NT_SUCCESS(NtStatus) );
  7191. Buffer = NULL;
  7192. NtStatus = SamQueryInformationUser(
  7193. UserHandle1,
  7194. UserScriptInformation,
  7195. &Buffer
  7196. );
  7197. if (NT_SUCCESS(NtStatus)) {
  7198. if (Buffer != NULL) {
  7199. if ( (((USER_SCRIPT_INFORMATION *)Buffer)->ScriptPath.MaximumLength
  7200. >= 0)
  7201. ) {
  7202. printf("Succeeded\n");
  7203. printf(" Script Path is: *%wZ*\n",
  7204. &(((USER_SCRIPT_INFORMATION *)Buffer)->ScriptPath) );
  7205. } else {
  7206. printf("Failed\n");
  7207. printf(" String not returned.\n");
  7208. TestStatus = FALSE;
  7209. }
  7210. SamFreeMemory( Buffer );
  7211. } else {
  7212. printf("Failed\n");
  7213. printf(" Buffer address not set on return.\n");
  7214. printf(" RPC should have allocated a buffer.\n");
  7215. TestStatus = FALSE;
  7216. }
  7217. } else {
  7218. printf("Failed\n");
  7219. printf(" Completion status is 0x%lx\n", NtStatus);
  7220. TestStatus = FALSE;
  7221. }
  7222. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7223. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7224. printf(" Query User ProfilePath Information . . . . . . . . . ");
  7225. NtStatus = SamOpenUser(
  7226. DomainHandle,
  7227. USER_READ_LOGON,
  7228. DOMAIN_USER_RID_ADMIN,
  7229. &UserHandle1
  7230. );
  7231. ASSERT(NT_SUCCESS(NtStatus) );
  7232. Buffer = NULL;
  7233. NtStatus = SamQueryInformationUser(
  7234. UserHandle1,
  7235. UserProfileInformation,
  7236. &Buffer
  7237. );
  7238. if (NT_SUCCESS(NtStatus)) {
  7239. if (Buffer != NULL) {
  7240. if ( (((USER_PROFILE_INFORMATION *)Buffer)->ProfilePath.MaximumLength
  7241. >= 0)
  7242. ) {
  7243. printf("Succeeded\n");
  7244. printf(" Profile Path is: *%wZ*\n",
  7245. &(((USER_PROFILE_INFORMATION *)Buffer)->ProfilePath) );
  7246. } else {
  7247. printf("Failed\n");
  7248. printf(" String not returned.\n");
  7249. TestStatus = FALSE;
  7250. }
  7251. SamFreeMemory( Buffer );
  7252. } else {
  7253. printf("Failed\n");
  7254. printf(" Buffer address not set on return.\n");
  7255. printf(" RPC should have allocated a buffer.\n");
  7256. TestStatus = FALSE;
  7257. }
  7258. } else {
  7259. printf("Failed\n");
  7260. printf(" Completion status is 0x%lx\n", NtStatus);
  7261. TestStatus = FALSE;
  7262. }
  7263. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7264. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7265. printf(" Query User Logon Information . . . . . . . . . . . . ");
  7266. NtStatus = SamOpenUser(
  7267. DomainHandle,
  7268. USER_READ_ACCOUNT | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON,
  7269. DOMAIN_USER_RID_ADMIN,
  7270. &UserHandle1
  7271. );
  7272. ASSERT(NT_SUCCESS(NtStatus) );
  7273. Buffer = NULL;
  7274. NtStatus = SamQueryInformationUser(
  7275. UserHandle1,
  7276. UserLogonInformation,
  7277. &Buffer
  7278. );
  7279. if (NT_SUCCESS(NtStatus)) {
  7280. if (Buffer != NULL) {
  7281. if ( (((USER_LOGON_INFORMATION *)Buffer)->UserName.MaximumLength > 0) &&
  7282. (((USER_LOGON_INFORMATION *)Buffer)->UserName.Buffer != NULL)
  7283. ) {
  7284. printf("Succeeded\n");
  7285. printf(" User RID is: 0x%lx\n",
  7286. (((USER_LOGON_INFORMATION *)Buffer)->UserId) );
  7287. printf(" Primary Group is: 0x%lx\n",
  7288. (((USER_LOGON_INFORMATION *)Buffer)->PrimaryGroupId) );
  7289. printf(" Logon Units are: 0x%lx\n",
  7290. (((USER_LOGON_INFORMATION *)Buffer)->LogonHours.UnitsPerWeek) );
  7291. printf(" Bad PWD count is: 0x%lx\n",
  7292. (((USER_LOGON_INFORMATION *)Buffer)->BadPasswordCount) );
  7293. printf(" Logon count is: 0x%lx\n",
  7294. (((USER_LOGON_INFORMATION *)Buffer)->LogonCount) );
  7295. printf(" last Logon is: (0x%lx, 0x%lx)\n",
  7296. (((USER_LOGON_INFORMATION *)Buffer)->LastLogon.HighPart),
  7297. (((USER_LOGON_INFORMATION *)Buffer)->LastLogon.LowPart) );
  7298. printf(" last Logoff is: (0x%lx, 0x%lx)\n",
  7299. (((USER_LOGON_INFORMATION *)Buffer)->LastLogoff.HighPart),
  7300. (((USER_LOGON_INFORMATION *)Buffer)->LastLogoff.LowPart) );
  7301. printf(" User Name is: *%wZ*\n",
  7302. &(((USER_LOGON_INFORMATION *)Buffer)->UserName) );
  7303. printf(" Full Name is: *%wZ*\n",
  7304. &(((USER_LOGON_INFORMATION *)Buffer)->FullName) );
  7305. printf(" Home Dir is: *%wZ*\n",
  7306. &(((USER_LOGON_INFORMATION *)Buffer)->HomeDirectory) );
  7307. printf(" Home Dir Drive is: *%wZ*\n",
  7308. &(((USER_LOGON_INFORMATION *)Buffer)->HomeDirectoryDrive) );
  7309. printf(" Script Path is: *%wZ*\n",
  7310. &(((USER_LOGON_INFORMATION *)Buffer)->ScriptPath) );
  7311. printf(" Profile Path is: *%wZ*\n",
  7312. &(((USER_LOGON_INFORMATION *)Buffer)->ProfilePath) );
  7313. printf(" WorkStations are: *%wZ*\n",
  7314. &(((USER_LOGON_INFORMATION *)Buffer)->WorkStations) );
  7315. } else {
  7316. printf("Failed\n");
  7317. printf(" One of the UNICODE_STRINGs not returned.\n");
  7318. TestStatus = FALSE;
  7319. }
  7320. SamFreeMemory( Buffer );
  7321. } else {
  7322. printf("Failed\n");
  7323. printf(" Buffer address not set on return.\n");
  7324. printf(" RPC should have allocated a buffer.\n");
  7325. TestStatus = FALSE;
  7326. }
  7327. } else {
  7328. printf("Failed\n");
  7329. printf(" Completion status is 0x%lx\n", NtStatus);
  7330. TestStatus = FALSE;
  7331. }
  7332. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7333. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7334. printf(" Query User Logon Hours . . . . . . . . . . . . . . . ");
  7335. NtStatus = SamOpenUser(
  7336. DomainHandle,
  7337. USER_READ_LOGON,
  7338. DOMAIN_USER_RID_ADMIN,
  7339. &UserHandle1
  7340. );
  7341. ASSERT(NT_SUCCESS(NtStatus) );
  7342. Buffer = NULL;
  7343. NtStatus = SamQueryInformationUser(
  7344. UserHandle1,
  7345. UserLogonHoursInformation,
  7346. &Buffer
  7347. );
  7348. if (NT_SUCCESS(NtStatus)) {
  7349. if (Buffer != NULL) {
  7350. printf("Succeeded\n");
  7351. printf(" Logon Units are: 0x%lx\n",
  7352. (((USER_LOGON_HOURS_INFORMATION *)Buffer)->LogonHours.UnitsPerWeek) );
  7353. SamFreeMemory( Buffer );
  7354. } else {
  7355. printf("Failed\n");
  7356. printf(" Buffer address not set on return.\n");
  7357. printf(" RPC should have allocated a buffer.\n");
  7358. TestStatus = FALSE;
  7359. }
  7360. } else {
  7361. printf("Failed\n");
  7362. printf(" Completion status is 0x%lx\n", NtStatus);
  7363. TestStatus = FALSE;
  7364. }
  7365. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7366. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7367. printf(" Query Account Information . . . . . . . . . . . . . . ");
  7368. NtStatus = SamOpenUser(
  7369. DomainHandle,
  7370. USER_READ_GENERAL | USER_READ_PREFERENCES |
  7371. USER_READ_LOGON | USER_READ_ACCOUNT,
  7372. DOMAIN_USER_RID_ADMIN,
  7373. &UserHandle1
  7374. );
  7375. ASSERT(NT_SUCCESS(NtStatus) );
  7376. Buffer = NULL;
  7377. NtStatus = SamQueryInformationUser(
  7378. UserHandle1,
  7379. UserAccountInformation,
  7380. &Buffer
  7381. );
  7382. if (NT_SUCCESS(NtStatus)) {
  7383. if (Buffer != NULL) {
  7384. if ( (((USER_ACCOUNT_INFORMATION *)Buffer)->UserName.MaximumLength > 0) &&
  7385. (((USER_ACCOUNT_INFORMATION *)Buffer)->UserName.Buffer != NULL)
  7386. ) {
  7387. printf("Succeeded\n");
  7388. printf(" User RID is: 0x%lx\n",
  7389. (((USER_ACCOUNT_INFORMATION *)Buffer)->UserId) );
  7390. printf(" Primary Group is: 0x%lx\n",
  7391. (((USER_ACCOUNT_INFORMATION *)Buffer)->PrimaryGroupId) );
  7392. printf(" Logon Units are: 0x%lx\n",
  7393. (((USER_ACCOUNT_INFORMATION *)Buffer)->LogonHours.UnitsPerWeek) );
  7394. printf(" Bad PWD count is: 0x%lx\n",
  7395. (((USER_ACCOUNT_INFORMATION *)Buffer)->BadPasswordCount) );
  7396. printf(" Logon count is: 0x%lx\n",
  7397. (((USER_ACCOUNT_INFORMATION *)Buffer)->LogonCount) );
  7398. printf(" Account Ctrl is: 0x%lx\n",
  7399. (((USER_ACCOUNT_INFORMATION *)Buffer)->UserAccountControl) );
  7400. printf(" last Logon is: (0x%lx, 0x%lx)\n",
  7401. (((USER_ACCOUNT_INFORMATION *)Buffer)->LastLogon.HighPart),
  7402. (((USER_ACCOUNT_INFORMATION *)Buffer)->LastLogon.LowPart) );
  7403. printf(" last Logoff is: (0x%lx, 0x%lx)\n",
  7404. (((USER_ACCOUNT_INFORMATION *)Buffer)->LastLogoff.HighPart),
  7405. (((USER_ACCOUNT_INFORMATION *)Buffer)->LastLogoff.LowPart) );
  7406. printf(" Pwd Last Set is: (0x%lx, 0x%lx)\n",
  7407. (((USER_ACCOUNT_INFORMATION *)Buffer)->PasswordLastSet.HighPart),
  7408. (((USER_ACCOUNT_INFORMATION *)Buffer)->PasswordLastSet.LowPart) );
  7409. printf(" Account Expires is: (0x%lx, 0x%lx)\n",
  7410. (((USER_ACCOUNT_INFORMATION *)Buffer)->AccountExpires.HighPart),
  7411. (((USER_ACCOUNT_INFORMATION *)Buffer)->AccountExpires.LowPart) );
  7412. printf(" User Name is: *%wZ*\n",
  7413. &(((USER_ACCOUNT_INFORMATION *)Buffer)->UserName) );
  7414. printf(" Full Name is: *%wZ*\n",
  7415. &(((USER_ACCOUNT_INFORMATION *)Buffer)->FullName) );
  7416. printf(" Home Dir is: *%wZ*\n",
  7417. &(((USER_ACCOUNT_INFORMATION *)Buffer)->HomeDirectory) );
  7418. printf(" Home Dir Drive is: *%wZ*\n",
  7419. &(((USER_ACCOUNT_INFORMATION *)Buffer)->HomeDirectoryDrive) );
  7420. printf(" Script Path is: *%wZ*\n",
  7421. &(((USER_ACCOUNT_INFORMATION *)Buffer)->ScriptPath) );
  7422. printf(" Profile Path is: *%wZ*\n",
  7423. &(((USER_ACCOUNT_INFORMATION *)Buffer)->ProfilePath) );
  7424. printf(" Admin Comment is: *%wZ*\n",
  7425. &(((USER_ACCOUNT_INFORMATION *)Buffer)->AdminComment) );
  7426. printf(" WorkStations are: *%wZ*\n",
  7427. &(((USER_ACCOUNT_INFORMATION *)Buffer)->WorkStations) );
  7428. } else {
  7429. printf("Failed\n");
  7430. printf(" One of the UNICODE_STRINGs not returned.\n");
  7431. TestStatus = FALSE;
  7432. }
  7433. SamFreeMemory( Buffer );
  7434. } else {
  7435. printf("Failed\n");
  7436. printf(" Buffer address not set on return.\n");
  7437. printf(" RPC should have allocated a buffer.\n");
  7438. TestStatus = FALSE;
  7439. }
  7440. } else {
  7441. printf("Failed\n");
  7442. printf(" Completion status is 0x%lx\n", NtStatus);
  7443. TestStatus = FALSE;
  7444. }
  7445. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7446. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7447. printf(" Query Workstations Information . . . . . . . . . . . ");
  7448. NtStatus = SamOpenUser(
  7449. DomainHandle,
  7450. USER_READ_LOGON,
  7451. DOMAIN_USER_RID_ADMIN,
  7452. &UserHandle1
  7453. );
  7454. ASSERT(NT_SUCCESS(NtStatus) );
  7455. Buffer = NULL;
  7456. NtStatus = SamQueryInformationUser(
  7457. UserHandle1,
  7458. UserWorkStationsInformation,
  7459. &Buffer
  7460. );
  7461. if (NT_SUCCESS(NtStatus)) {
  7462. if (Buffer != NULL) {
  7463. if ( (((USER_WORKSTATIONS_INFORMATION *)Buffer)->WorkStations.MaximumLength
  7464. >= 0)
  7465. ) {
  7466. printf("Succeeded\n");
  7467. printf(" Workstations is: *%wZ*\n",
  7468. &(((USER_WORKSTATIONS_INFORMATION *)Buffer)->WorkStations) );
  7469. } else {
  7470. printf("Failed\n");
  7471. printf(" String not returned.\n");
  7472. TestStatus = FALSE;
  7473. }
  7474. SamFreeMemory( Buffer );
  7475. } else {
  7476. printf("Failed\n");
  7477. printf(" Buffer address not set on return.\n");
  7478. printf(" RPC should have allocated a buffer.\n");
  7479. TestStatus = FALSE;
  7480. }
  7481. } else {
  7482. printf("Failed\n");
  7483. printf(" Completion status is 0x%lx\n", NtStatus);
  7484. TestStatus = FALSE;
  7485. }
  7486. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7487. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7488. printf(" Query Internal1 Information . . . . . . . . . . . ");
  7489. NtStatus = SamOpenUser(
  7490. DomainHandle,
  7491. USER_READ_LOGON,
  7492. DOMAIN_USER_RID_ADMIN,
  7493. &UserHandle1
  7494. );
  7495. ASSERT(NT_SUCCESS(NtStatus) );
  7496. Buffer = NULL;
  7497. NtStatus = SamQueryInformationUser(
  7498. UserHandle1,
  7499. UserInternal1Information,
  7500. &Buffer
  7501. );
  7502. if ( NtStatus == STATUS_INVALID_INFO_CLASS ) {
  7503. //
  7504. // We're not a trusted client, so we expected this to fail.
  7505. //
  7506. printf("Succeeded\n");
  7507. } else {
  7508. printf("Failed\n");
  7509. printf(" Status was %lx.\n", NtStatus );
  7510. TestStatus = FALSE;
  7511. if ( NT_SUCCESS( NtStatus ) ) {
  7512. SamFreeMemory( Buffer );
  7513. }
  7514. }
  7515. // This is the code that USED to test this function, when it was allowed
  7516. // for non-trusted clients.
  7517. //
  7518. // if (NT_SUCCESS(NtStatus)) {
  7519. // if (Buffer != NULL) {
  7520. //
  7521. // if ( (((USER_INTERNAL1_INFORMATION *)Buffer)->CaseInsensitiveDbcs.MaximumLength > 0) &&
  7522. // (((USER_INTERNAL1_INFORMATION *)Buffer)->CaseInsensitiveDbcs.Buffer != NULL) &&
  7523. // (((USER_INTERNAL1_INFORMATION *)Buffer)->CaseSensitiveUnicode.MaximumLength > 0) &&
  7524. // (((USER_INTERNAL1_INFORMATION *)Buffer)->CaseSensitiveUnicode.Buffer != NULL)
  7525. // ) {
  7526. //
  7527. // printf("Succeeded\n");
  7528. //
  7529. // //
  7530. // // Print them out as strings, even though they've been
  7531. // // through a OWF.
  7532. // //
  7533. //
  7534. // printf(" CaseInsensitiveDbcs is: *%s*\n",
  7535. // &(((USER_INTERNAL1_INFORMATION *)Buffer)->CaseInsensitiveDbcs) );
  7536. //
  7537. // printf(" CaseSensitiveUnicode is: *%s*\n",
  7538. // &(((USER_INTERNAL1_INFORMATION *)Buffer)->CaseSensitiveUnicode) );
  7539. //
  7540. //
  7541. // } else {
  7542. // printf("Failed\n");
  7543. // printf(" One of the strings not returned.\n");
  7544. // TestStatus = FALSE;
  7545. // }
  7546. // SamFreeMemory( Buffer );
  7547. // } else {
  7548. // printf("Failed\n");
  7549. // printf(" Buffer address not set on return.\n");
  7550. // printf(" RPC should have allocated a buffer.\n");
  7551. // TestStatus = FALSE;
  7552. // }
  7553. // } else {
  7554. // printf("Failed\n");
  7555. // printf(" Completion status is 0x%lx\n", NtStatus);
  7556. // TestStatus = FALSE;
  7557. // }
  7558. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7559. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7560. printf(" Query Internal2 Information . . . . . . . . . . . ");
  7561. NtStatus = SamOpenUser(
  7562. DomainHandle,
  7563. USER_READ_LOGON,
  7564. DOMAIN_USER_RID_ADMIN,
  7565. &UserHandle1
  7566. );
  7567. ASSERT(NT_SUCCESS(NtStatus) );
  7568. Buffer = NULL;
  7569. NtStatus = SamQueryInformationUser(
  7570. UserHandle1,
  7571. UserInternal2Information,
  7572. &Buffer
  7573. );
  7574. if ( NtStatus == STATUS_INVALID_INFO_CLASS ) {
  7575. //
  7576. // We're not a trusted client, so we don't expect to be able
  7577. // to do this.
  7578. //
  7579. printf("Succeeded.\n");
  7580. } else {
  7581. printf("Failed\n");
  7582. printf(" Completion status is 0x%lx\n", NtStatus);
  7583. TestStatus = FALSE;
  7584. SamFreeMemory( Buffer );
  7585. }
  7586. // This is the code that USED to test this function, when non-trusted
  7587. // clients were allowed to do this...
  7588. //
  7589. // if (NT_SUCCESS(NtStatus)) {
  7590. // if (Buffer != NULL) {
  7591. //
  7592. // printf("Succeeded\n");
  7593. //
  7594. // printf(" last Logon is: (0x%lx, 0x%lx)\n",
  7595. // (((USER_INTERNAL2_INFORMATION *)Buffer)->LastLogon.HighPart),
  7596. // (((USER_INTERNAL2_INFORMATION *)Buffer)->LastLogon.LowPart) );
  7597. // printf(" last Logoff is: (0x%lx, 0x%lx)\n",
  7598. // (((USER_INTERNAL2_INFORMATION *)Buffer)->LastLogoff.HighPart),
  7599. // (((USER_INTERNAL2_INFORMATION *)Buffer)->LastLogoff.LowPart) );
  7600. // printf(" BadPwdCount is: (0x%x)\n",
  7601. // ((USER_INTERNAL2_INFORMATION *)Buffer)->BadPasswordCount );
  7602. // printf(" LogonCount is: (0x%x)\n",
  7603. // ((USER_INTERNAL2_INFORMATION *)Buffer)->LogonCount );
  7604. //
  7605. // SamFreeMemory( Buffer );
  7606. // } else {
  7607. // printf("Failed\n");
  7608. // printf(" Buffer address not set on return.\n");
  7609. // printf(" RPC should have allocated a buffer.\n");
  7610. // TestStatus = FALSE;
  7611. // }
  7612. // } else {
  7613. // printf("Failed\n");
  7614. // printf(" Completion status is 0x%lx\n", NtStatus);
  7615. // TestStatus = FALSE;
  7616. // }
  7617. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7618. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7619. printf(" Query Set Password Information . . . . . . . . . . . ");
  7620. NtStatus = SamOpenUser(
  7621. DomainHandle,
  7622. USER_READ_LOGON,
  7623. DOMAIN_USER_RID_ADMIN,
  7624. &UserHandle1
  7625. );
  7626. ASSERT(NT_SUCCESS(NtStatus) );
  7627. Buffer = NULL;
  7628. NtStatus = SamQueryInformationUser(
  7629. UserHandle1,
  7630. UserSetPasswordInformation,
  7631. &Buffer
  7632. );
  7633. if (NtStatus == STATUS_INVALID_INFO_CLASS ) {
  7634. printf("Succeeded\n");
  7635. } else {
  7636. printf("Failed\n");
  7637. printf(" Completion status is 0x%lx\n", NtStatus);
  7638. printf(" Expected 0x%lx (INVALID_INFO_CLASS)\n", STATUS_INVALID_INFO_CLASS);
  7639. TestStatus = FALSE;
  7640. }
  7641. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7642. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7643. ///////////////////////////////////////////////////////////////////////////
  7644. // //
  7645. // Get Groups For User Suite //
  7646. // //
  7647. ///////////////////////////////////////////////////////////////////////////
  7648. printf("\n");
  7649. printf(" Get Groups For User . . . . . . . . . . . . . . . . . Suite\n");
  7650. printf(" Get Groups For Well-Known Account . . . . . . . . . . ");
  7651. NtStatus = SamOpenUser(
  7652. DomainHandle,
  7653. USER_LIST_GROUPS,
  7654. DOMAIN_USER_RID_ADMIN,
  7655. &UserHandle1
  7656. );
  7657. ASSERT(NT_SUCCESS(NtStatus) );
  7658. Buffer = NULL;
  7659. NtStatus = SamGetGroupsForUser(
  7660. UserHandle1,
  7661. (PGROUP_MEMBERSHIP *)&Buffer,
  7662. &MembershipCount
  7663. );
  7664. if (NT_SUCCESS(NtStatus)) {
  7665. if (Buffer != NULL) {
  7666. printf("Succeeded\n");
  7667. printf(" Member of: %d groups\n", MembershipCount);
  7668. for ( i=0; i<MembershipCount; i++) {
  7669. printf(" Group[%d] Rid/Attributes: 0x%lx/0x%lx\n",
  7670. i,
  7671. (((PGROUP_MEMBERSHIP)Buffer)[i].RelativeId),
  7672. (((PGROUP_MEMBERSHIP)Buffer)[i].Attributes)
  7673. );
  7674. }
  7675. SamFreeMemory( Buffer );
  7676. } else {
  7677. printf("Failed\n");
  7678. printf(" Buffer address not set on return.\n");
  7679. printf(" RPC should have allocated a buffer.\n");
  7680. TestStatus = FALSE;
  7681. }
  7682. } else {
  7683. printf("Failed\n");
  7684. printf(" Completion status is 0x%lx\n", NtStatus);
  7685. TestStatus = FALSE;
  7686. }
  7687. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7688. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7689. ///////////////////////////////////////////////////////////////////////////
  7690. // //
  7691. // Set User Suite //
  7692. // //
  7693. ///////////////////////////////////////////////////////////////////////////
  7694. printf("\n");
  7695. printf(" Set User . . . . . . . . . . . . . . . . . . . . . . Suite\n");
  7696. printf(" Set General Information . . . . . . . . . . . . . . . ");
  7697. NtStatus = SamOpenUser(
  7698. DomainHandle,
  7699. USER_ALL_ACCESS,
  7700. DOMAIN_USER_RID_ADMIN,
  7701. &UserHandle1
  7702. );
  7703. ASSERT(NT_SUCCESS(NtStatus) );
  7704. //
  7705. // Make the parameter marshallable, but don't worry about values.
  7706. //
  7707. GeneralInformation.UserName = DummyName1;
  7708. GeneralInformation.FullName = DummyName1;
  7709. GeneralInformation.AdminComment = DummyName1;
  7710. GeneralInformation.UserComment = DummyName1;
  7711. Buffer = &GeneralInformation;
  7712. NtStatus = SamSetInformationUser(
  7713. UserHandle1,
  7714. UserGeneralInformation,
  7715. Buffer
  7716. );
  7717. if (NtStatus == STATUS_INVALID_INFO_CLASS ) {
  7718. printf("Succeeded\n");
  7719. } else {
  7720. printf("Failed\n");
  7721. printf(" Completion status is 0x%lx\n", NtStatus);
  7722. printf(" Expected 0x%lx (INVALID_INFO_CLASS)\n", STATUS_INVALID_INFO_CLASS);
  7723. TestStatus = FALSE;
  7724. }
  7725. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7726. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7727. printf(" Set Preferences Information . . . . . . . . . . . . . ");
  7728. NtStatus = SamOpenUser(
  7729. DomainHandle,
  7730. USER_READ_GENERAL | USER_WRITE_PREFERENCES | USER_READ_PREFERENCES,
  7731. DOMAIN_USER_RID_ADMIN,
  7732. &UserHandle1
  7733. );
  7734. ASSERT(NT_SUCCESS(NtStatus) );
  7735. //
  7736. // Get the current value...
  7737. //
  7738. Buffer1 = NULL;
  7739. NtStatus = SamQueryInformationUser(
  7740. UserHandle1,
  7741. UserPreferencesInformation,
  7742. &Buffer1
  7743. );
  7744. TST_SUCCESS_ASSERT(NtStatus);
  7745. ASSERT(Buffer1 != NULL);
  7746. //
  7747. // Change the fields to new values and write them out.
  7748. //
  7749. NameLength = ((USER_PREFERENCES_INFORMATION *)Buffer1)->UserComment.Length;
  7750. if ( NameLength == DummyString1.Length ) {
  7751. ((USER_PREFERENCES_INFORMATION *)Buffer1)->UserComment = DummyString2;
  7752. } else {
  7753. ((USER_PREFERENCES_INFORMATION *)Buffer1)->UserComment = DummyString1;
  7754. }
  7755. ((USER_PREFERENCES_INFORMATION *)Buffer1)->CountryCode += 1;
  7756. ((USER_PREFERENCES_INFORMATION *)Buffer1)->CodePage += 1;
  7757. NtStatus = SamSetInformationUser(
  7758. UserHandle1,
  7759. UserPreferencesInformation,
  7760. Buffer1
  7761. );
  7762. if ( NT_SUCCESS(NtStatus) ) {
  7763. //
  7764. // Now check that the change was really made...
  7765. //
  7766. NtStatus = SamQueryInformationUser(
  7767. UserHandle1,
  7768. UserPreferencesInformation,
  7769. &Buffer2
  7770. );
  7771. ASSERT(NT_SUCCESS( NtStatus ) );
  7772. if (
  7773. !RtlCompareString(
  7774. (PSTRING)&((USER_PREFERENCES_INFORMATION *)Buffer1)->UserComment,
  7775. (PSTRING)&((USER_PREFERENCES_INFORMATION *)Buffer2)->UserComment,
  7776. TRUE)
  7777. &&
  7778. (((USER_PREFERENCES_INFORMATION *)Buffer1)->CountryCode ==
  7779. ((USER_PREFERENCES_INFORMATION *)Buffer2)->CountryCode)
  7780. &&
  7781. (((USER_PREFERENCES_INFORMATION *)Buffer1)->CodePage ==
  7782. ((USER_PREFERENCES_INFORMATION *)Buffer2)->CodePage)
  7783. ) {
  7784. printf("Succeeded\n");
  7785. //
  7786. // Change back some fields to keep from screwing up our database
  7787. //
  7788. ((USER_PREFERENCES_INFORMATION *)Buffer1)->CountryCode -= 1;
  7789. ((USER_PREFERENCES_INFORMATION *)Buffer1)->CodePage -= 1;
  7790. IgnoreStatus = SamSetInformationUser(
  7791. UserHandle1,
  7792. UserPreferencesInformation,
  7793. Buffer1
  7794. );
  7795. ASSERT(NT_SUCCESS(IgnoreStatus));
  7796. } else {
  7797. printf("Failed\n");
  7798. printf(" Values queried don't match values written\n");
  7799. printf(" UserComment Written is %wZ\n",
  7800. (PUNICODE_STRING)&((USER_PREFERENCES_INFORMATION *)Buffer1)->UserComment);
  7801. printf(" UserComment Retrieved is %wZ\n",
  7802. (PUNICODE_STRING)&((USER_PREFERENCES_INFORMATION *)Buffer2)->UserComment);
  7803. printf(" CountryCode Written is 0x%lx\n",
  7804. (ULONG)((USER_PREFERENCES_INFORMATION *)Buffer1)->CountryCode);
  7805. printf(" CountryCode Retrieved is 0x%lx\n",
  7806. (ULONG)((USER_PREFERENCES_INFORMATION *)Buffer2)->CountryCode);
  7807. printf(" CodePage Written is 0x%lx\n",
  7808. (ULONG)((USER_PREFERENCES_INFORMATION *)Buffer1)->CodePage);
  7809. printf(" CodePage Retrieved is 0x%lx\n",
  7810. (ULONG)((USER_PREFERENCES_INFORMATION *)Buffer2)->CodePage);
  7811. TestStatus = FALSE;
  7812. }
  7813. SamFreeMemory( Buffer1 );
  7814. SamFreeMemory( Buffer2 );
  7815. } else {
  7816. printf("Failed\n");
  7817. printf(" Completion status is 0x%lx\n", NtStatus);
  7818. TestStatus = FALSE;
  7819. SamFreeMemory( Buffer1 );
  7820. }
  7821. printf(" Set Logon Information . . . . . . . . . . . . . . . . ");
  7822. NtStatus = SamOpenUser(
  7823. DomainHandle,
  7824. USER_ALL_ACCESS,
  7825. DOMAIN_USER_RID_ADMIN,
  7826. &UserHandle1
  7827. );
  7828. ASSERT(NT_SUCCESS(NtStatus) );
  7829. //
  7830. // Make the parameter marshallable, but don't worry about values.
  7831. //
  7832. LogonInformation.UserName = DummyName1;
  7833. LogonInformation.FullName = DummyName1;
  7834. LogonInformation.HomeDirectory = DummyName1;
  7835. LogonInformation.HomeDirectoryDrive = DummyName1;
  7836. LogonInformation.ScriptPath = DummyName1;
  7837. LogonInformation.ProfilePath = DummyName1;
  7838. LogonInformation.WorkStations = DummyName1;
  7839. LogonInformation.LogonHours = DummyLogonHours;
  7840. Buffer = &LogonInformation;
  7841. NtStatus = SamSetInformationUser(
  7842. UserHandle1,
  7843. UserLogonInformation,
  7844. Buffer
  7845. );
  7846. if (NtStatus == STATUS_INVALID_INFO_CLASS ) {
  7847. printf("Succeeded\n");
  7848. } else {
  7849. printf("Failed\n");
  7850. printf(" Completion status is 0x%lx\n", NtStatus);
  7851. printf(" Expected 0x%lx (INVALID_INFO_CLASS)\n", STATUS_INVALID_INFO_CLASS);
  7852. TestStatus = FALSE;
  7853. }
  7854. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7855. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7856. printf(" Set Logon Hours Information . . . . . . . . . . . . . ");
  7857. NtStatus = SamOpenUser(
  7858. DomainHandle,
  7859. USER_WRITE_ACCOUNT | USER_READ_LOGON,
  7860. DOMAIN_USER_RID_ADMIN,
  7861. &UserHandle1
  7862. );
  7863. ASSERT(NT_SUCCESS(NtStatus) );
  7864. //
  7865. // Get the current value...
  7866. //
  7867. Buffer1 = NULL;
  7868. NtStatus = SamQueryInformationUser(
  7869. UserHandle1,
  7870. UserLogonHoursInformation,
  7871. &Buffer1
  7872. );
  7873. TST_SUCCESS_ASSERT(NtStatus);
  7874. ASSERT(Buffer1 != NULL);
  7875. ASSERT( ((USER_LOGON_HOURS_INFORMATION *)Buffer1)->LogonHours.LogonHours
  7876. != NULL); //Don't support zero length bit masks in this test yet.
  7877. //
  7878. // Change the field to a new value and write it out.
  7879. // We have two choices for out test:
  7880. // NoLogonRestriction
  7881. // DummyLogonHours
  7882. //
  7883. // They are guaranteed to have different values in the
  7884. // LOGON_HOURS_DIFFERENT_OFFSET byte of their respective bit masks.
  7885. //
  7886. if ( 0 == ((USER_LOGON_HOURS_INFORMATION *)Buffer1)->LogonHours.LogonHours[LOGON_HOURS_DIFFERENT_OFFSET]) {
  7887. ((USER_LOGON_HOURS_INFORMATION *)Buffer1)->LogonHours = DummyLogonHours;
  7888. } else {
  7889. ((USER_LOGON_HOURS_INFORMATION *)Buffer1)->LogonHours = NoLogonRestriction;
  7890. }
  7891. NtStatus = SamSetInformationUser(
  7892. UserHandle1,
  7893. UserLogonHoursInformation,
  7894. Buffer1
  7895. );
  7896. if ( NT_SUCCESS(NtStatus) ) {
  7897. //
  7898. // Now check that the change was really made...
  7899. //
  7900. NtStatus = SamQueryInformationUser(
  7901. UserHandle1,
  7902. UserLogonHoursInformation,
  7903. &Buffer2
  7904. );
  7905. ASSERT(NT_SUCCESS( NtStatus ) );
  7906. if (
  7907. ((USER_LOGON_HOURS_INFORMATION *)Buffer1)->LogonHours.LogonHours[LOGON_HOURS_DIFFERENT_OFFSET]
  7908. ==
  7909. ((USER_LOGON_HOURS_INFORMATION *)Buffer2)->LogonHours.LogonHours[LOGON_HOURS_DIFFERENT_OFFSET]
  7910. ) {
  7911. printf("Succeeded\n");
  7912. } else {
  7913. printf("Failed\n");
  7914. printf(" Value queried doesn't match value written\n");
  7915. printf(" Units Written are 0x%lx\n",
  7916. ((USER_LOGON_HOURS_INFORMATION *)Buffer1)->LogonHours.UnitsPerWeek);
  7917. printf(" Units Retrieved are 0x%lx\n",
  7918. ((USER_LOGON_HOURS_INFORMATION *)Buffer2)->LogonHours.UnitsPerWeek);
  7919. printf(" Byte 0x%lx of the written bit mask is 0x%lx\n",
  7920. LOGON_HOURS_DIFFERENT_OFFSET,
  7921. (ULONG)((USER_LOGON_HOURS_INFORMATION *)Buffer1)->LogonHours.LogonHours[LOGON_HOURS_DIFFERENT_OFFSET]
  7922. );
  7923. printf(" Byte 0x%lx of the retrieved bit mask is 0x%lx\n",
  7924. LOGON_HOURS_DIFFERENT_OFFSET,
  7925. (ULONG)((USER_LOGON_HOURS_INFORMATION *)Buffer2)->LogonHours.LogonHours[LOGON_HOURS_DIFFERENT_OFFSET]
  7926. );
  7927. TestStatus = FALSE;
  7928. }
  7929. SamFreeMemory( Buffer1 );
  7930. SamFreeMemory( Buffer2 );
  7931. } else {
  7932. printf("Failed\n");
  7933. printf(" Completion status is 0x%lx\n", NtStatus);
  7934. TestStatus = FALSE;
  7935. SamFreeMemory( Buffer1 );
  7936. }
  7937. printf(" Set Account Information . . . . . . . . . . . . . . . ");
  7938. NtStatus = SamOpenUser(
  7939. DomainHandle,
  7940. USER_WRITE_ACCOUNT |
  7941. USER_READ_GENERAL |
  7942. USER_READ_PREFERENCES |
  7943. USER_READ_LOGON,
  7944. DOMAIN_USER_RID_ADMIN,
  7945. &UserHandle1
  7946. );
  7947. ASSERT(NT_SUCCESS(NtStatus) );
  7948. //
  7949. // Make the parameter marshallable, but don't worry about values.
  7950. //
  7951. AccountInformation.UserName = DummyName1;
  7952. AccountInformation.FullName = DummyName1;
  7953. AccountInformation.HomeDirectory = DummyName1;
  7954. AccountInformation.HomeDirectoryDrive = DummyName1;
  7955. AccountInformation.ScriptPath = DummyName1;
  7956. AccountInformation.ProfilePath = DummyName1;
  7957. AccountInformation.AdminComment = DummyName1;
  7958. AccountInformation.WorkStations = DummyName1;
  7959. AccountInformation.LogonHours = DummyLogonHours;
  7960. Buffer = &AccountInformation;
  7961. NtStatus = SamSetInformationUser(
  7962. UserHandle1,
  7963. UserAccountInformation,
  7964. Buffer
  7965. );
  7966. if (NtStatus == STATUS_INVALID_INFO_CLASS ) {
  7967. printf("Succeeded\n");
  7968. } else {
  7969. printf("Failed\n");
  7970. printf(" Completion status is 0x%lx\n", NtStatus);
  7971. printf(" Expected 0x%lx (INVALID_INFO_CLASS)\n", STATUS_INVALID_INFO_CLASS);
  7972. TestStatus = FALSE;
  7973. }
  7974. IgnoreStatus = SamCloseHandle( UserHandle1 );
  7975. ASSERT( NT_SUCCESS(IgnoreStatus) );
  7976. printf(" Set Home . . . . . . . . . . . . . . . . . . . . . . ");
  7977. NtStatus = SamOpenUser(
  7978. DomainHandle,
  7979. USER_WRITE_ACCOUNT | USER_READ_LOGON,
  7980. DOMAIN_USER_RID_ADMIN,
  7981. &UserHandle1
  7982. );
  7983. ASSERT(NT_SUCCESS(NtStatus) );
  7984. //
  7985. // Get the current value...
  7986. //
  7987. Buffer1 = NULL;
  7988. NtStatus = SamQueryInformationUser(
  7989. UserHandle1,
  7990. UserHomeInformation,
  7991. &Buffer1
  7992. );
  7993. TST_SUCCESS_ASSERT(NtStatus);
  7994. ASSERT(Buffer1 != NULL);
  7995. //
  7996. // Change the field to a new value and write it out.
  7997. //
  7998. NameLength = ((USER_HOME_INFORMATION *)Buffer1)->HomeDirectory.Length;
  7999. if ( NameLength == DummyString1.Length ) {
  8000. ((USER_HOME_INFORMATION *)Buffer1)->HomeDirectory = DummyString2;
  8001. } else {
  8002. ((USER_HOME_INFORMATION *)Buffer1)->HomeDirectory = DummyString1;
  8003. }
  8004. NameLength = ((USER_HOME_INFORMATION *)Buffer1)->HomeDirectoryDrive.Length;
  8005. if ( NameLength == DummyString1.Length ) {
  8006. ((USER_HOME_INFORMATION *)Buffer1)->HomeDirectoryDrive = DummyString2;
  8007. } else {
  8008. ((USER_HOME_INFORMATION *)Buffer1)->HomeDirectoryDrive = DummyString1;
  8009. }
  8010. NtStatus = SamSetInformationUser(
  8011. UserHandle1,
  8012. UserHomeInformation,
  8013. Buffer1
  8014. );
  8015. if ( NT_SUCCESS(NtStatus) ) {
  8016. //
  8017. // Now check that the change was really made...
  8018. //
  8019. NtStatus = SamQueryInformationUser(
  8020. UserHandle1,
  8021. UserHomeInformation,
  8022. &Buffer2
  8023. );
  8024. ASSERT(NT_SUCCESS( NtStatus ) );
  8025. if (!RtlCompareString(
  8026. (PSTRING)&((USER_HOME_INFORMATION *)Buffer1)->HomeDirectory,
  8027. (PSTRING)&((USER_HOME_INFORMATION *)Buffer2)->HomeDirectory,
  8028. TRUE) ) {
  8029. if (!RtlCompareString(
  8030. (PSTRING)&((USER_HOME_INFORMATION *)Buffer1)->HomeDirectoryDrive,
  8031. (PSTRING)&((USER_HOME_INFORMATION *)Buffer2)->HomeDirectoryDrive,
  8032. TRUE)
  8033. ) {
  8034. printf("Succeeded\n");
  8035. } else {
  8036. printf("Failed\n");
  8037. printf(" Drive Value queried doesn't match value written\n");
  8038. printf(" Value Written is %wZ\n",
  8039. (PUNICODE_STRING)&((USER_HOME_INFORMATION *)Buffer1)->HomeDirectoryDrive);
  8040. printf(" Value Retrieved is %wZ\n",
  8041. (PUNICODE_STRING)&((USER_HOME_INFORMATION *)Buffer2)->HomeDirectoryDrive);
  8042. TestStatus = FALSE;
  8043. }
  8044. } else {
  8045. printf("Failed\n");
  8046. printf(" Directory Value queried doesn't match value written\n");
  8047. printf(" Value Written is %wZ\n",
  8048. (PUNICODE_STRING)&((USER_HOME_INFORMATION *)Buffer1)->HomeDirectory);
  8049. printf(" Value Retrieved is %wZ\n",
  8050. (PUNICODE_STRING)&((USER_HOME_INFORMATION *)Buffer2)->HomeDirectory);
  8051. TestStatus = FALSE;
  8052. }
  8053. SamFreeMemory( Buffer1 );
  8054. SamFreeMemory( Buffer2 );
  8055. } else {
  8056. printf("Failed\n");
  8057. printf(" Completion status is 0x%lx\n", NtStatus);
  8058. TestStatus = FALSE;
  8059. SamFreeMemory( Buffer1 );
  8060. }
  8061. printf(" Set Script . . . . . . . . . . . . . . . . . . . . . ");
  8062. NtStatus = SamOpenUser(
  8063. DomainHandle,
  8064. USER_WRITE_ACCOUNT | USER_READ_LOGON,
  8065. DOMAIN_USER_RID_ADMIN,
  8066. &UserHandle1
  8067. );
  8068. ASSERT(NT_SUCCESS(NtStatus) );
  8069. //
  8070. // Get the current value...
  8071. //
  8072. Buffer1 = NULL;
  8073. NtStatus = SamQueryInformationUser(
  8074. UserHandle1,
  8075. UserScriptInformation,
  8076. &Buffer1
  8077. );
  8078. TST_SUCCESS_ASSERT(NtStatus);
  8079. ASSERT(Buffer1 != NULL);
  8080. //
  8081. // Change the field to a new value and write it out.
  8082. //
  8083. NameLength = ((USER_SCRIPT_INFORMATION *)Buffer1)->ScriptPath.Length;
  8084. if ( NameLength == DummyString1.Length ) {
  8085. ((USER_SCRIPT_INFORMATION *)Buffer1)->ScriptPath = DummyString2;
  8086. } else {
  8087. ((USER_SCRIPT_INFORMATION *)Buffer1)->ScriptPath = DummyString1;
  8088. }
  8089. NtStatus = SamSetInformationUser(
  8090. UserHandle1,
  8091. UserScriptInformation,
  8092. Buffer1
  8093. );
  8094. if ( NT_SUCCESS(NtStatus) ) {
  8095. //
  8096. // Now check that the change was really made...
  8097. //
  8098. NtStatus = SamQueryInformationUser(
  8099. UserHandle1,
  8100. UserScriptInformation,
  8101. &Buffer2
  8102. );
  8103. ASSERT(NT_SUCCESS( NtStatus ) );
  8104. if (
  8105. !RtlCompareString(
  8106. (PSTRING)&((USER_SCRIPT_INFORMATION *)Buffer1)->ScriptPath,
  8107. (PSTRING)&((USER_SCRIPT_INFORMATION *)Buffer2)->ScriptPath,
  8108. TRUE)
  8109. ) {
  8110. printf("Succeeded\n");
  8111. } else {
  8112. printf("Failed\n");
  8113. printf(" Value queried doesn't match value written\n");
  8114. printf(" Value Written is %wZ\n",
  8115. (PUNICODE_STRING)&((USER_SCRIPT_INFORMATION *)Buffer1)->ScriptPath);
  8116. printf(" Value Retrieved is %wZ\n",
  8117. (PUNICODE_STRING)&((USER_SCRIPT_INFORMATION *)Buffer2)->ScriptPath);
  8118. TestStatus = FALSE;
  8119. }
  8120. SamFreeMemory( Buffer1 );
  8121. SamFreeMemory( Buffer2 );
  8122. } else {
  8123. printf("Failed\n");
  8124. printf(" Completion status is 0x%lx\n", NtStatus);
  8125. TestStatus = FALSE;
  8126. SamFreeMemory( Buffer1 );
  8127. }
  8128. printf(" Set Profile . . . . . . . . . . . . . . . . . . . . . ");
  8129. NtStatus = SamOpenUser(
  8130. DomainHandle,
  8131. USER_WRITE_ACCOUNT | USER_READ_LOGON,
  8132. DOMAIN_USER_RID_ADMIN,
  8133. &UserHandle1
  8134. );
  8135. ASSERT(NT_SUCCESS(NtStatus) );
  8136. //
  8137. // Get the current value...
  8138. //
  8139. Buffer1 = NULL;
  8140. NtStatus = SamQueryInformationUser(
  8141. UserHandle1,
  8142. UserProfileInformation,
  8143. &Buffer1
  8144. );
  8145. TST_SUCCESS_ASSERT(NtStatus);
  8146. ASSERT(Buffer1 != NULL);
  8147. //
  8148. // Change the field to a new value and write it out.
  8149. //
  8150. NameLength = ((USER_PROFILE_INFORMATION *)Buffer1)->ProfilePath.Length;
  8151. if ( NameLength == DummyString1.Length ) {
  8152. ((USER_PROFILE_INFORMATION *)Buffer1)->ProfilePath = DummyString2;
  8153. } else {
  8154. ((USER_PROFILE_INFORMATION *)Buffer1)->ProfilePath = DummyString1;
  8155. }
  8156. NtStatus = SamSetInformationUser(
  8157. UserHandle1,
  8158. UserProfileInformation,
  8159. Buffer1
  8160. );
  8161. if ( NT_SUCCESS(NtStatus) ) {
  8162. //
  8163. // Now check that the change was really made...
  8164. //
  8165. NtStatus = SamQueryInformationUser(
  8166. UserHandle1,
  8167. UserProfileInformation,
  8168. &Buffer2
  8169. );
  8170. ASSERT(NT_SUCCESS( NtStatus ) );
  8171. if (
  8172. !RtlCompareString(
  8173. (PSTRING)&((USER_PROFILE_INFORMATION *)Buffer1)->ProfilePath,
  8174. (PSTRING)&((USER_PROFILE_INFORMATION *)Buffer2)->ProfilePath,
  8175. TRUE)
  8176. ) {
  8177. printf("Succeeded\n");
  8178. } else {
  8179. printf("Failed\n");
  8180. printf(" Value queried doesn't match value written\n");
  8181. printf(" Value Written is %wZ\n",
  8182. (PUNICODE_STRING)&((USER_PROFILE_INFORMATION *)Buffer1)->ProfilePath);
  8183. printf(" Value Retrieved is %wZ\n",
  8184. (PUNICODE_STRING)&((USER_PROFILE_INFORMATION *)Buffer2)->ProfilePath);
  8185. TestStatus = FALSE;
  8186. }
  8187. SamFreeMemory( Buffer1 );
  8188. SamFreeMemory( Buffer2 );
  8189. } else {
  8190. printf("Failed\n");
  8191. printf(" Completion status is 0x%lx\n", NtStatus);
  8192. TestStatus = FALSE;
  8193. SamFreeMemory( Buffer1 );
  8194. }
  8195. printf(" Set Admin Comment . . . . . . . . . . . . . . . . . . ");
  8196. NtStatus = SamOpenUser(
  8197. DomainHandle,
  8198. USER_WRITE_ACCOUNT | USER_READ_GENERAL,
  8199. DOMAIN_USER_RID_ADMIN,
  8200. &UserHandle1
  8201. );
  8202. ASSERT(NT_SUCCESS(NtStatus) );
  8203. //
  8204. // Get the current value...
  8205. //
  8206. Buffer1 = NULL;
  8207. NtStatus = SamQueryInformationUser(
  8208. UserHandle1,
  8209. UserAdminCommentInformation,
  8210. &Buffer1
  8211. );
  8212. TST_SUCCESS_ASSERT(NtStatus);
  8213. ASSERT(Buffer1 != NULL);
  8214. //
  8215. // Change the field to a new value and write it out.
  8216. //
  8217. NameLength = ((USER_ADMIN_COMMENT_INFORMATION *)Buffer1)->AdminComment.Length;
  8218. if ( NameLength == DummyString1.Length ) {
  8219. ((USER_ADMIN_COMMENT_INFORMATION *)Buffer1)->AdminComment = DummyString2;
  8220. } else {
  8221. ((USER_ADMIN_COMMENT_INFORMATION *)Buffer1)->AdminComment = DummyString1;
  8222. }
  8223. NtStatus = SamSetInformationUser(
  8224. UserHandle1,
  8225. UserAdminCommentInformation,
  8226. Buffer1
  8227. );
  8228. if ( NT_SUCCESS(NtStatus) ) {
  8229. //
  8230. // Now check that the change was really made...
  8231. //
  8232. NtStatus = SamQueryInformationUser(
  8233. UserHandle1,
  8234. UserAdminCommentInformation,
  8235. &Buffer2
  8236. );
  8237. ASSERT(NT_SUCCESS( NtStatus ) );
  8238. if (
  8239. !RtlCompareString(
  8240. (PSTRING)&((USER_ADMIN_COMMENT_INFORMATION *)Buffer1)->AdminComment,
  8241. (PSTRING)&((USER_ADMIN_COMMENT_INFORMATION *)Buffer2)->AdminComment,
  8242. TRUE)
  8243. ) {
  8244. printf("Succeeded\n");
  8245. } else {
  8246. printf("Failed\n");
  8247. printf(" Value queried doesn't match value written\n");
  8248. printf(" Value Written is %wZ\n",
  8249. (PUNICODE_STRING)&((USER_ADMIN_COMMENT_INFORMATION *)Buffer1)->AdminComment);
  8250. printf(" Value Retrieved is %wZ\n",
  8251. (PUNICODE_STRING)&((USER_ADMIN_COMMENT_INFORMATION *)Buffer2)->AdminComment);
  8252. TestStatus = FALSE;
  8253. }
  8254. SamFreeMemory( Buffer1 );
  8255. SamFreeMemory( Buffer2 );
  8256. } else {
  8257. printf("Failed\n");
  8258. printf(" Completion status is 0x%lx\n", NtStatus);
  8259. TestStatus = FALSE;
  8260. SamFreeMemory( Buffer1 );
  8261. }
  8262. printf(" Set Workstations . . . . . . . . . . . . . . . . . . ");
  8263. printf("BROKEN TEST - NOT TESTED\n");
  8264. #ifdef BROKEN
  8265. NtStatus = SamOpenUser(
  8266. DomainHandle,
  8267. USER_WRITE_ACCOUNT | USER_READ_LOGON,
  8268. DOMAIN_USER_RID_ADMIN,
  8269. &UserHandle1
  8270. );
  8271. ASSERT(NT_SUCCESS(NtStatus) );
  8272. //
  8273. // Get the current value...
  8274. //
  8275. Buffer1 = NULL;
  8276. NtStatus = SamQueryInformationUser(
  8277. UserHandle1,
  8278. UserWorkStationsInformation,
  8279. &Buffer1
  8280. );
  8281. TST_SUCCESS_ASSERT(NtStatus);
  8282. ASSERT(Buffer1 != NULL);
  8283. //
  8284. // Change the field to a new value and write it out.
  8285. //
  8286. NameLength = ((USER_WORKSTATIONS_INFORMATION *)Buffer1)->WorkStations.Length;
  8287. if ( NameLength == DummyString1.Length ) {
  8288. ((USER_WORKSTATIONS_INFORMATION *)Buffer1)->WorkStations = DummyString2;
  8289. } else {
  8290. ((USER_WORKSTATIONS_INFORMATION *)Buffer1)->WorkStations = DummyString1;
  8291. }
  8292. NtStatus = SamSetInformationUser(
  8293. UserHandle1,
  8294. UserWorkStationsInformation,
  8295. Buffer1
  8296. );
  8297. if ( NT_SUCCESS(NtStatus) ) {
  8298. //
  8299. // Now check that the change was really made...
  8300. //
  8301. NtStatus = SamQueryInformationUser(
  8302. UserHandle1,
  8303. UserWorkStationsInformation,
  8304. &Buffer2
  8305. );
  8306. ASSERT(NT_SUCCESS( NtStatus ) );
  8307. if (
  8308. !RtlCompareString(
  8309. (PSTRING)&((USER_WORKSTATIONS_INFORMATION *)Buffer1)->WorkStations,
  8310. (PSTRING)&((USER_WORKSTATIONS_INFORMATION *)Buffer2)->WorkStations,
  8311. TRUE)
  8312. ) {
  8313. printf("Succeeded\n");
  8314. } else {
  8315. printf("Failed\n");
  8316. printf(" Value queried doesn't match value written\n");
  8317. printf(" Value Written is %wZ\n",
  8318. (PUNICODE_STRING)&((USER_WORKSTATIONS_INFORMATION *)Buffer1)->WorkStations);
  8319. printf(" Value Retrieved is %wZ\n",
  8320. (PUNICODE_STRING)&((USER_WORKSTATIONS_INFORMATION *)Buffer2)->WorkStations);
  8321. TestStatus = FALSE;
  8322. }
  8323. SamFreeMemory( Buffer1 );
  8324. SamFreeMemory( Buffer2 );
  8325. } else {
  8326. printf("Failed\n");
  8327. printf(" Completion status is 0x%lx\n", NtStatus);
  8328. TestStatus = FALSE;
  8329. SamFreeMemory( Buffer1 );
  8330. }
  8331. #endif //BROKEN
  8332. printf(" Set Internal1 . . . . . . . . . . . . . . . . . . . ");
  8333. NtStatus = SamOpenUser(
  8334. DomainHandle,
  8335. USER_WRITE_ACCOUNT | USER_READ_LOGON | USER_FORCE_PASSWORD_CHANGE,
  8336. DOMAIN_USER_RID_ADMIN,
  8337. &UserHandle1
  8338. );
  8339. ASSERT(NT_SUCCESS(NtStatus) );
  8340. //
  8341. // We can't get the current values, since this level is only
  8342. // queryable by trusted clients. So just try setting a couple
  8343. // of values and make sure that we don't get an error.
  8344. //
  8345. Buffer1 = RtlAllocateHeap( RtlProcessHeap(), 0, sizeof(USER_INTERNAL1_INFORMATION) );
  8346. ASSERT( Buffer1 != NULL );
  8347. ((PUSER_INTERNAL1_INFORMATION)Buffer1)->NtPasswordPresent = FALSE;
  8348. ((PUSER_INTERNAL1_INFORMATION)Buffer1)->LmPasswordPresent = FALSE;
  8349. NtStatus = SamSetInformationUser(
  8350. UserHandle1,
  8351. UserInternal1Information,
  8352. Buffer1
  8353. );
  8354. if (NtStatus != STATUS_PASSWORD_RESTRICTION) {
  8355. printf("Failed\n");
  8356. printf(" Expected Status = 0x%lx\n", STATUS_PASSWORD_RESTRICTION);
  8357. printf(" Received Status = 0x%lx\n", NtStatus );
  8358. TestStatus = FALSE;
  8359. } else {
  8360. //
  8361. // The NULL password worked, so let's try a real password.
  8362. //
  8363. NtStatus = RtlCalculateNtOwfPassword(
  8364. &DummyName1,
  8365. &((PUSER_INTERNAL1_INFORMATION)Buffer1)->NtOwfPassword
  8366. );
  8367. ASSERT(NT_SUCCESS(NtStatus));
  8368. ((PUSER_INTERNAL1_INFORMATION)Buffer1)->NtPasswordPresent = TRUE;
  8369. NtStatus = RtlCalculateLmOwfPassword(
  8370. DUMMY_STRING1,
  8371. &((PUSER_INTERNAL1_INFORMATION)Buffer1)->LmOwfPassword
  8372. );
  8373. ASSERT(NT_SUCCESS(NtStatus));
  8374. ((PUSER_INTERNAL1_INFORMATION)Buffer1)->LmPasswordPresent = TRUE;
  8375. NtStatus = SamSetInformationUser(
  8376. UserHandle1,
  8377. UserInternal1Information,
  8378. Buffer1
  8379. );
  8380. if ( NT_SUCCESS(NtStatus) ) {
  8381. printf("Succeeded\n");
  8382. } else {
  8383. printf("Failed\n");
  8384. printf(" Return status was %lx\n", NtStatus );
  8385. TestStatus = FALSE;
  8386. }
  8387. }
  8388. RtlFreeHeap( RtlProcessHeap(), 0, Buffer1 );
  8389. // This is the code that used to be here, when UserInternal1Information was
  8390. // queryable by non-trusted clients...
  8391. //
  8392. // Buffer1 = NULL;
  8393. // NtStatus = SamQueryInformationUser(
  8394. // UserHandle1,
  8395. // UserInternal1Information,
  8396. // &Buffer1
  8397. // );
  8398. // TST_SUCCESS_ASSERT(NtStatus);
  8399. // ASSERT(Buffer1 != NULL);
  8400. //
  8401. // //
  8402. // // The passwords were initially empty. Put in some random
  8403. // // OWF passwords, and have them written out.
  8404. // //
  8405. //
  8406. // NtStatus = RtlCalculateNtOwfPassword(
  8407. // (PNT_PASSWORD)&DummyName1,
  8408. // &EncryptedPasswordBuffer
  8409. // );
  8410. //
  8411. // ((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseSensitiveUnicode.Buffer = (PCHAR)&EncryptedPasswordBuffer;
  8412. // ((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseSensitiveUnicode.Length = 16;
  8413. // ((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseSensitiveUnicode.MaximumLength = 16;
  8414. //
  8415. // NtStatus = RtlCalculateNtOwfPassword(
  8416. // (PNT_PASSWORD)&DummyName2,
  8417. // &EncryptedPasswordBuffer2
  8418. // );
  8419. //
  8420. // ((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseInsensitiveDbcs.Buffer = (PCHAR)&EncryptedPasswordBuffer2;
  8421. // ((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseInsensitiveDbcs.Length = 16;
  8422. // ((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseInsensitiveDbcs.MaximumLength = 16;
  8423. //
  8424. // NtStatus = SamSetInformationUser(
  8425. // UserHandle1,
  8426. // UserInternal1Information,
  8427. // Buffer1
  8428. // );
  8429. // if ( NT_SUCCESS(NtStatus) ) {
  8430. //
  8431. // //
  8432. // // Now check that the change was really made...
  8433. // //
  8434. //
  8435. // NtStatus = SamQueryInformationUser(
  8436. // UserHandle1,
  8437. // UserInternal1Information,
  8438. // &Buffer2
  8439. // );
  8440. // ASSERT(NT_SUCCESS( NtStatus ) );
  8441. //
  8442. // if ( (
  8443. // !RtlCompareString(
  8444. // (PSTRING)&((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseSensitiveUnicode,
  8445. // (PSTRING)&((USER_INTERNAL1_INFORMATION *)Buffer2)->CaseSensitiveUnicode,
  8446. // TRUE)
  8447. // ) || (
  8448. // !RtlCompareString(
  8449. // (PSTRING)&((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseInsensitiveDbcs,
  8450. // (PSTRING)&((USER_INTERNAL1_INFORMATION *)Buffer2)->CaseInsensitiveDbcs,
  8451. // TRUE)
  8452. // ) ) {
  8453. //
  8454. // printf("Succeeded\n");
  8455. //
  8456. // } else {
  8457. //
  8458. // printf("Failed\n");
  8459. // printf(" Value queried doesn't match value written\n");
  8460. // printf(" CaseInsensitiveDbcs Written is %wZ\n",
  8461. // (PUNICODE_STRING)&((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseInsensitiveDbcs);
  8462. // printf(" CaseInsensitiveDbcs Retrieved is %wZ\n",
  8463. // (PUNICODE_STRING)&((USER_INTERNAL1_INFORMATION *)Buffer2)->CaseInsensitiveDbcs);
  8464. // printf(" CaseSensitiveUnicode Written is %wZ\n",
  8465. // (PUNICODE_STRING)&((USER_INTERNAL1_INFORMATION *)Buffer1)->CaseSensitiveUnicode);
  8466. // printf(" CaseSensitiveUnicode Retrieved is %wZ\n",
  8467. // (PUNICODE_STRING)&((USER_INTERNAL1_INFORMATION *)Buffer2)->CaseSensitiveUnicode);
  8468. //
  8469. // TestStatus = FALSE;
  8470. //
  8471. // }
  8472. //
  8473. // SamFreeMemory( Buffer1 );
  8474. // SamFreeMemory( Buffer2 );
  8475. //
  8476. // } else {
  8477. // printf("Failed\n");
  8478. // printf(" Completion status is 0x%lx\n", NtStatus);
  8479. // TestStatus = FALSE;
  8480. // SamFreeMemory( Buffer1 );
  8481. //
  8482. // }
  8483. printf(" Set Internal2 . . . . . . . . . . . . . . . . . . . ");
  8484. NtStatus = SamOpenUser(
  8485. DomainHandle,
  8486. USER_WRITE_ACCOUNT | USER_READ_LOGON,
  8487. DOMAIN_USER_RID_ADMIN,
  8488. &UserHandle1
  8489. );
  8490. ASSERT(NT_SUCCESS(NtStatus) );
  8491. //
  8492. // We can't get the current values, since this level is only
  8493. // queryable by trusted clients. We can't set either, but
  8494. // try it and make sure we get the correct error.
  8495. //
  8496. Buffer1 = RtlAllocateHeap( RtlProcessHeap(), 0, sizeof(USER_INTERNAL2_INFORMATION) );
  8497. ASSERT( Buffer1 != NULL );
  8498. ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogon.HighPart = 1;
  8499. ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogoff.HighPart = 2;
  8500. ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogon.LowPart = 3;
  8501. ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogoff.LowPart = 4;
  8502. ((USER_INTERNAL2_INFORMATION *)Buffer1)->BadPasswordCount = 5;
  8503. ((USER_INTERNAL2_INFORMATION *)Buffer1)->LogonCount = 6;
  8504. NtStatus = SamSetInformationUser(
  8505. UserHandle1,
  8506. UserInternal2Information,
  8507. Buffer1
  8508. );
  8509. RtlFreeHeap( RtlProcessHeap(), 0, Buffer1 );
  8510. if ( NtStatus == STATUS_INVALID_INFO_CLASS ) {
  8511. printf("Succeeded\n");
  8512. } else {
  8513. printf("Failed\n");
  8514. printf(" Expected Status = 0x%lx\n", STATUS_INVALID_INFO_CLASS);
  8515. printf(" Received Status = 0x%lx\n", NtStatus );
  8516. TestStatus = FALSE;
  8517. }
  8518. // This is the code that was here when UserInternal2Information could be
  8519. // queried and set by non-trusted clients...
  8520. //
  8521. // //
  8522. // // Get the current values...
  8523. // //
  8524. //
  8525. // Buffer1 = NULL;
  8526. // NtStatus = SamQueryInformationUser(
  8527. // UserHandle1,
  8528. // UserInternal2Information,
  8529. // &Buffer1
  8530. // );
  8531. // TST_SUCCESS_ASSERT(NtStatus);
  8532. // ASSERT(Buffer1 != NULL);
  8533. //
  8534. // //
  8535. // // Now change the fields and write them out.
  8536. // //
  8537. //
  8538. // ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogon.HighPart += 1;
  8539. // ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogoff.HighPart += 1;
  8540. // ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogon.LowPart += 2;
  8541. // ((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogoff.LowPart += 2;
  8542. // ((USER_INTERNAL2_INFORMATION *)Buffer1)->BadPasswordCount += 1;
  8543. // ((USER_INTERNAL2_INFORMATION *)Buffer1)->LogonCount += 1;
  8544. //
  8545. // NtStatus = SamSetInformationUser(
  8546. // UserHandle1,
  8547. // UserInternal2Information,
  8548. // Buffer1
  8549. // );
  8550. // if ( NT_SUCCESS(NtStatus) ) {
  8551. //
  8552. // //
  8553. // // Now check that the change was really made...
  8554. // //
  8555. //
  8556. // NtStatus = SamQueryInformationUser(
  8557. // UserHandle1,
  8558. // UserInternal2Information,
  8559. // &Buffer2
  8560. // );
  8561. // ASSERT(NT_SUCCESS( NtStatus ) );
  8562. // if (
  8563. // (((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogon.HighPart ==
  8564. // ((USER_INTERNAL2_INFORMATION *)Buffer2)->LastLogon.HighPart) &&
  8565. // (((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogon.LowPart ==
  8566. // ((USER_INTERNAL2_INFORMATION *)Buffer2)->LastLogon.LowPart) &&
  8567. // (((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogoff.HighPart ==
  8568. // ((USER_INTERNAL2_INFORMATION *)Buffer2)->LastLogoff.HighPart) &&
  8569. // (((USER_INTERNAL2_INFORMATION *)Buffer1)->LastLogoff.LowPart ==
  8570. // ((USER_INTERNAL2_INFORMATION *)Buffer2)->LastLogoff.LowPart) &&
  8571. // (((USER_INTERNAL2_INFORMATION *)Buffer1)->BadPasswordCount ==
  8572. // ((USER_INTERNAL2_INFORMATION *)Buffer2)->BadPasswordCount) &&
  8573. // (((USER_INTERNAL2_INFORMATION *)Buffer1)->LogonCount ==
  8574. // ((USER_INTERNAL2_INFORMATION *)Buffer2)->LogonCount)
  8575. // ) {
  8576. //
  8577. // printf("Succeeded\n");
  8578. //
  8579. // } else {
  8580. //
  8581. // printf("Failed\n");
  8582. // printf(" Value queried doesn't match value written\n");
  8583. //
  8584. // TestStatus = FALSE;
  8585. //
  8586. // }
  8587. //
  8588. // SamFreeMemory( Buffer1 );
  8589. // SamFreeMemory( Buffer2 );
  8590. //
  8591. // } else {
  8592. // printf("Failed\n");
  8593. // printf(" Completion status is 0x%lx\n", NtStatus);
  8594. // TestStatus = FALSE;
  8595. // SamFreeMemory( Buffer1 );
  8596. //
  8597. // }
  8598. printf(" Set Password . . . . . . . . . . . . . . . . . . . . ");
  8599. NtStatus = SamOpenUser(
  8600. DomainHandle,
  8601. USER_FORCE_PASSWORD_CHANGE,
  8602. DOMAIN_USER_RID_ADMIN,
  8603. &UserHandle1
  8604. );
  8605. ASSERT(NT_SUCCESS(NtStatus) );
  8606. //
  8607. // Create a fake cleartext UNICODE password and write it out.
  8608. //
  8609. NtStatus = SamSetInformationUser(
  8610. UserHandle1,
  8611. UserSetPasswordInformation,
  8612. &DummyName2
  8613. );
  8614. if ( NT_SUCCESS(NtStatus) ) {
  8615. //
  8616. // We can't verify that it really worked, so we just have
  8617. // to trust the return code.
  8618. //
  8619. printf("Succeeded\n");
  8620. } else {
  8621. printf("Failed\n");
  8622. printf(" Return code was %lx\n", NtStatus );
  8623. TestStatus = FALSE;
  8624. }
  8625. printf(" Set Control . . . . . . . . . . . . . . . . . . . . . ");
  8626. NtStatus = SamOpenUser(
  8627. DomainHandle,
  8628. USER_WRITE_ACCOUNT | USER_READ_ACCOUNT,
  8629. DOMAIN_USER_RID_ADMIN,
  8630. &UserHandle1
  8631. );
  8632. ASSERT(NT_SUCCESS(NtStatus) );
  8633. Buffer1 = NULL;
  8634. NtStatus = SamQueryInformationUser(
  8635. UserHandle1,
  8636. UserControlInformation,
  8637. &Buffer1
  8638. );
  8639. TST_SUCCESS_ASSERT(NtStatus);
  8640. ASSERT(Buffer1 != NULL);
  8641. //
  8642. // Change the value and write it back
  8643. //
  8644. ((USER_CONTROL_INFORMATION *)Buffer1)->UserAccountControl ^= USER_HOME_DIRECTORY_REQUIRED;
  8645. NtStatus = SamSetInformationUser(
  8646. UserHandle1,
  8647. UserControlInformation,
  8648. Buffer1
  8649. );
  8650. if (NT_SUCCESS(NtStatus)) {
  8651. //
  8652. // Check the written value to make sure it stuck
  8653. //
  8654. Buffer2 = NULL;
  8655. NtStatus = SamQueryInformationUser(
  8656. UserHandle1,
  8657. UserControlInformation,
  8658. &Buffer2
  8659. );
  8660. TST_SUCCESS_ASSERT(NtStatus);
  8661. ASSERT(Buffer2 != NULL);
  8662. if ( ((USER_CONTROL_INFORMATION *)Buffer1)->UserAccountControl ==
  8663. ((USER_CONTROL_INFORMATION *)Buffer2)->UserAccountControl ) {
  8664. printf("Succeeded\n");
  8665. SamFreeMemory( Buffer2 );
  8666. //
  8667. // Make sure the account is left enabled to prevent problems.
  8668. //
  8669. ((USER_CONTROL_INFORMATION *)Buffer1)->UserAccountControl &= ~USER_ACCOUNT_DISABLED;
  8670. IgnoreStatus = SamSetInformationUser(
  8671. UserHandle1,
  8672. UserControlInformation,
  8673. Buffer1
  8674. );
  8675. ASSERT(NT_SUCCESS(IgnoreStatus));
  8676. } else {
  8677. printf("Failed\n");
  8678. printf(" Returned Value Doesn't Match Set Value.\n");
  8679. TestStatus = FALSE;
  8680. }
  8681. } else {
  8682. printf("Failed\n");
  8683. printf(" Completion status is 0x%lx\n", NtStatus);
  8684. TestStatus = FALSE;
  8685. }
  8686. SamFreeMemory( Buffer1 );
  8687. IgnoreStatus = SamCloseHandle( UserHandle1 );
  8688. ASSERT( NT_SUCCESS(IgnoreStatus) );
  8689. printf(" Set Expires . . . . . . . . . . . . . . . . . . . . . ");
  8690. printf("BROKEN TEST - NOT TESTED\n");
  8691. #ifdef BROKEN
  8692. NtStatus = SamOpenUser(
  8693. DomainHandle,
  8694. USER_WRITE_ACCOUNT | USER_READ_ACCOUNT,
  8695. DOMAIN_USER_RID_ADMIN,
  8696. &UserHandle1
  8697. );
  8698. ASSERT(NT_SUCCESS(NtStatus) );
  8699. Buffer1 = NULL;
  8700. NtStatus = SamQueryInformationUser(
  8701. UserHandle1,
  8702. UserExpiresInformation,
  8703. &Buffer1
  8704. );
  8705. TST_SUCCESS_ASSERT(NtStatus);
  8706. ASSERT(Buffer1 != NULL);
  8707. //
  8708. // Change the value and write it back
  8709. //
  8710. ((USER_EXPIRES_INFORMATION *)Buffer1)->AccountExpires.LowPart += 1234;
  8711. ((USER_EXPIRES_INFORMATION *)Buffer1)->AccountExpires.HighPart += 1234;
  8712. NtStatus = SamSetInformationUser(
  8713. UserHandle1,
  8714. UserExpiresInformation,
  8715. Buffer1
  8716. );
  8717. if (NT_SUCCESS(NtStatus)) {
  8718. //
  8719. // Check the written value to make sure it stuck
  8720. //
  8721. Buffer2 = NULL;
  8722. NtStatus = SamQueryInformationUser(
  8723. UserHandle1,
  8724. UserExpiresInformation,
  8725. &Buffer2
  8726. );
  8727. TST_SUCCESS_ASSERT(NtStatus);
  8728. ASSERT(Buffer2 != NULL);
  8729. if ( ( ((USER_EXPIRES_INFORMATION *)Buffer1)->AccountExpires.LowPart ==
  8730. ((USER_EXPIRES_INFORMATION *)Buffer2)->AccountExpires.LowPart ) &&
  8731. ( ((USER_EXPIRES_INFORMATION *)Buffer1)->AccountExpires.HighPart ==
  8732. ((USER_EXPIRES_INFORMATION *)Buffer2)->AccountExpires.HighPart ) ) {
  8733. printf("Succeeded\n");
  8734. SamFreeMemory( Buffer2 );
  8735. //
  8736. // Change the values back
  8737. //
  8738. ((USER_EXPIRES_INFORMATION *)Buffer1)->AccountExpires.LowPart += 1234;
  8739. ((USER_EXPIRES_INFORMATION *)Buffer1)->AccountExpires.HighPart += 1234;
  8740. IgnoreStatus = SamSetInformationUser(
  8741. UserHandle1,
  8742. UserExpiresInformation,
  8743. Buffer1
  8744. );
  8745. ASSERT(NT_SUCCESS(IgnoreStatus));
  8746. } else {
  8747. printf("Failed\n");
  8748. printf(" Returned Value Doesn't Match Set Value.\n");
  8749. TestStatus = FALSE;
  8750. }
  8751. } else {
  8752. printf("Failed\n");
  8753. printf(" Completion status is 0x%lx\n", NtStatus);
  8754. TestStatus = FALSE;
  8755. }
  8756. SamFreeMemory( Buffer1 );
  8757. IgnoreStatus = SamCloseHandle( UserHandle1 );
  8758. ASSERT( NT_SUCCESS(IgnoreStatus) );
  8759. #endif //BROKEN
  8760. ///////////////////////////////////////////////////////////////////////////
  8761. // //
  8762. // Change Password For User Suite //
  8763. // //
  8764. ///////////////////////////////////////////////////////////////////////////
  8765. printf("\n");
  8766. printf(" Change Password For User . . . . . . . . . . . . . . Suite\n");
  8767. printf(" Change Password For Well-Known User . . . . . . . . . ");
  8768. NtStatus = SamOpenUser(
  8769. DomainHandle,
  8770. USER_CHANGE_PASSWORD,
  8771. DOMAIN_USER_RID_ADMIN,
  8772. &UserHandle1
  8773. );
  8774. ASSERT(NT_SUCCESS(NtStatus) );
  8775. Buffer = NULL;
  8776. //
  8777. // The current password is DummyName2. Using DummyName2 as the
  8778. // old password, change it to DummyName1 and make sure we get
  8779. // STATUS_SUCCESS.
  8780. //
  8781. NtStatus = SamChangePasswordUser(
  8782. UserHandle1,
  8783. &DummyName2,
  8784. &DummyName1
  8785. );
  8786. //
  8787. // The current password is DummyName1. Using something WRONG for
  8788. // the old password, try to change it to DummyName2 and make sure
  8789. // it doesn't succeed.
  8790. //
  8791. if ( NtStatus == STATUS_SUCCESS ) {
  8792. NtStatus = SamChangePasswordUser(
  8793. UserHandle1,
  8794. &DummyName2,
  8795. &DummyName2
  8796. );
  8797. if ( NtStatus == STATUS_SUCCESS ) {
  8798. NtStatus = STATUS_UNSUCCESSFUL;
  8799. } else {
  8800. NtStatus = STATUS_SUCCESS;
  8801. }
  8802. }
  8803. //
  8804. // The current password is DummyName1. Using DummyName1 as the
  8805. // old password, change it to DummyName2 and make sure it works
  8806. // since by default there is no password history.
  8807. //
  8808. if ( NtStatus == STATUS_SUCCESS ) {
  8809. NtStatus = SamChangePasswordUser(
  8810. UserHandle1,
  8811. &DummyName1,
  8812. &DummyName2
  8813. );
  8814. }
  8815. if ( NT_SUCCESS( NtStatus ) ) {
  8816. printf("Succeeded\n");
  8817. } else {
  8818. printf("Failed\n");
  8819. printf(" Status is %lx\n", NtStatus);
  8820. TestStatus = FALSE;
  8821. }
  8822. IgnoreStatus = SamCloseHandle( UserHandle1 );
  8823. ASSERT( NT_SUCCESS(IgnoreStatus) );
  8824. }
  8825. // END PASS #1
  8826. if (Pass == 2) {
  8827. printf("\n");
  8828. printf("\n");
  8829. printf(" User (Pass #2) . . . . . . . . . . . . . . . . . . . Test\n");
  8830. ///////////////////////////////////////////////////////////////////////////
  8831. // //
  8832. // Delete User Suite //
  8833. // //
  8834. ///////////////////////////////////////////////////////////////////////////
  8835. printf("\n");
  8836. printf(" Delete User . . . . . . . . . . . . . . . . . . . . Suite\n");
  8837. printf(" Delete Normal User . . . . . . . . . . . . . . . . . ");
  8838. //
  8839. // This User was created in pass #1
  8840. //
  8841. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  8842. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  8843. TST_SUCCESS_ASSERT(NtStatus);
  8844. NtStatus = SamLookupNamesInDomain(
  8845. DomainHandle,
  8846. 1,
  8847. &AccountNames[0],
  8848. &LookedUpRids,
  8849. &LookedUpUses
  8850. );
  8851. TST_SUCCESS_ASSERT(NtStatus);
  8852. ASSERT(LookedUpUses[0] == SidTypeUser);
  8853. RtlFreeUnicodeString( &AccountNames[0] );
  8854. UserHandle1 = NULL;
  8855. NtStatus = SamOpenUser( DomainHandle, DELETE, LookedUpRids[0], &UserHandle1 );
  8856. TST_SUCCESS_ASSERT(NtStatus);
  8857. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  8858. NtStatus = SamDeleteUser( UserHandle1 );
  8859. if (NT_SUCCESS(NtStatus)) {
  8860. printf("Succeeded\n");
  8861. } else {
  8862. printf("Failed\n");
  8863. printf(" Completion status is 0x%lx\n", NtStatus);
  8864. TestStatus = FALSE;
  8865. }
  8866. printf(" Delete Admin Group Member . . . . . . . . . . . . . . ");
  8867. printf("(Unimplemented)\n");
  8868. printf(" Delete Last Admin Group Member . . . . . . . . . . . ");
  8869. printf("(Unimplemented)\n");
  8870. ///////////////////////////////////////////////////////////////////////////
  8871. // //
  8872. // Set User Suite //
  8873. // //
  8874. ///////////////////////////////////////////////////////////////////////////
  8875. printf("\n");
  8876. printf(" Set User (Pass 2) . . . . . . . . . . . . . . . . . . Suite\n");
  8877. printf(" Set ALL information. . . . . . . . . . . . ");
  8878. printf("BROKEN TEST - NOT TESTED\n");
  8879. #ifdef BROKEN
  8880. RtlInitString( &AccountNameAnsi, "AllUser" );
  8881. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  8882. TST_SUCCESS_ASSERT(NtStatus);
  8883. UserRid = 0;
  8884. UserHandle1 = NULL;
  8885. NtStatus = SamCreateUserInDomain(
  8886. DomainHandle,
  8887. &AccountName,
  8888. USER_ALL_ACCESS,
  8889. &UserHandle1,
  8890. &UserRid
  8891. );
  8892. RtlFreeUnicodeString( &AccountName );
  8893. ASSERT(NT_SUCCESS(NtStatus));
  8894. All = NULL;
  8895. NtStatus = SamQueryInformationUser(
  8896. UserHandle1,
  8897. UserAllInformation,
  8898. &All
  8899. );
  8900. if ( NT_SUCCESS( NtStatus ) ) {
  8901. //
  8902. // Now change some of the data, and set it
  8903. //
  8904. RtlInitString( &TmpAnsiString, "FullName" );
  8905. TmpStatus = RtlAnsiStringToUnicodeString(
  8906. (PUNICODE_STRING)(&All->FullName),
  8907. &TmpAnsiString,
  8908. TRUE );
  8909. ASSERT( NT_SUCCESS( TmpStatus ) );
  8910. RtlInitString( &TmpAnsiString, "HomeDirectory" );
  8911. TmpStatus = RtlAnsiStringToUnicodeString(
  8912. (PUNICODE_STRING)(&All->HomeDirectory),
  8913. &TmpAnsiString,
  8914. TRUE );
  8915. ASSERT( NT_SUCCESS( TmpStatus ) );
  8916. RtlInitString( &TmpAnsiString, "HomeDirectoryDrive" );
  8917. TmpStatus = RtlAnsiStringToUnicodeString(
  8918. (PUNICODE_STRING)(&All->HomeDirectoryDrive),
  8919. &TmpAnsiString,
  8920. TRUE );
  8921. ASSERT( NT_SUCCESS( TmpStatus ) );
  8922. RtlInitString( &TmpAnsiString, "ScriptPath" );
  8923. TmpStatus = RtlAnsiStringToUnicodeString(
  8924. (PUNICODE_STRING)(&All->ScriptPath),
  8925. &TmpAnsiString,
  8926. TRUE );
  8927. ASSERT( NT_SUCCESS( TmpStatus ) );
  8928. RtlInitString( &TmpAnsiString, "ProfilePath" );
  8929. TmpStatus = RtlAnsiStringToUnicodeString(
  8930. (PUNICODE_STRING)(&All->ProfilePath),
  8931. &TmpAnsiString,
  8932. TRUE );
  8933. ASSERT( NT_SUCCESS( TmpStatus ) );
  8934. RtlInitString( &TmpAnsiString, "AdminComment" );
  8935. TmpStatus = RtlAnsiStringToUnicodeString(
  8936. (PUNICODE_STRING)(&All->AdminComment),
  8937. &TmpAnsiString,
  8938. TRUE );
  8939. ASSERT( NT_SUCCESS( TmpStatus ) );
  8940. RtlInitString( &TmpAnsiString, "WorkStations" );
  8941. TmpStatus = RtlAnsiStringToUnicodeString(
  8942. (PUNICODE_STRING)(&All->WorkStations),
  8943. &TmpAnsiString,
  8944. TRUE );
  8945. ASSERT( NT_SUCCESS( TmpStatus ) );
  8946. RtlInitString( &TmpAnsiString, "UserComment" );
  8947. TmpStatus = RtlAnsiStringToUnicodeString(
  8948. (PUNICODE_STRING)(&All->UserComment),
  8949. &TmpAnsiString,
  8950. TRUE );
  8951. ASSERT( NT_SUCCESS( TmpStatus ) );
  8952. RtlInitString( &TmpAnsiString, "Parameters" );
  8953. TmpStatus = RtlAnsiStringToUnicodeString(
  8954. (PUNICODE_STRING)(&All->Parameters),
  8955. &TmpAnsiString,
  8956. TRUE );
  8957. ASSERT( NT_SUCCESS( TmpStatus ) );
  8958. All->CountryCode = 7;
  8959. All->CodePage = 8;
  8960. All->PasswordExpired = TRUE;
  8961. All->NtPasswordPresent = TRUE;
  8962. All->LmPasswordPresent = FALSE;
  8963. RtlInitString( &TmpAnsiString, "NtPassword" );
  8964. TmpStatus = RtlAnsiStringToUnicodeString(
  8965. (PUNICODE_STRING)(&All->NtPassword),
  8966. &TmpAnsiString,
  8967. TRUE );
  8968. ASSERT( NT_SUCCESS( TmpStatus ) );
  8969. All->LogonHours.UnitsPerWeek = 7;
  8970. All->WhichFields = ( USER_ALL_FULLNAME |
  8971. USER_ALL_HOMEDIRECTORY |
  8972. USER_ALL_HOMEDIRECTORYDRIVE |
  8973. USER_ALL_SCRIPTPATH |
  8974. USER_ALL_PROFILEPATH |
  8975. USER_ALL_ADMINCOMMENT |
  8976. USER_ALL_WORKSTATIONS |
  8977. USER_ALL_USERCOMMENT |
  8978. USER_ALL_PARAMETERS |
  8979. USER_ALL_COUNTRYCODE |
  8980. USER_ALL_CODEPAGE |
  8981. USER_ALL_PASSWORDEXPIRED |
  8982. USER_ALL_NTPASSWORDPRESENT |
  8983. USER_ALL_LOGONHOURS );
  8984. NtStatus = SamSetInformationUser(
  8985. UserHandle1,
  8986. UserAllInformation,
  8987. All
  8988. );
  8989. if ( NT_SUCCESS( NtStatus ) ) {
  8990. NtStatus = SamQueryInformationUser(
  8991. UserHandle1,
  8992. UserAllInformation,
  8993. &All2
  8994. );
  8995. if ( NT_SUCCESS( NtStatus ) ) {
  8996. //
  8997. // Verify that queried info is as we set it
  8998. //
  8999. if (
  9000. //
  9001. // Fields that we didn't touch. Note that
  9002. // PasswordMustChange changed anyway, since we
  9003. // changed from a null to a non-null password.
  9004. //
  9005. ( All2->WhichFields != (USER_ALL_READ_GENERAL_MASK |
  9006. USER_ALL_READ_PREFERENCES_MASK |
  9007. USER_ALL_READ_ACCOUNT_MASK |
  9008. USER_ALL_READ_LOGON_MASK) ) ||
  9009. ( !(All->LastLogon.QuadPart ==
  9010. All2->LastLogon.QuadPart ) ) ||
  9011. ( !(All->LastLogoff.QuadPart ==
  9012. All2->LastLogoff.QuadPart ) ) ||
  9013. ( !(All->PasswordLastSet.QuadPart ==
  9014. All2->PasswordLastSet.QuadPart ) ) ||
  9015. ( !(All->AccountExpires.QuadPart ==
  9016. All2->AccountExpires.QuadPart ) ) ||
  9017. ( !(All->PasswordCanChange.QuadPart ==
  9018. All2->PasswordCanChange.QuadPart ) ) ||
  9019. ( (All->PasswordMustChange.QuadPart ==
  9020. All2->PasswordMustChange.QuadPart ) ) ||
  9021. (RtlCompareUnicodeString(
  9022. &(All->UserName),
  9023. &(All2->UserName),
  9024. FALSE) != 0) ||
  9025. ( All->UserId != All2->UserId ) ||
  9026. ( All->PrimaryGroupId != All2->PrimaryGroupId ) ||
  9027. ( All->UserAccountControl != All2->UserAccountControl ) ||
  9028. ( All->PrivateDataSensitive !=
  9029. All2->PrivateDataSensitive ) ||
  9030. // Fields that we changed. Note that we set
  9031. // NtPasswordSet, but it shouldn't be set on return.
  9032. (RtlCompareUnicodeString(
  9033. &(All->FullName),
  9034. &(All2->FullName),
  9035. FALSE) != 0) ||
  9036. (RtlCompareUnicodeString(
  9037. &(All->HomeDirectory),
  9038. &(All2->HomeDirectory),
  9039. FALSE) != 0) ||
  9040. (RtlCompareUnicodeString(
  9041. &(All->HomeDirectoryDrive),
  9042. &(All2->HomeDirectoryDrive),
  9043. FALSE) != 0) ||
  9044. (RtlCompareUnicodeString(
  9045. &(All->ScriptPath),
  9046. &(All2->ScriptPath),
  9047. FALSE) != 0) ||
  9048. (RtlCompareUnicodeString(
  9049. &(All->ProfilePath),
  9050. &(All2->ProfilePath),
  9051. FALSE) != 0) ||
  9052. (RtlCompareUnicodeString(
  9053. &(All->AdminComment),
  9054. &(All2->AdminComment),
  9055. FALSE) != 0) ||
  9056. (RtlCompareUnicodeString(
  9057. &(All->WorkStations),
  9058. &(All2->WorkStations),
  9059. FALSE) != 0) ||
  9060. (RtlCompareUnicodeString(
  9061. &(All->UserComment),
  9062. &(All2->UserComment),
  9063. FALSE) != 0) ||
  9064. (RtlCompareUnicodeString(
  9065. &(All->Parameters),
  9066. &(All2->Parameters),
  9067. FALSE) != 0) ||
  9068. ( All->CountryCode != All2->CountryCode ) ||
  9069. ( All->CodePage != All2->CodePage ) ||
  9070. ( All->LmPasswordPresent != All2->LmPasswordPresent ) ||
  9071. ( All->NtPasswordPresent == All2->NtPasswordPresent ) ||
  9072. ( All->LogonHours.UnitsPerWeek !=
  9073. All2->LogonHours.UnitsPerWeek )
  9074. ) {
  9075. NtStatus = STATUS_DATA_ERROR;
  9076. }
  9077. SamFreeMemory( All2 );
  9078. }
  9079. }
  9080. SamFreeMemory( All );
  9081. }
  9082. if (NtStatus == STATUS_SUCCESS) {
  9083. printf("Succeeded\n");
  9084. } else {
  9085. printf("Failed\n");
  9086. printf(" Completion status is 0x%lx\n", NtStatus);
  9087. TestStatus = FALSE;
  9088. }
  9089. //
  9090. // Now get rid of the user account if necessary
  9091. //
  9092. NtStatus = SamDeleteUser( UserHandle1 );
  9093. ASSERT(NT_SUCCESS(NtStatus));
  9094. #endif //BROKEN
  9095. printf(" Set Primary Group (non member). . . . . . . . . . . . ");
  9096. //
  9097. // The following user might already exist (from earlier in the test)
  9098. //
  9099. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  9100. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  9101. TST_SUCCESS_ASSERT(NtStatus);
  9102. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  9103. UserRid = 0;
  9104. UserHandle1 = NULL;
  9105. NtStatus = SamCreateUserInDomain(
  9106. DomainHandle,
  9107. &AccountName,
  9108. USER_ALL_ACCESS,
  9109. &UserHandle1,
  9110. &UserRid
  9111. );
  9112. RtlFreeUnicodeString( &AccountName );
  9113. DeleteUser = TRUE;
  9114. if (NtStatus == STATUS_USER_EXISTS) {
  9115. DeleteUser = FALSE;
  9116. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  9117. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  9118. TST_SUCCESS_ASSERT(NtStatus);
  9119. NtStatus = SamLookupNamesInDomain(
  9120. DomainHandle,
  9121. 1,
  9122. &AccountNames[0],
  9123. &LookedUpRids,
  9124. &LookedUpUses
  9125. );
  9126. TST_SUCCESS_ASSERT(NtStatus);
  9127. ASSERT(LookedUpUses[0] == SidTypeUser);
  9128. RtlFreeUnicodeString( &AccountNames[0] );
  9129. NtStatus = SamOpenUser(
  9130. DomainHandle,
  9131. USER_ALL_ACCESS,
  9132. LookedUpRids[0],
  9133. &UserHandle1);
  9134. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  9135. }
  9136. ASSERT(NT_SUCCESS(NtStatus));
  9137. //
  9138. // The user is not a member of DOMAIN_GROUP_RID_ADMINS.
  9139. // See if we can make this group the user's primary group
  9140. //
  9141. ASSERT(sizeof(GroupRid) == sizeof(USER_PRIMARY_GROUP_INFORMATION));
  9142. GroupRid = DOMAIN_GROUP_RID_ADMINS;
  9143. NtStatus = SamSetInformationUser(
  9144. UserHandle1,
  9145. UserPrimaryGroupInformation,
  9146. &GroupRid
  9147. );
  9148. if (NtStatus == STATUS_MEMBER_NOT_IN_GROUP) {
  9149. printf("Succeeded\n");
  9150. } else {
  9151. printf("Failed\n");
  9152. printf(" Completion status is 0x%lx\n", NtStatus);
  9153. TestStatus = FALSE;
  9154. }
  9155. //
  9156. // Now get rid of the user account if necessary
  9157. //
  9158. if (DeleteUser == TRUE) {
  9159. NtStatus = SamDeleteUser( UserHandle1 );
  9160. ASSERT(NT_SUCCESS(NtStatus));
  9161. } else {
  9162. NtStatus = SamCloseHandle( UserHandle1 );
  9163. ASSERT(NT_SUCCESS(NtStatus));
  9164. }
  9165. printf(" Set Primary Group (member). . . . . . . . . . . . . . ");
  9166. //
  9167. // Make a user (might already exist)
  9168. // Make a group
  9169. // Make the group the user's primary group
  9170. // Change the user so the group isn't the primary group
  9171. // remove the group
  9172. // delete the group
  9173. // If we created the user, delete it.
  9174. //
  9175. // The following user might already exist (from earlier in the test)
  9176. //
  9177. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  9178. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  9179. TST_SUCCESS_ASSERT(NtStatus);
  9180. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  9181. UserRid = 0;
  9182. UserHandle1 = NULL;
  9183. NtStatus = SamCreateUserInDomain(
  9184. DomainHandle,
  9185. &AccountName,
  9186. USER_ALL_ACCESS,
  9187. &UserHandle1,
  9188. &UserRid
  9189. );
  9190. RtlFreeUnicodeString( &AccountName );
  9191. DeleteUser = TRUE;
  9192. if (NtStatus == STATUS_USER_EXISTS) {
  9193. DeleteUser = FALSE;
  9194. RtlInitString( &AccountNameAnsi, USER_NAME1 );
  9195. NtStatus = RtlAnsiStringToUnicodeString( &AccountNames[0], &AccountNameAnsi, TRUE );
  9196. TST_SUCCESS_ASSERT(NtStatus);
  9197. NtStatus = SamLookupNamesInDomain(
  9198. DomainHandle,
  9199. 1,
  9200. &AccountNames[0],
  9201. &LookedUpRids,
  9202. &LookedUpUses
  9203. );
  9204. RtlFreeUnicodeString( &AccountNames[0] );
  9205. TST_SUCCESS_ASSERT(NtStatus);
  9206. ASSERT(LookedUpUses[0] == SidTypeUser);
  9207. UserRid = LookedUpRids[0];
  9208. NtStatus = SamOpenUser(
  9209. DomainHandle,
  9210. USER_ALL_ACCESS,
  9211. UserRid,
  9212. &UserHandle1);
  9213. SamFreeMemory( LookedUpUses ); SamFreeMemory( LookedUpRids );
  9214. }
  9215. ASSERT(NT_SUCCESS(NtStatus));
  9216. //
  9217. // create the group
  9218. //
  9219. RtlInitString( &AccountNameAnsi, GROUP_NAME1 );
  9220. NtStatus = RtlAnsiStringToUnicodeString( &AccountName, &AccountNameAnsi, TRUE );
  9221. TST_SUCCESS_ASSERT(NtStatus);
  9222. //InitializeObjectAttributes( &ObjectAttributes, &AccountName, 0, 0, NULL );
  9223. GroupRid = 0;
  9224. GroupHandle1 = NULL;
  9225. NtStatus = SamCreateGroupInDomain(
  9226. DomainHandle,
  9227. &AccountName,
  9228. GROUP_ALL_ACCESS,
  9229. &GroupHandle1,
  9230. &GroupRid
  9231. );
  9232. RtlFreeUnicodeString( &AccountName );
  9233. ASSERT(NT_SUCCESS(NtStatus));
  9234. //
  9235. // Make the user a member of this group
  9236. //
  9237. NtStatus = SamAddMemberToGroup(
  9238. GroupHandle1,
  9239. UserRid,
  9240. SE_GROUP_MANDATORY |
  9241. SE_GROUP_ENABLED_BY_DEFAULT |
  9242. SE_GROUP_ENABLED
  9243. );
  9244. ASSERT(NT_SUCCESS(NtStatus));
  9245. //
  9246. // Set the user's primary group Id to be this group
  9247. //
  9248. NtStatus = SamSetInformationUser(
  9249. UserHandle1,
  9250. UserPrimaryGroupInformation,
  9251. &GroupRid
  9252. );
  9253. if (NT_SUCCESS(NtStatus)) {
  9254. Buffer1 = NULL;
  9255. NtStatus = SamQueryInformationUser(
  9256. UserHandle1,
  9257. UserPrimaryGroupInformation,
  9258. &Buffer1
  9259. );
  9260. TST_SUCCESS_ASSERT(NtStatus);
  9261. ASSERT(Buffer1 != NULL);
  9262. if ( ((USER_PRIMARY_GROUP_INFORMATION *)Buffer1)->PrimaryGroupId ==
  9263. GroupRid ) {
  9264. printf("Succeeded\n");
  9265. SamFreeMemory( Buffer1 );
  9266. } else {
  9267. printf("Failed\n");
  9268. printf(" Returned Value Doesn't Match Set Value.\n");
  9269. printf(" Value written is: 0x%lx\n", GroupRid);
  9270. printf(" Value retrieved is: 0x%lx\n",
  9271. ((USER_PRIMARY_GROUP_INFORMATION *)Buffer1)->PrimaryGroupId);
  9272. TestStatus = FALSE;
  9273. }
  9274. } else {
  9275. printf("Failed\n");
  9276. printf(" Completion status is 0x%lx\n", NtStatus);
  9277. TestStatus = FALSE;
  9278. }
  9279. //
  9280. // Set the user's primary group Id back and remove the user
  9281. // from the group
  9282. //
  9283. GroupRid = DOMAIN_GROUP_RID_USERS;
  9284. NtStatus = SamSetInformationUser(
  9285. UserHandle1,
  9286. UserPrimaryGroupInformation,
  9287. &GroupRid
  9288. );
  9289. ASSERT(NT_SUCCESS(NtStatus));
  9290. NtStatus = SamRemoveMemberFromGroup(GroupHandle1, UserRid);
  9291. ASSERT(NT_SUCCESS(NtStatus));
  9292. //
  9293. // Now get rid of the group and possibly the user account
  9294. //
  9295. NtStatus = SamDeleteGroup( GroupHandle1 );
  9296. ASSERT(NT_SUCCESS(NtStatus));
  9297. if (DeleteUser == TRUE) {
  9298. NtStatus = SamDeleteUser( UserHandle1 );
  9299. ASSERT(NT_SUCCESS(NtStatus));
  9300. } else {
  9301. NtStatus = SamCloseHandle( UserHandle1 );
  9302. ASSERT(NT_SUCCESS(NtStatus));
  9303. }
  9304. printf(" Set Name Information . . . . . . . . . . . . . . . . ");
  9305. printf("(Untested)\n");
  9306. }
  9307. return(TestStatus);
  9308. }
  9309. #endif // NOT_PART_OF_PROGRAM