Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cttoken.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 cttoken.c 00008 00009 Abstract: 00010 00011 Common token object test routines. 00012 00013 These routines are used in both kernel and user mode tests. 00014 00015 This test assumes the security runtime library routines are 00016 functioning correctly. 00017 00018 NOTE: This test program allocates a lot of memory and frees 00019 none of it ! ! ! 00020 00021 00022 00023 Author: 00024 00025 Jim Kelly (JimK) 27-June-1990 00026 00027 Environment: 00028 00029 Test of token object. 00030 00031 Revision History: 00032 00033 --*/ 00034 00035 #include "tsecomm.c" // Mode dependent macros and routines. 00036 00037 00038 00040 // // 00041 // Module wide variables // 00042 // // 00044 00045 #define DEFAULT_DACL_LENGTH (1024L) 00046 #define GROUP_IDS_LENGTH (1024L) 00047 #define NEW_GROUP_STATE_LENGTH (1024L) 00048 #define PRIVILEGES_LENGTH (128L) 00049 #define TOO_BIG_ACL_SIZE (2048L) 00050 #define TOO_BIG_PRIMARY_GROUP_SIZE (39L) 00051 00052 // 00053 // definitions related to TokenWithGroups 00054 // (we also substitute SYSTEM for NEANDERTHOL in some tests) 00055 // 00056 00057 #define FLINTSTONE_INDEX (0L) 00058 #define CHILD_INDEX (1L) 00059 #define NEANDERTHOL_INDEX (2L) 00060 #define SYSTEM_INDEX (2L) 00061 #define WORLD_INDEX (3L) 00062 #define GROUP_COUNT (4L) 00063 #define RESTRICTED_SID_COUNT (2L) 00064 00065 00066 // 00067 // Definitions related to TokenWithPrivileges 00068 // 00069 00070 #define UNSOLICITED_INDEX (0L) 00071 #define SECURITY_INDEX (1L) 00072 #define ASSIGN_PRIMARY_INDEX (2L) 00073 #define PRIVILEGE_COUNT (3L) 00074 00075 00076 NTSTATUS Status; 00077 00078 HANDLE SimpleToken; 00079 HANDLE TokenWithGroups; 00080 HANDLE TokenWithDefaultOwner; 00081 HANDLE TokenWithPrivileges; 00082 HANDLE TokenWithDefaultDacl; 00083 00084 HANDLE TokenWithRestrictedGroups; 00085 HANDLE TokenWithRestrictedPrivileges; 00086 HANDLE TokenWithRestrictedSids; 00087 HANDLE TokenWithMoreRestrictedSids; 00088 00089 00090 HANDLE Token; 00091 HANDLE ProcessToken; 00092 HANDLE ImpersonationToken; 00093 HANDLE AnonymousToken; 00094 00095 OBJECT_ATTRIBUTES PrimaryTokenAttributes; 00096 PSECURITY_DESCRIPTOR PrimarySecurityDescriptor; 00097 SECURITY_QUALITY_OF_SERVICE PrimarySecurityQos; 00098 00099 OBJECT_ATTRIBUTES ImpersonationTokenAttributes; 00100 PSECURITY_DESCRIPTOR ImpersonationSecurityDescriptor; 00101 SECURITY_QUALITY_OF_SERVICE ImpersonationSecurityQos; 00102 00103 OBJECT_ATTRIBUTES AnonymousTokenAttributes; 00104 PSECURITY_DESCRIPTOR AnonymousSecurityDescriptor; 00105 SECURITY_QUALITY_OF_SERVICE AnonymousSecurityQos; 00106 00107 ULONG DisabledGroupAttributes; 00108 ULONG OptionalGroupAttributes; 00109 ULONG NormalGroupAttributes; 00110 ULONG OwnerGroupAttributes; 00111 00112 ULONG LengthAvailable; 00113 ULONG CurrentLength; 00114 00115 00116 TIME_FIELDS TempTimeFields = {3000, 1, 1, 1, 1, 1, 1, 1}; 00117 LARGE_INTEGER NoExpiration; 00118 00119 LUID BadAuthenticationId; 00120 LUID SystemAuthenticationId = SYSTEM_LUID; 00121 LUID OriginalAuthenticationId; 00122 00123 TOKEN_SOURCE TestSource = {"SE: TEST", 0}; 00124 00125 PSID Owner; 00126 PSID Group; 00127 PACL Dacl; 00128 00129 PSID TempOwner; 00130 PSID TempGroup; 00131 PACL TempDacl; 00132 00133 UQUAD ThreadStack[256]; 00134 INITIAL_TEB InitialTeb; 00135 NTSTATUS Status; 00136 CLIENT_ID ThreadClientId; 00137 CONTEXT ThreadContext; 00138 HANDLE ThreadHandle; 00139 OBJECT_ATTRIBUTES ThreadObja; 00140 00141 00142 00143 00144 00145 00147 // // 00148 // Private Macros // 00149 // // 00151 00152 00153 #define TestpPrintLuid(G) \ 00154 DbgPrint( "(0x%x, 0x%x)", \ 00155 (G).HighPart, (G).LowPart); \ 00156 00157 00158 00159 00161 // // 00162 // Initialization Routine // 00163 // // 00165 00166 BOOLEAN 00167 TestTokenInitialize() 00168 { 00169 00170 NTSTATUS Status; 00171 ULONG ReturnLength; 00172 HANDLE ProcessToken; 00173 TOKEN_STATISTICS ProcessTokenStatistics; 00174 PTOKEN_PRIVILEGES NewState; 00175 00176 00177 if (!TSeVariableInitialization()) { 00178 DbgPrint("Se: Failed to initialize global test variables.\n"); 00179 return FALSE; 00180 } 00181 00182 00183 DisabledGroupAttributes = (SE_GROUP_ENABLED_BY_DEFAULT); 00184 00185 OptionalGroupAttributes = (SE_GROUP_ENABLED_BY_DEFAULT | 00186 SE_GROUP_ENABLED 00187 ); 00188 NormalGroupAttributes = (SE_GROUP_MANDATORY | 00189 SE_GROUP_ENABLED_BY_DEFAULT | 00190 SE_GROUP_ENABLED 00191 ); 00192 OwnerGroupAttributes = (SE_GROUP_MANDATORY | 00193 SE_GROUP_ENABLED_BY_DEFAULT | 00194 SE_GROUP_ENABLED | 00195 SE_GROUP_OWNER 00196 ); 00197 00198 00199 PrimarySecurityDescriptor = 00200 (PSECURITY_DESCRIPTOR)TstAllocatePool( PagedPool, 1024 ); 00201 00202 Status = RtlCreateSecurityDescriptor ( 00203 PrimarySecurityDescriptor, 00204 SECURITY_DESCRIPTOR_REVISION1 00205 ); ASSERT(NT_SUCCESS(Status)); 00206 Status = RtlSetDaclSecurityDescriptor ( 00207 PrimarySecurityDescriptor, 00208 TRUE, //DaclPresent, 00209 NULL, //Dacl OPTIONAL, // No protection 00210 FALSE //DaclDefaulted OPTIONAL 00211 ); ASSERT(NT_SUCCESS(Status)); 00212 00213 00214 InitializeObjectAttributes( 00215 &PrimaryTokenAttributes, 00216 NULL, 00217 OBJ_INHERIT, 00218 NULL, 00219 PrimarySecurityDescriptor 00220 ); 00221 00222 00223 ImpersonationSecurityDescriptor = 00224 (PSECURITY_DESCRIPTOR)TstAllocatePool( PagedPool, 1024 ); 00225 00226 ImpersonationSecurityQos.Length = (ULONG)sizeof(SECURITY_QUALITY_OF_SERVICE); 00227 ImpersonationSecurityQos.ImpersonationLevel = SecurityImpersonation; 00228 ImpersonationSecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 00229 ImpersonationSecurityQos.EffectiveOnly = FALSE; 00230 00231 InitializeObjectAttributes( 00232 &ImpersonationTokenAttributes, 00233 NULL, 00234 OBJ_INHERIT, 00235 NULL, 00236 NULL 00237 ); 00238 ImpersonationTokenAttributes.SecurityQualityOfService = 00239 &ImpersonationSecurityQos; 00240 00241 00242 AnonymousSecurityDescriptor = 00243 (PSECURITY_DESCRIPTOR)TstAllocatePool( PagedPool, 1024 ); 00244 00245 AnonymousSecurityQos.Length = (ULONG)sizeof(SECURITY_QUALITY_OF_SERVICE); 00246 AnonymousSecurityQos.ImpersonationLevel = SecurityAnonymous; 00247 AnonymousSecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 00248 AnonymousSecurityQos.EffectiveOnly = FALSE; 00249 00250 InitializeObjectAttributes( 00251 &AnonymousTokenAttributes, 00252 NULL, 00253 OBJ_INHERIT, 00254 NULL, 00255 NULL 00256 ); 00257 AnonymousTokenAttributes.SecurityQualityOfService = 00258 &AnonymousSecurityQos; 00259 00260 00261 // 00262 // Build an ACL for use. 00263 // 00264 00265 Dacl = (PACL)TstAllocatePool( PagedPool, 256 ); 00266 00267 Dacl->AclRevision=ACL_REVISION; 00268 Dacl->Sbz1=0; 00269 Dacl->Sbz2=0; 00270 Dacl->AclSize=256; 00271 Dacl->AceCount=0; 00272 00273 00274 // 00275 // Set up expiration times 00276 // 00277 00278 TempTimeFields.Year = 3000; 00279 TempTimeFields.Month = 1; 00280 TempTimeFields.Day = 1; 00281 TempTimeFields.Hour = 1; 00282 TempTimeFields.Minute = 1; 00283 TempTimeFields.Second = 1; 00284 TempTimeFields.Milliseconds = 1; 00285 TempTimeFields.Weekday = 1; 00286 00287 RtlTimeFieldsToTime( &TempTimeFields, &NoExpiration ); 00288 00289 // 00290 // Set up a bad authentication ID 00291 // 00292 00293 BadAuthenticationId = RtlConvertLongToLuid(1); 00294 00295 00296 // 00297 // Use a token source specific to security test 00298 // 00299 00300 NtAllocateLocallyUniqueId( &(TestSource.SourceIdentifier) ); 00301 00302 // 00303 // Create a new thread for impersonation tests 00304 // 00305 00306 00307 // 00308 // Initialize object attributes. 00309 // Note that the name of the thread is NULL so that we 00310 // can run multiple copies of the test at the same time 00311 // without collisions. 00312 // 00313 00314 InitializeObjectAttributes(&ThreadObja, NULL, 0, NULL, NULL); 00315 00316 // 00317 // Initialize thread context and initial TEB. 00318 // 00319 00320 RtlInitializeContext(NtCurrentProcess(), 00321 &ThreadContext, 00322 NULL, 00323 (PVOID)TestTokenInitialize, 00324 &ThreadStack[254]); 00325 00326 InitialTeb.StackBase = &ThreadStack[254]; 00327 InitialTeb.StackLimit = &ThreadStack[0]; 00328 00329 // 00330 // Create a thread in a suspended state. 00331 // 00332 00333 Status = NtCreateThread(&ThreadHandle, 00334 THREAD_ALL_ACCESS, 00335 &ThreadObja, 00336 NtCurrentProcess(), 00337 &ThreadClientId, 00338 &ThreadContext, 00339 &InitialTeb, 00340 TRUE); 00341 00342 ASSERT(NT_SUCCESS(Status)); 00343 00344 00345 00346 // 00347 // The following is sortof a horse-before-the-cart type of initialization. 00348 // Now that the system is enforcing things like "you can only create a 00349 // token with an AuthenticationId that the reference monitor has been told 00350 // about, it is necessary to obtain some information out of our current 00351 // token. 00352 // 00353 00354 Status = NtOpenProcessToken( 00355 NtCurrentProcess(), 00356 TOKEN_ALL_ACCESS, 00357 &ProcessToken 00358 ); 00359 ASSERT( NT_SUCCESS(Status) ); 00360 Status = NtQueryInformationToken( 00361 ProcessToken, // Handle 00362 TokenStatistics, // TokenInformationClass 00363 &ProcessTokenStatistics, // TokenInformation 00364 sizeof(TOKEN_STATISTICS), // TokenInformationLength 00365 &ReturnLength // ReturnLength 00366 ); 00367 ASSERT(NT_SUCCESS(Status)); 00368 OriginalAuthenticationId = ProcessTokenStatistics.AuthenticationId; 00369 00370 00371 DbgPrint("Se: enabling AssignPrimary & TCB privileges...\n"); 00372 00373 NewState = (PTOKEN_PRIVILEGES) TstAllocatePool( 00374 PagedPool, 00375 200 00376 ); 00377 00378 NewState->PrivilegeCount = 2; 00379 NewState->Privileges[0].Luid = CreateTokenPrivilege; 00380 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 00381 NewState->Privileges[1].Luid = AssignPrimaryTokenPrivilege; 00382 NewState->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; 00383 00384 00385 Status = NtAdjustPrivilegesToken( 00386 ProcessToken, // TokenHandle 00387 FALSE, // DisableAllPrivileges 00388 NewState, // NewState (OPTIONAL) 00389 0, // BufferLength 00390 NULL, // PreviousState (OPTIONAL) 00391 &ReturnLength // ReturnLength 00392 ); 00393 00394 if (Status != STATUS_SUCCESS) { 00395 00396 DbgPrint("Failed to enable TCB and AssignPrimaryToken privilegs: 0x%x\n",Status); 00397 return FALSE; 00398 00399 } 00400 00401 DbgPrint("Done.\n"); 00402 00403 return TRUE; 00404 } 00405 00406 00407 00409 // // 00410 // Test routines // 00411 // // 00413 00415 // // 00416 // Token Creation Test // 00417 // // 00419 00420 BOOLEAN 00421 TestTokenCreate() 00422 { 00423 00424 BOOLEAN CompletionStatus = TRUE; 00425 00426 TOKEN_USER UserId; 00427 TOKEN_PRIMARY_GROUP PrimaryGroup; 00428 PTOKEN_GROUPS GroupIds; 00429 PTOKEN_PRIVILEGES Privileges; 00430 TOKEN_DEFAULT_DACL DefaultDacl; 00431 TOKEN_DEFAULT_DACL NullDefaultDacl; 00432 TOKEN_OWNER Owner; 00433 00434 DbgPrint("\n"); 00435 00436 GroupIds = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 00437 GROUP_IDS_LENGTH 00438 ); 00439 00440 Privileges = (PTOKEN_PRIVILEGES)TstAllocatePool( PagedPool, 00441 PRIVILEGES_LENGTH 00442 ); 00443 00444 DefaultDacl.DefaultDacl = (PACL)TstAllocatePool( PagedPool, 00445 DEFAULT_DACL_LENGTH 00446 ); 00447 00448 00449 // 00450 // Create the simplest token possible 00451 // (no Groups, explicit Owner, or DefaultDacl) 00452 // 00453 00454 DbgPrint("Se: Create Simple Token ... "); 00455 00456 UserId.User.Sid = PebblesSid; 00457 UserId.User.Attributes = 0; 00458 GroupIds->GroupCount = 0; 00459 Privileges->PrivilegeCount = 0; 00460 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00461 00462 00463 Status = NtCreateToken( 00464 &Token, // Handle 00465 (TOKEN_ALL_ACCESS), // DesiredAccess 00466 &PrimaryTokenAttributes, // ObjectAttributes 00467 TokenPrimary, // TokenType 00468 &SystemAuthenticationId, // Authentication LUID 00469 &NoExpiration, // Expiration Time 00470 &UserId, // Owner ID 00471 GroupIds, // Group IDs 00472 Privileges, // Privileges 00473 NULL, // Owner 00474 &PrimaryGroup, // Primary Group 00475 NULL, // Default Dacl 00476 &TestSource // TokenSource 00477 ); 00478 00479 if (NT_SUCCESS(Status)) { 00480 DbgPrint("Succeeded.\n"); 00481 Status = NtDuplicateObject( 00482 NtCurrentProcess(), // SourceProcessHandle 00483 Token, // SourceHandle 00484 NtCurrentProcess(), // TargetProcessHandle 00485 &SimpleToken, // TargetHandle 00486 0, // DesiredAccess (over-ridden by option) 00487 0, // HandleAttributes 00488 DUPLICATE_SAME_ACCESS // Options 00489 ); 00490 ASSERT(NT_SUCCESS(Status)); 00491 Status = NtClose(Token); 00492 ASSERT(NT_SUCCESS(Status)); 00493 } else { 00494 DbgPrint("********** Failed ************\n"); 00495 DbgPrint("Status is: 0x%lx \n", Status); 00496 CompletionStatus = FALSE; 00497 } 00498 00499 ASSERT(NT_SUCCESS(Status)); 00500 00501 00502 00503 // 00504 // Create a token with groups 00505 // 00506 00507 DbgPrint("Se: Create Token With Groups ... "); 00508 00509 GroupIds->GroupCount = GROUP_COUNT; 00510 00511 GroupIds->Groups[0].Sid = FlintstoneSid; 00512 GroupIds->Groups[1].Sid = ChildSid; 00513 GroupIds->Groups[2].Sid = NeandertholSid; 00514 GroupIds->Groups[3].Sid = WorldSid; 00515 00516 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 00517 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 00518 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 00519 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 00520 00521 00522 UserId.User.Sid = PebblesSid; 00523 UserId.User.Attributes = 0; 00524 00525 Privileges->PrivilegeCount = 0; 00526 00527 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00528 00529 00530 Status = NtCreateToken( 00531 &Token, // Handle 00532 (TOKEN_ALL_ACCESS), // DesiredAccess 00533 &PrimaryTokenAttributes, // ObjectAttributes 00534 TokenPrimary, // TokenType 00535 &OriginalAuthenticationId, // Authentication LUID 00536 &NoExpiration, // Expiration Time 00537 &UserId, // Owner ID 00538 GroupIds, // Group IDs 00539 Privileges, // Privileges 00540 NULL, // Owner 00541 &PrimaryGroup, // Primary Group 00542 NULL, // Default Dacl 00543 &TestSource // TokenSource 00544 ); 00545 00546 if (NT_SUCCESS(Status)) { 00547 DbgPrint("Succeeded.\n"); 00548 Status = NtDuplicateObject( 00549 NtCurrentProcess(), // SourceProcessHandle 00550 Token, // SourceHandle 00551 NtCurrentProcess(), // TargetProcessHandle 00552 &TokenWithGroups, // TargetHandle 00553 0, // DesiredAccess (over-ridden by option) 00554 0, // HandleAttributes 00555 DUPLICATE_SAME_ACCESS // Options 00556 ); 00557 ASSERT(NT_SUCCESS(Status)); 00558 Status = NtClose(Token); 00559 ASSERT(NT_SUCCESS(Status)); 00560 } else { 00561 DbgPrint("********** Failed ************\n"); 00562 DbgPrint("Status is: 0x%lx \n", Status); 00563 CompletionStatus = FALSE; 00564 } 00565 00566 ASSERT(NT_SUCCESS(Status)); 00567 00568 00569 00570 00571 // 00572 // Create a token with default owner 00573 // 00574 00575 DbgPrint("Se: Create Token Default Owner ... "); 00576 00577 GroupIds->GroupCount = GROUP_COUNT; 00578 00579 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 00580 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 00581 GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid; 00582 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 00583 00584 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 00585 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 00586 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 00587 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 00588 00589 00590 UserId.User.Sid = PebblesSid; 00591 UserId.User.Attributes = 0; 00592 00593 Owner.Owner = FlintstoneSid; 00594 00595 Privileges->PrivilegeCount = 0; 00596 00597 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00598 00599 00600 Status = NtCreateToken( 00601 &Token, // Handle 00602 (TOKEN_ALL_ACCESS), // DesiredAccess 00603 &PrimaryTokenAttributes, // ObjectAttributes 00604 TokenPrimary, // TokenType 00605 &SystemAuthenticationId, // Authentication LUID 00606 &NoExpiration, // Expiration Time 00607 &UserId, // Owner ID 00608 GroupIds, // Group IDs 00609 Privileges, // Privileges 00610 &Owner, // Owner 00611 &PrimaryGroup, // Primary Group 00612 NULL, // Default Dacl 00613 &TestSource // TokenSource 00614 ); 00615 00616 if (NT_SUCCESS(Status)) { 00617 DbgPrint("Succeeded.\n"); 00618 Status = NtDuplicateObject( 00619 NtCurrentProcess(), // SourceProcessHandle 00620 Token, // SourceHandle 00621 NtCurrentProcess(), // TargetProcessHandle 00622 &TokenWithDefaultOwner, // TargetHandle 00623 0, // DesiredAccess (over-ridden by option) 00624 0, // HandleAttributes 00625 DUPLICATE_SAME_ACCESS // Options 00626 ); 00627 ASSERT(NT_SUCCESS(Status)); 00628 Status = NtClose(Token); 00629 ASSERT(NT_SUCCESS(Status)); 00630 } else { 00631 DbgPrint("********** Failed ************\n"); 00632 DbgPrint("Status is: 0x%lx \n", Status); 00633 CompletionStatus = FALSE; 00634 } 00635 00636 ASSERT(NT_SUCCESS(Status)); 00637 00638 00639 00640 00641 // 00642 // Create a token with default privileges 00643 // 00644 00645 DbgPrint("Se: Create Token privileges ... "); 00646 00647 GroupIds->GroupCount = GROUP_COUNT; 00648 00649 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 00650 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 00651 GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid; 00652 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 00653 00654 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 00655 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 00656 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 00657 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 00658 00659 00660 UserId.User.Sid = PebblesSid; 00661 UserId.User.Attributes = 0; 00662 00663 Owner.Owner = FlintstoneSid; 00664 00665 Privileges->PrivilegeCount = PRIVILEGE_COUNT; 00666 00667 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 00668 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 00669 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid = AssignPrimaryTokenPrivilege; 00670 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 00671 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 00672 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes = SE_PRIVILEGE_ENABLED; 00673 00674 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00675 00676 00677 Status = NtCreateToken( 00678 &Token, // Handle 00679 (TOKEN_ALL_ACCESS), // DesiredAccess 00680 &PrimaryTokenAttributes, // ObjectAttributes 00681 TokenPrimary, // TokenType 00682 &OriginalAuthenticationId, // Authentication LUID 00683 &NoExpiration, // Expiration Time 00684 &UserId, // Owner ID 00685 GroupIds, // Group IDs 00686 Privileges, // Privileges 00687 &Owner, // Owner 00688 &PrimaryGroup, // Primary Group 00689 NULL, // Default Dacl 00690 &TestSource // TokenSource 00691 ); 00692 00693 if (NT_SUCCESS(Status)) { 00694 DbgPrint("Succeeded.\n"); 00695 Status = NtDuplicateObject( 00696 NtCurrentProcess(), // SourceProcessHandle 00697 Token, // SourceHandle 00698 NtCurrentProcess(), // TargetProcessHandle 00699 &TokenWithPrivileges, // TargetHandle 00700 0, // DesiredAccess (over-ridden by option) 00701 0, // HandleAttributes 00702 DUPLICATE_SAME_ACCESS // Options 00703 ); 00704 ASSERT(NT_SUCCESS(Status)); 00705 Status = NtClose(Token); 00706 ASSERT(NT_SUCCESS(Status)); 00707 } else { 00708 DbgPrint("********** Failed ************\n"); 00709 DbgPrint("Status is: 0x%lx \n", Status); 00710 CompletionStatus = FALSE; 00711 } 00712 00713 ASSERT(NT_SUCCESS(Status)); 00714 00715 00716 00717 00718 // 00719 // Create a token with default DACL 00720 // 00721 00722 DbgPrint("Se: Create Token With Default Dacl ... "); 00723 00724 GroupIds->GroupCount = GROUP_COUNT; 00725 00726 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 00727 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 00728 GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid; 00729 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 00730 00731 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 00732 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 00733 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 00734 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 00735 00736 UserId.User.Sid = PebblesSid; 00737 UserId.User.Attributes = 0; 00738 00739 Owner.Owner = FlintstoneSid; 00740 00741 Privileges->PrivilegeCount = PRIVILEGE_COUNT; 00742 00743 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 00744 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 00745 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid = AssignPrimaryTokenPrivilege; 00746 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 00747 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 00748 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes = SE_PRIVILEGE_ENABLED; 00749 00750 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00751 00752 Status = RtlCreateAcl( DefaultDacl.DefaultDacl, DEFAULT_DACL_LENGTH, ACL_REVISION); 00753 00754 ASSERT(NT_SUCCESS(Status) ); 00755 00756 Status = NtCreateToken( 00757 &Token, // Handle 00758 (TOKEN_ALL_ACCESS), // DesiredAccess 00759 &PrimaryTokenAttributes, // ObjectAttributes 00760 TokenPrimary, // TokenType 00761 &SystemAuthenticationId, // Authentication LUID 00762 &NoExpiration, // Expiration Time 00763 &UserId, // Owner ID 00764 GroupIds, // Group IDs 00765 Privileges, // Privileges 00766 &Owner, // Owner 00767 &PrimaryGroup, // Primary Group 00768 &DefaultDacl, // Default Dacl 00769 &TestSource // TokenSource 00770 ); 00771 00772 if (NT_SUCCESS(Status)) { 00773 DbgPrint("Succeeded.\n"); 00774 00775 // 00776 // Save a copy of this for later use... 00777 // 00778 00779 Status = NtDuplicateObject( 00780 NtCurrentProcess(), // SourceProcessHandle 00781 Token, // SourceHandle 00782 NtCurrentProcess(), // TargetProcessHandle 00783 &TokenWithDefaultDacl, // TargetHandle 00784 0, // DesiredAccess (over-ridden by option) 00785 0, // HandleAttributes 00786 DUPLICATE_SAME_ACCESS // Options 00787 ); 00788 ASSERT(NT_SUCCESS(Status)); 00789 Status = NtClose(Token); 00790 ASSERT(NT_SUCCESS(Status)); 00791 } else { 00792 DbgPrint("********** Failed ************\n"); 00793 DbgPrint("Status is: 0x%lx \n", Status); 00794 CompletionStatus = FALSE; 00795 } 00796 00797 ASSERT(NT_SUCCESS(Status)); 00798 00799 00800 00801 00802 // 00803 // Create a token with a null default DACL 00804 // 00805 00806 DbgPrint("Se: Create Token With a Null Default Dacl ... "); 00807 00808 GroupIds->GroupCount = GROUP_COUNT; 00809 00810 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 00811 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 00812 GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid; 00813 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 00814 00815 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 00816 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 00817 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 00818 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 00819 00820 UserId.User.Sid = PebblesSid; 00821 UserId.User.Attributes = 0; 00822 00823 Owner.Owner = FlintstoneSid; 00824 00825 Privileges->PrivilegeCount = PRIVILEGE_COUNT; 00826 00827 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 00828 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 00829 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid = AssignPrimaryTokenPrivilege; 00830 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 00831 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 00832 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes = SE_PRIVILEGE_ENABLED; 00833 00834 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00835 00836 NullDefaultDacl.DefaultDacl = NULL; 00837 00838 00839 Status = NtCreateToken( 00840 &Token, // Handle 00841 (TOKEN_ALL_ACCESS), // DesiredAccess 00842 &PrimaryTokenAttributes, // ObjectAttributes 00843 TokenPrimary, // TokenType 00844 &OriginalAuthenticationId, // Authentication LUID 00845 &NoExpiration, // Expiration Time 00846 &UserId, // Owner ID 00847 GroupIds, // Group IDs 00848 Privileges, // Privileges 00849 &Owner, // Owner 00850 &PrimaryGroup, // Primary Group 00851 &NullDefaultDacl, // Default Dacl 00852 &TestSource // TokenSource 00853 ); 00854 00855 if (NT_SUCCESS(Status)) { 00856 DbgPrint("Succeeded.\n"); 00857 Status = NtClose(Token); 00858 ASSERT(NT_SUCCESS(Status)); 00859 } else { 00860 DbgPrint("********** Failed ************\n"); 00861 DbgPrint("Status is: 0x%lx \n", Status); 00862 CompletionStatus = FALSE; 00863 } 00864 00865 ASSERT(NT_SUCCESS(Status)); 00866 00867 00868 00869 00870 // 00871 // Create an impersonation token, Impersonation level = Impersonation 00872 // 00873 00874 DbgPrint("Se: Create an impersonation token ... "); 00875 00876 GroupIds->GroupCount = GROUP_COUNT; 00877 00878 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 00879 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 00880 GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid; 00881 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 00882 00883 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 00884 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 00885 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 00886 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 00887 00888 UserId.User.Sid = PebblesSid; 00889 UserId.User.Attributes = 0; 00890 00891 Owner.Owner = FlintstoneSid; 00892 00893 Privileges->PrivilegeCount = PRIVILEGE_COUNT; 00894 00895 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 00896 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 00897 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid = AssignPrimaryTokenPrivilege; 00898 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 00899 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 00900 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes = SE_PRIVILEGE_ENABLED; 00901 00902 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00903 00904 Status = RtlCreateAcl( DefaultDacl.DefaultDacl, DEFAULT_DACL_LENGTH, ACL_REVISION); 00905 00906 ASSERT(NT_SUCCESS(Status) ); 00907 00908 Status = NtCreateToken( 00909 &Token, // Handle 00910 (TOKEN_ALL_ACCESS), // DesiredAccess 00911 &ImpersonationTokenAttributes, // ObjectAttributes 00912 TokenImpersonation, // TokenType 00913 &SystemAuthenticationId, // Authentication LUID 00914 &NoExpiration, // Expiration Time 00915 &UserId, // Owner ID 00916 GroupIds, // Group IDs 00917 Privileges, // Privileges 00918 &Owner, // Owner 00919 &PrimaryGroup, // Primary Group 00920 &DefaultDacl, // Default Dacl 00921 &TestSource // TokenSource 00922 ); 00923 00924 if (NT_SUCCESS(Status)) { 00925 DbgPrint("Succeeded.\n"); 00926 Status = NtDuplicateObject( 00927 NtCurrentProcess(), // SourceProcessHandle 00928 Token, // SourceHandle 00929 NtCurrentProcess(), // TargetProcessHandle 00930 &ImpersonationToken, // TargetHandle 00931 0, // DesiredAccess (over-ridden by option) 00932 0, // HandleAttributes 00933 DUPLICATE_SAME_ACCESS // Options 00934 ); 00935 ASSERT(NT_SUCCESS(Status)); 00936 Status = NtClose(Token); 00937 ASSERT(NT_SUCCESS(Status)); 00938 } else { 00939 DbgPrint("********** Failed ************\n"); 00940 DbgPrint("Status is: 0x%lx \n", Status); 00941 CompletionStatus = FALSE; 00942 } 00943 00944 ASSERT(NT_SUCCESS(Status)); 00945 00946 00947 00948 00949 // 00950 // Create an impersonation token, Impersonation level = Anonymous 00951 // 00952 00953 DbgPrint("Se: Create an anonymous token ... "); 00954 00955 GroupIds->GroupCount = GROUP_COUNT; 00956 00957 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 00958 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 00959 GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid; 00960 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 00961 00962 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 00963 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 00964 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 00965 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 00966 00967 UserId.User.Sid = PebblesSid; 00968 UserId.User.Attributes = 0; 00969 00970 Owner.Owner = FlintstoneSid; 00971 00972 Privileges->PrivilegeCount = PRIVILEGE_COUNT; 00973 00974 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 00975 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 00976 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid = AssignPrimaryTokenPrivilege; 00977 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 00978 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 00979 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes = SE_PRIVILEGE_ENABLED; 00980 00981 PrimaryGroup.PrimaryGroup = FlintstoneSid; 00982 00983 Status = RtlCreateAcl( DefaultDacl.DefaultDacl, DEFAULT_DACL_LENGTH, ACL_REVISION); 00984 00985 ASSERT(NT_SUCCESS(Status) ); 00986 00987 Status = NtCreateToken( 00988 &Token, // Handle 00989 (TOKEN_ALL_ACCESS), // DesiredAccess 00990 &AnonymousTokenAttributes, // ObjectAttributes 00991 TokenImpersonation, // TokenType 00992 &OriginalAuthenticationId, // Authentication LUID 00993 &NoExpiration, // Expiration Time 00994 &UserId, // Owner ID 00995 GroupIds, // Group IDs 00996 Privileges, // Privileges 00997 &Owner, // Owner 00998 &PrimaryGroup, // Primary Group 00999 &DefaultDacl, // Default Dacl 01000 &TestSource // TokenSource 01001 ); 01002 01003 if (NT_SUCCESS(Status)) { 01004 DbgPrint("Succeeded.\n"); 01005 Status = NtDuplicateObject( 01006 NtCurrentProcess(), // SourceProcessHandle 01007 Token, // SourceHandle 01008 NtCurrentProcess(), // TargetProcessHandle 01009 &AnonymousToken, // TargetHandle 01010 0, // DesiredAccess (over-ridden by option) 01011 0, // HandleAttributes 01012 DUPLICATE_SAME_ACCESS // Options 01013 ); 01014 ASSERT(NT_SUCCESS(Status)); 01015 Status = NtClose(Token); 01016 ASSERT(NT_SUCCESS(Status)); 01017 } else { 01018 DbgPrint("********** Failed ************\n"); 01019 DbgPrint("Status is: 0x%lx \n", Status); 01020 CompletionStatus = FALSE; 01021 } 01022 01023 ASSERT(NT_SUCCESS(Status)); 01024 01025 01026 01027 // 01028 // Create the simplest token possible 01029 // (no Groups, explicit Owner, or DefaultDacl) 01030 // 01031 01032 DbgPrint("Se: Create Token With Bad Authentication Id ... "); 01033 01034 UserId.User.Sid = PebblesSid; 01035 UserId.User.Attributes = 0; 01036 GroupIds->GroupCount = 0; 01037 Privileges->PrivilegeCount = 0; 01038 PrimaryGroup.PrimaryGroup = FlintstoneSid; 01039 01040 01041 Status = NtCreateToken( 01042 &Token, // Handle 01043 (TOKEN_ALL_ACCESS), // DesiredAccess 01044 &PrimaryTokenAttributes, // ObjectAttributes 01045 TokenPrimary, // TokenType 01046 &BadAuthenticationId, // Authentication LUID 01047 &NoExpiration, // Expiration Time 01048 &UserId, // Owner ID 01049 GroupIds, // Group IDs 01050 Privileges, // Privileges 01051 NULL, // Owner 01052 &PrimaryGroup, // Primary Group 01053 NULL, // Default Dacl 01054 &TestSource // TokenSource 01055 ); 01056 01057 if (Status == STATUS_NO_SUCH_LOGON_SESSION) { 01058 DbgPrint("Succeeded.\n"); 01059 } else { 01060 DbgPrint("********** Failed ************\n"); 01061 DbgPrint("Status is: 0x%lx \n", Status); 01062 DbgPrint("Status should be: 0x%lx \n", STATUS_NO_SUCH_LOGON_SESSION); 01063 CompletionStatus = FALSE; 01064 } 01065 01066 01067 01068 01069 01070 01071 // 01072 // All done with this test 01073 // 01074 01075 return CompletionStatus; 01076 } 01077 01079 // // 01080 // Token Filtering Test // 01081 // // 01083 01084 BOOLEAN 01085 TestTokenFilter() 01086 { 01087 01088 BOOLEAN CompletionStatus = TRUE; 01089 01090 PTOKEN_GROUPS GroupIds; 01091 PTOKEN_GROUPS RestrictedGroupIds; 01092 PTOKEN_PRIVILEGES Privileges; 01093 01094 DbgPrint("\n"); 01095 01096 GroupIds = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 01097 GROUP_IDS_LENGTH 01098 ); 01099 01100 RestrictedGroupIds = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 01101 GROUP_IDS_LENGTH 01102 ); 01103 01104 Privileges = (PTOKEN_PRIVILEGES)TstAllocatePool( PagedPool, 01105 PRIVILEGES_LENGTH 01106 ); 01107 01108 01109 01110 01111 // 01112 // Filter a token without doing anything 01113 // 01114 01115 DbgPrint("Se: Filter null Token ... "); 01116 Status = NtFilterToken( 01117 TokenWithGroups, 01118 0, // no flags 01119 NULL, // no groups to disable 01120 NULL, // no privileges to disable 01121 NULL, // no restricted sids 01122 &Token 01123 ); 01124 if (NT_SUCCESS(Status)) { 01125 DbgPrint("Succeeded.\n"); 01126 NtClose(Token); 01127 } else { 01128 DbgPrint("********** Failed ************\n"); 01129 DbgPrint("Status is: 0x%lx \n", Status); 01130 CompletionStatus = FALSE; 01131 } 01132 01133 // 01134 // Filter a token and remove some groups 01135 // 01136 01137 GroupIds->GroupCount = 2; 01138 01139 GroupIds->Groups[0].Sid = FlintstoneSid; 01140 GroupIds->Groups[1].Sid = ChildSid; 01141 01142 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = SE_GROUP_USE_FOR_DENY_ONLY; 01143 GroupIds->Groups[CHILD_INDEX].Attributes = SE_GROUP_USE_FOR_DENY_ONLY; 01144 01145 01146 DbgPrint("Se: Filter token with disabled groups ... "); 01147 Status = NtFilterToken( 01148 TokenWithGroups, 01149 0, // no flags 01150 GroupIds, // no groups to disable 01151 NULL, // no privileges to disable 01152 NULL, // no restricted sids 01153 &TokenWithRestrictedGroups 01154 ); 01155 if (NT_SUCCESS(Status)) { 01156 DbgPrint("Succeeded.\n"); 01157 } else { 01158 DbgPrint("********** Failed ************\n"); 01159 DbgPrint("Status is: 0x%lx \n", Status); 01160 CompletionStatus = FALSE; 01161 } 01162 01163 01164 // 01165 // Filter a token and remove some privileges 01166 // 01167 01168 01169 Privileges->PrivilegeCount = 2; 01170 01171 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 01172 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 01173 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 01174 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 01175 01176 01177 DbgPrint("Se: Filter token with disabled privilegs ... "); 01178 Status = NtFilterToken( 01179 TokenWithPrivileges, 01180 0, // no flags 01181 NULL, // no groups to disable 01182 Privileges, // no privileges to disable 01183 NULL, // no restricted sids 01184 &TokenWithRestrictedPrivileges 01185 ); 01186 if (NT_SUCCESS(Status)) { 01187 DbgPrint("Succeeded.\n"); 01188 } else { 01189 DbgPrint("********** Failed ************\n"); 01190 DbgPrint("Status is: 0x%lx \n", Status); 01191 CompletionStatus = FALSE; 01192 } 01193 01194 01195 // 01196 // Filter a restricted token and add some restricted sids 01197 // 01198 01199 RestrictedGroupIds->GroupCount = RESTRICTED_SID_COUNT; 01200 01201 RestrictedGroupIds->GroupCount = RESTRICTED_SID_COUNT; 01202 01203 RestrictedGroupIds->Groups[0].Sid = FlintstoneSid; 01204 RestrictedGroupIds->Groups[1].Sid = ChildSid; 01205 01206 RestrictedGroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 01207 RestrictedGroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 01208 01209 01210 01211 DbgPrint("Se: Filter token with restricted sids ... "); 01212 Status = NtFilterToken( 01213 TokenWithGroups, 01214 0, // no flags 01215 NULL, // no groups to disable 01216 NULL, // no privileges to disable 01217 RestrictedGroupIds, // no restricted sids 01218 &TokenWithRestrictedSids 01219 ); 01220 if (NT_SUCCESS(Status)) { 01221 DbgPrint("Succeeded.\n"); 01222 } else { 01223 DbgPrint("********** Failed ************\n"); 01224 DbgPrint("Status is: 0x%lx \n", Status); 01225 CompletionStatus = FALSE; 01226 } 01227 01228 01229 // 01230 // Filter a token and add some restricted sids 01231 // 01232 01233 RestrictedGroupIds->GroupCount = RESTRICTED_SID_COUNT; 01234 01235 RestrictedGroupIds->Groups[0].Sid = NeandertholSid; 01236 RestrictedGroupIds->Groups[1].Sid = WorldSid; 01237 01238 RestrictedGroupIds->Groups[0].Attributes = OwnerGroupAttributes; 01239 RestrictedGroupIds->Groups[1].Attributes = OptionalGroupAttributes; 01240 01241 01242 DbgPrint("Se: Filter token with more restricted sids ... "); 01243 Status = NtFilterToken( 01244 TokenWithRestrictedSids, 01245 0, // no flags 01246 NULL, // no groups to disable 01247 NULL, // no privileges to disable 01248 RestrictedGroupIds, // no restricted sids 01249 &TokenWithMoreRestrictedSids 01250 ); 01251 if (NT_SUCCESS(Status)) { 01252 DbgPrint("Succeeded.\n"); 01253 } else { 01254 DbgPrint("********** Failed ************\n"); 01255 DbgPrint("Status is: 0x%lx \n", Status); 01256 CompletionStatus = FALSE; 01257 } 01258 01259 01260 // 01261 // All done with this test 01262 // 01263 01264 return CompletionStatus; 01265 } 01266 01267 01268 01270 // // 01271 // Open Primary Token Test // 01272 // // 01274 01275 BOOLEAN 01276 TestTokenOpenPrimary() 01277 { 01278 NTSTATUS Status; 01279 BOOLEAN CompletionStatus = TRUE; 01280 01281 HANDLE ProcessToken; 01282 HANDLE SubProcessToken; 01283 HANDLE SubProcess; 01284 01285 TOKEN_STATISTICS ProcessTokenStatistics; 01286 TOKEN_STATISTICS SubProcessTokenStatistics; 01287 01288 ULONG ReturnLength; 01289 01290 DbgPrint("\n"); 01291 01292 // 01293 // Open the current process's token 01294 // 01295 01296 DbgPrint("Se: Open own process's token ... "); 01297 01298 Status = NtOpenProcessToken( 01299 NtCurrentProcess(), 01300 TOKEN_ALL_ACCESS, 01301 &ProcessToken 01302 ); 01303 if (NT_SUCCESS(Status)) { 01304 Status = NtQueryInformationToken( 01305 ProcessToken, // Handle 01306 TokenStatistics, // TokenInformationClass 01307 &ProcessTokenStatistics, // TokenInformation 01308 sizeof(TOKEN_STATISTICS), // TokenInformationLength 01309 &ReturnLength // ReturnLength 01310 ); 01311 ASSERT(NT_SUCCESS(Status)); 01312 if ( ProcessTokenStatistics.TokenType == TokenPrimary) { 01313 if ( RtlEqualLuid( &ProcessTokenStatistics.AuthenticationId, 01314 &OriginalAuthenticationId ) ) { 01315 DbgPrint("Succeeded.\n"); 01316 } else { 01317 DbgPrint("********** Failed ************\n"); 01318 DbgPrint("Unexpected authentication ID value.\n"); 01319 DbgPrint("Authentication ID is: "); 01320 TestpPrintLuid(ProcessTokenStatistics.AuthenticationId); 01321 DbgPrint("\n"); 01322 CompletionStatus = FALSE; 01323 } 01324 01325 } else { 01326 DbgPrint("********** Failed ************\n"); 01327 DbgPrint("Token type not TokenPrimary.\n"); 01328 DbgPrint("Returned token type is: 0x%lx \n", 01329 ProcessTokenStatistics.TokenType); 01330 DbgPrint("Authentication ID is: "); 01331 TestpPrintLuid(ProcessTokenStatistics.AuthenticationId); 01332 DbgPrint("\n"); 01333 CompletionStatus = FALSE; 01334 } 01335 Status = NtClose(ProcessToken); 01336 ASSERT(NT_SUCCESS(Status)); 01337 01338 } else { 01339 DbgPrint("********** Failed ************\n"); 01340 DbgPrint("Status is: 0x%lx \n", Status); 01341 CompletionStatus = FALSE; 01342 } 01343 01344 01345 01346 01347 01348 01349 // 01350 // Open another process's token 01351 // 01352 01353 DbgPrint("Se: Open another process's token ... "); 01354 01355 Status = NtCreateProcess( 01356 &SubProcess, 01357 (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE), 01358 NULL, 01359 NtCurrentProcess(), // ParentProcess 01360 FALSE, // InheritObjectTable 01361 NULL, // SectionHandle, 01362 NULL, // DebugPort, 01363 NULL // ExceptionPort 01364 ); 01365 01366 Status = NtOpenProcessToken( 01367 SubProcess, 01368 TOKEN_ALL_ACCESS, 01369 &SubProcessToken 01370 ); 01371 if (NT_SUCCESS(Status)) { 01372 Status = NtQueryInformationToken( 01373 SubProcessToken, // Handle 01374 TokenStatistics, // TokenInformationClass 01375 &SubProcessTokenStatistics, // TokenInformation 01376 sizeof(TOKEN_STATISTICS), // TokenInformationLength 01377 &ReturnLength // ReturnLength 01378 ); 01379 ASSERT(NT_SUCCESS(Status)); 01380 if ( SubProcessTokenStatistics.TokenType == TokenPrimary) { 01381 if ( RtlEqualLuid( &SubProcessTokenStatistics.AuthenticationId, 01382 &OriginalAuthenticationId ) ) { 01383 if ( (ProcessTokenStatistics.TokenId.HighPart == 01384 SubProcessTokenStatistics.TokenId.HighPart) && 01385 (ProcessTokenStatistics.TokenId.LowPart == 01386 SubProcessTokenStatistics.TokenId.LowPart) ) { 01387 DbgPrint("********** Failed ************\n"); 01388 DbgPrint("Same token as parent process (token IDs match).\n"); 01389 DbgPrint("Authentication ID is: "); 01390 TestpPrintLuid(SubProcessTokenStatistics.AuthenticationId); 01391 DbgPrint("\n"); 01392 CompletionStatus = FALSE; 01393 01394 } else { 01395 DbgPrint("Succeeded.\n"); 01396 } 01397 } else { 01398 DbgPrint("********** Failed ************\n"); 01399 DbgPrint("Unexpected authentication ID value.\n"); 01400 DbgPrint("Authentication ID is: "); 01401 TestpPrintLuid(SubProcessTokenStatistics.AuthenticationId); 01402 DbgPrint("\n"); 01403 CompletionStatus = FALSE; 01404 } 01405 } else { 01406 DbgPrint("********** Failed ************\n"); 01407 DbgPrint("Token type not TokenPrimary.\n"); 01408 DbgPrint("Returned token type is: 0x%lx \n", 01409 SubProcessTokenStatistics.TokenType); 01410 DbgPrint("Authentication ID is: "); 01411 TestpPrintLuid(SubProcessTokenStatistics.AuthenticationId); 01412 DbgPrint("\n"); 01413 CompletionStatus = FALSE; 01414 } 01415 Status = NtClose(SubProcessToken); 01416 ASSERT(NT_SUCCESS(Status)); 01417 } else { 01418 DbgPrint("********** Failed ************\n"); 01419 DbgPrint("Status is: 0x%lx \n", Status); 01420 CompletionStatus = FALSE; 01421 } 01422 01423 01424 return CompletionStatus; 01425 } 01426 01428 // // 01429 // Query Token Test // 01430 // // 01432 01433 BOOLEAN 01434 TestTokenQuery() 01435 { 01436 BOOLEAN CompletionStatus = TRUE; 01437 ULONG ReturnLength; 01438 BOOLEAN ValuesCompare; 01439 01440 PTOKEN_USER UserId = NULL; 01441 PTOKEN_PRIMARY_GROUP PrimaryGroup = NULL; 01442 PTOKEN_GROUPS GroupIds = NULL; 01443 PTOKEN_GROUPS RestrictedSids = NULL; 01444 PTOKEN_PRIVILEGES Privileges = NULL; 01445 PTOKEN_OWNER Owner = NULL; 01446 PTOKEN_DEFAULT_DACL DefaultDacl = NULL; 01447 01448 SECURITY_IMPERSONATION_LEVEL QueriedImpersonationLevel; 01449 TOKEN_SOURCE QueriedSource; 01450 TOKEN_TYPE QueriedType; 01451 TOKEN_STATISTICS QueriedStatistics; 01452 01453 DbgPrint("\n"); 01454 01455 01456 01457 #if 0 01458 01459 // 01460 // Query invalid return buffer address 01461 // 01462 01463 DbgPrint("Se: Query with invalid buffer address ... "); 01464 01465 UserId = (PTOKEN_USER)((PVOID)0x200L); 01466 Status = NtQueryInformationToken( 01467 SimpleToken, // Handle 01468 TokenUser, // TokenInformationClass 01469 UserId, // TokenInformation 01470 3000, // TokenInformationLength 01471 &ReturnLength // ReturnLength 01472 ); 01473 #ifdef TOKEN_DEBUG 01474 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01475 #endif //TOKEN_DEBUG 01476 01477 if (Status == STATUS_ACCESS_VIOLATION) { 01478 DbgPrint("Succeeded.\n"); 01479 } else { 01480 DbgPrint("********** Failed ************\n"); 01481 DbgPrint("Status is: 0x%lx \n", Status); 01482 CompletionStatus = FALSE; 01483 } 01484 01485 ASSERT(!NT_SUCCESS(Status)); 01486 01487 #endif //0 01488 01489 01491 // // 01492 // Query User ID // 01493 // // 01495 01496 // 01497 // Query User ID with zero length buffer 01498 // 01499 01500 DbgPrint("Se: Query User ID with zero length buffer ... "); 01501 01502 Status = NtQueryInformationToken( 01503 SimpleToken, // Handle 01504 TokenUser, // TokenInformationClass 01505 UserId, // TokenInformation 01506 0, // TokenInformationLength 01507 &ReturnLength // ReturnLength 01508 ); 01509 #ifdef TOKEN_DEBUG 01510 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01511 #endif //TOKEN_DEBUG 01512 01513 if (Status == STATUS_BUFFER_TOO_SMALL) { 01514 DbgPrint("Succeeded.\n"); 01515 } else { 01516 DbgPrint("********** Failed ************\n"); 01517 DbgPrint("Status is: 0x%lx \n", Status); 01518 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01519 CompletionStatus = FALSE; 01520 } 01521 01522 ASSERT(!NT_SUCCESS(Status)); 01523 01524 01525 01526 01527 UserId = (PTOKEN_USER)TstAllocatePool( PagedPool, 01528 ReturnLength 01529 ); 01530 01531 // 01532 // Query user SID 01533 // (This relies upon the ReturnLength returned from previous call) 01534 // 01535 01536 DbgPrint("Se: Query token user ... "); 01537 01538 Status = NtQueryInformationToken( 01539 SimpleToken, // Handle 01540 TokenUser, // TokenInformationClass 01541 UserId, // TokenInformation 01542 ReturnLength, // TokenInformationLength 01543 &ReturnLength // ReturnLength 01544 ); 01545 #ifdef TOKEN_DEBUG 01546 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01547 #endif //TOKEN_DEBUG 01548 01549 if (NT_SUCCESS(Status)) { 01550 01551 // 01552 // Check returned value 01553 // 01554 01555 if (RtlEqualSid((UserId->User.Sid), PebblesSid) ) { 01556 DbgPrint("Succeeded.\n"); 01557 } else { 01558 DbgPrint("********** Failed ************\n"); 01559 DbgPrint("Unexpected value returned by query.\n"); 01560 DbgPrint("Status is: 0x%lx \n", Status); 01561 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01562 CompletionStatus = FALSE; 01563 } 01564 } else { 01565 DbgPrint("********** Failed ************\n"); 01566 DbgPrint("Status is: 0x%lx \n", Status); 01567 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01568 CompletionStatus = FALSE; 01569 } 01570 01571 ASSERT(NT_SUCCESS(Status)); 01572 01573 01574 // 01575 // Query with too little buffer 01576 // (This relies upon the ReturnLength returned from previous call) 01577 // 01578 01579 DbgPrint("Se: Query user with too small buffer ... "); 01580 01581 Status = NtQueryInformationToken( 01582 SimpleToken, // Handle 01583 TokenUser, // TokenInformationClass 01584 UserId, // TokenInformation 01585 ReturnLength-1, // TokenInformationLength 01586 &ReturnLength // ReturnLength 01587 ); 01588 #ifdef TOKEN_DEBUG 01589 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01590 #endif //TOKEN_DEBUG 01591 01592 if (Status == STATUS_BUFFER_TOO_SMALL) { 01593 DbgPrint("Succeeded.\n"); 01594 } else { 01595 DbgPrint("********** Failed ************\n"); 01596 DbgPrint("Status is: 0x%lx \n", Status); 01597 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01598 CompletionStatus = FALSE; 01599 } 01600 01601 ASSERT(!NT_SUCCESS(Status)); 01602 01603 01605 // // 01606 // Query Primary Group // 01607 // // 01609 01610 // 01611 // Query primary group with zero length buffer 01612 // 01613 01614 DbgPrint("Se: Query primary group with zero length buffer ... "); 01615 01616 Status = NtQueryInformationToken( 01617 SimpleToken, // Handle 01618 TokenPrimaryGroup, // TokenInformationClass 01619 PrimaryGroup, // TokenInformation 01620 0, // TokenInformationLength 01621 &ReturnLength // ReturnLength 01622 ); 01623 #ifdef TOKEN_DEBUG 01624 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01625 #endif //TOKEN_DEBUG 01626 01627 if (Status == STATUS_BUFFER_TOO_SMALL) { 01628 DbgPrint("Succeeded.\n"); 01629 } else { 01630 DbgPrint("********** Failed ************\n"); 01631 DbgPrint("Status is: 0x%lx \n", Status); 01632 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01633 CompletionStatus = FALSE; 01634 } 01635 01636 ASSERT(!NT_SUCCESS(Status)); 01637 01638 01639 01640 01641 PrimaryGroup = (PTOKEN_PRIMARY_GROUP)TstAllocatePool( PagedPool, 01642 ReturnLength 01643 ); 01644 01645 // 01646 // Query primary group SID 01647 // (This relies upon the ReturnLength returned from previous call) 01648 // 01649 01650 DbgPrint("Se: Query primary group ... "); 01651 01652 Status = NtQueryInformationToken( 01653 SimpleToken, // Handle 01654 TokenPrimaryGroup, // TokenInformationClass 01655 PrimaryGroup, // TokenInformation 01656 ReturnLength, // TokenInformationLength 01657 &ReturnLength // ReturnLength 01658 ); 01659 #ifdef TOKEN_DEBUG 01660 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01661 #endif //TOKEN_DEBUG 01662 01663 if (NT_SUCCESS(Status)) { 01664 01665 // 01666 // Check returned value 01667 // 01668 01669 if (RtlEqualSid( PrimaryGroup->PrimaryGroup, FlintstoneSid) ) { 01670 DbgPrint("Succeeded.\n"); 01671 } else { 01672 DbgPrint("********** Failed ************\n"); 01673 DbgPrint("Unexpected value returned by query.\n"); 01674 DbgPrint("Status is: 0x%lx \n", Status); 01675 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01676 CompletionStatus = FALSE; 01677 } 01678 } else { 01679 DbgPrint("********** Failed ************\n"); 01680 DbgPrint("Status is: 0x%lx \n", Status); 01681 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01682 CompletionStatus = FALSE; 01683 } 01684 01685 ASSERT(NT_SUCCESS(Status)); 01686 01687 01688 // 01689 // Query with too little buffer 01690 // (This relies upon the ReturnLength returned from previous call) 01691 // 01692 01693 DbgPrint("Se: Query primary group with too small buffer ... "); 01694 01695 Status = NtQueryInformationToken( 01696 SimpleToken, // Handle 01697 TokenPrimaryGroup, // TokenInformationClass 01698 PrimaryGroup, // TokenInformation 01699 ReturnLength-1, // TokenInformationLength 01700 &ReturnLength // ReturnLength 01701 ); 01702 #ifdef TOKEN_DEBUG 01703 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01704 #endif //TOKEN_DEBUG 01705 01706 if (Status == STATUS_BUFFER_TOO_SMALL) { 01707 DbgPrint("Succeeded.\n"); 01708 } else { 01709 DbgPrint("********** Failed ************\n"); 01710 DbgPrint("Status is: 0x%lx \n", Status); 01711 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01712 CompletionStatus = FALSE; 01713 } 01714 01715 ASSERT(!NT_SUCCESS(Status)); 01716 01717 01718 01720 // // 01721 // Query Groups // 01722 // // 01724 01725 // 01726 // Query groups with zero length buffer 01727 // 01728 01729 DbgPrint("Se: Query groups with zero length buffer ... "); 01730 01731 Status = NtQueryInformationToken( 01732 TokenWithGroups, // Handle 01733 TokenGroups, // TokenInformationClass 01734 GroupIds, // TokenInformation 01735 0, // TokenInformationLength 01736 &ReturnLength // ReturnLength 01737 ); 01738 #ifdef TOKEN_DEBUG 01739 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01740 #endif //TOKEN_DEBUG 01741 01742 if (Status == STATUS_BUFFER_TOO_SMALL) { 01743 DbgPrint("Succeeded.\n"); 01744 } else { 01745 DbgPrint("********** Failed ************\n"); 01746 DbgPrint("Status is: 0x%lx \n", Status); 01747 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01748 CompletionStatus = FALSE; 01749 } 01750 01751 ASSERT(!NT_SUCCESS(Status)); 01752 01753 01754 01755 01756 GroupIds = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 01757 ReturnLength 01758 ); 01759 01760 // 01761 // Query Group SIDs 01762 // (This relies upon the ReturnLength returned from previous call) 01763 // 01764 01765 DbgPrint("Se: Query groups ... "); 01766 01767 Status = NtQueryInformationToken( 01768 TokenWithGroups, // Handle 01769 TokenGroups, // TokenInformationClass 01770 GroupIds, // TokenInformation 01771 ReturnLength, // TokenInformationLength 01772 &ReturnLength // ReturnLength 01773 ); 01774 #ifdef TOKEN_DEBUG 01775 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01776 #endif //TOKEN_DEBUG 01777 01778 if (NT_SUCCESS(Status)) { 01779 01780 // 01781 // Check returned value 01782 // Group count = 4 01783 // SID 0 = Flintstone 01784 // SID 1 = ChildSid 01785 // SID 2 = NeandertholSid 01786 // SID 3 = WorldSid 01787 // 01788 01789 ValuesCompare = TRUE; 01790 01791 if (GroupIds->GroupCount != GROUP_COUNT) { 01792 ValuesCompare = FALSE; 01793 } 01794 01795 if ( (!RtlEqualSid((GroupIds->Groups[FLINTSTONE_INDEX].Sid), 01796 FlintstoneSid)) || 01797 (GroupIds->Groups[FLINTSTONE_INDEX].Attributes != 01798 OwnerGroupAttributes) ) { 01799 ValuesCompare = FALSE; 01800 } 01801 01802 if ( (!RtlEqualSid((GroupIds->Groups[CHILD_INDEX].Sid), ChildSid)) || 01803 (GroupIds->Groups[CHILD_INDEX].Attributes != 01804 OptionalGroupAttributes) ) { 01805 ValuesCompare = FALSE; 01806 } 01807 01808 if ( (!RtlEqualSid((GroupIds->Groups[NEANDERTHOL_INDEX].Sid), 01809 NeandertholSid)) || 01810 (GroupIds->Groups[NEANDERTHOL_INDEX].Attributes != 01811 OptionalGroupAttributes) ) { 01812 ValuesCompare = FALSE; 01813 } 01814 01815 if ( (!RtlEqualSid((GroupIds->Groups[WORLD_INDEX].Sid), WorldSid)) || 01816 (GroupIds->Groups[WORLD_INDEX].Attributes != NormalGroupAttributes) ) { 01817 ValuesCompare = FALSE; 01818 } 01819 01820 01821 if ( ValuesCompare ) { 01822 DbgPrint("Succeeded.\n"); 01823 } else { 01824 DbgPrint("********** Failed ************\n"); 01825 DbgPrint("Unexpected value returned by query.\n"); 01826 DbgPrint("Status is: 0x%lx \n", Status); 01827 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01828 DbgPrint("Returned group count is: 0x%lx \n", GroupIds->GroupCount); 01829 CompletionStatus = FALSE; 01830 } 01831 } else { 01832 DbgPrint("********** Failed ************\n"); 01833 DbgPrint("Status is: 0x%lx \n", Status); 01834 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01835 CompletionStatus = FALSE; 01836 } 01837 01838 ASSERT(NT_SUCCESS(Status)); 01839 01840 01841 // 01842 // Query with too little buffer 01843 // (This relies upon the ReturnLength returned from previous call) 01844 // 01845 01846 DbgPrint("Se: Query groups with too small buffer ... "); 01847 01848 Status = NtQueryInformationToken( 01849 TokenWithGroups, // Handle 01850 TokenGroups, // TokenInformationClass 01851 GroupIds, // TokenInformation 01852 ReturnLength-1, // TokenInformationLength 01853 &ReturnLength // ReturnLength 01854 ); 01855 #ifdef TOKEN_DEBUG 01856 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01857 #endif //TOKEN_DEBUG 01858 01859 if (Status == STATUS_BUFFER_TOO_SMALL) { 01860 DbgPrint("Succeeded.\n"); 01861 } else { 01862 DbgPrint("********** Failed ************\n"); 01863 DbgPrint("Status is: 0x%lx \n", Status); 01864 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01865 CompletionStatus = FALSE; 01866 } 01867 01868 ASSERT(!NT_SUCCESS(Status)); 01869 01870 // 01871 // Query groups with zero length buffer 01872 // 01873 01874 DbgPrint("Se: Query restgroups with zero length buffer ... "); 01875 Status = NtQueryInformationToken( 01876 TokenWithRestrictedGroups,// Handle 01877 TokenGroups, // TokenInformationClass 01878 GroupIds, // TokenInformation 01879 0, // TokenInformationLength 01880 &ReturnLength // ReturnLength 01881 ); 01882 #ifdef TOKEN_DEBUG 01883 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01884 #endif //TOKEN_DEBUG 01885 01886 if (Status == STATUS_BUFFER_TOO_SMALL) { 01887 DbgPrint("Succeeded.\n"); 01888 } else { 01889 DbgPrint("********** Failed ************\n"); 01890 DbgPrint("Status is: 0x%lx \n", Status); 01891 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01892 CompletionStatus = FALSE; 01893 } 01894 01895 ASSERT(!NT_SUCCESS(Status)); 01896 01897 01898 01899 01900 GroupIds = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 01901 ReturnLength 01902 ); 01903 01904 // 01905 // Query Group SIDs 01906 // (This relies upon the ReturnLength returned from previous call) 01907 // 01908 01909 DbgPrint("Se: Query rest groups ... "); 01910 01911 Status = NtQueryInformationToken( 01912 TokenWithRestrictedGroups,// Handle 01913 TokenGroups, // TokenInformationClass 01914 GroupIds, // TokenInformation 01915 ReturnLength, // TokenInformationLength 01916 &ReturnLength // ReturnLength 01917 ); 01918 #ifdef TOKEN_DEBUG 01919 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 01920 #endif //TOKEN_DEBUG 01921 01922 if (NT_SUCCESS(Status)) { 01923 01924 // 01925 // Check returned value 01926 // Group count = 4 01927 // SID 0 = Flintstone 01928 // SID 1 = ChildSid 01929 // SID 2 = NeandertholSid 01930 // SID 3 = WorldSid 01931 // 01932 01933 ValuesCompare = TRUE; 01934 01935 if (GroupIds->GroupCount != GROUP_COUNT) { 01936 ValuesCompare = FALSE; 01937 } 01938 01939 if ( (!RtlEqualSid((GroupIds->Groups[FLINTSTONE_INDEX].Sid), 01940 FlintstoneSid)) || 01941 (GroupIds->Groups[FLINTSTONE_INDEX].Attributes != 01942 ((OwnerGroupAttributes & ~(SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT)) | SE_GROUP_USE_FOR_DENY_ONLY) ) ) { 01943 ValuesCompare = FALSE; 01944 } 01945 01946 if ( (!RtlEqualSid((GroupIds->Groups[CHILD_INDEX].Sid), ChildSid)) || 01947 (GroupIds->Groups[CHILD_INDEX].Attributes != 01948 ((OptionalGroupAttributes & ~(SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT)) | SE_GROUP_USE_FOR_DENY_ONLY)) ) { 01949 ValuesCompare = FALSE; 01950 } 01951 01952 if ( (!RtlEqualSid((GroupIds->Groups[NEANDERTHOL_INDEX].Sid), 01953 NeandertholSid)) || 01954 (GroupIds->Groups[NEANDERTHOL_INDEX].Attributes != 01955 OptionalGroupAttributes) ) { 01956 ValuesCompare = FALSE; 01957 } 01958 01959 if ( (!RtlEqualSid((GroupIds->Groups[WORLD_INDEX].Sid), WorldSid)) || 01960 (GroupIds->Groups[WORLD_INDEX].Attributes != NormalGroupAttributes) ) { 01961 ValuesCompare = FALSE; 01962 } 01963 01964 01965 if ( ValuesCompare ) { 01966 DbgPrint("Succeeded.\n"); 01967 } else { 01968 01969 DbgPrint("********** Failed ************\n"); 01970 DbgPrint("Unexpected value returned by query.\n"); 01971 DbgPrint("Status is: 0x%lx \n", Status); 01972 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01973 DbgPrint("Returned group count is: 0x%lx \n", GroupIds->GroupCount); 01974 CompletionStatus = FALSE; 01975 } 01976 } else { 01977 DbgPrint("********** Failed ************\n"); 01978 DbgPrint("Status is: 0x%lx \n", Status); 01979 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 01980 CompletionStatus = FALSE; 01981 } 01982 01983 ASSERT(NT_SUCCESS(Status)); 01984 01985 01986 01988 // // 01989 // Query RestrictedSids // 01990 // // 01992 01993 // 01994 // Query groups with zero length buffer 01995 // 01996 01997 DbgPrint("Se: Query null restricted with zero length buffer ... "); 01998 01999 Status = NtQueryInformationToken( 02000 TokenWithGroups, // Handle 02001 TokenRestrictedSids, // TokenInformationClass 02002 RestrictedSids, // TokenInformation 02003 0, // TokenInformationLength 02004 &ReturnLength // ReturnLength 02005 ); 02006 #ifdef TOKEN_DEBUG 02007 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02008 #endif //TOKEN_DEBUG 02009 02010 if (Status == STATUS_BUFFER_TOO_SMALL) { 02011 DbgPrint("Succeeded.\n"); 02012 } else { 02013 DbgPrint("********** Failed ************\n"); 02014 DbgPrint("Status is: 0x%lx \n", Status); 02015 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02016 CompletionStatus = FALSE; 02017 } 02018 02019 ASSERT(!NT_SUCCESS(Status)); 02020 02021 // 02022 // Query groups with zero length buffer 02023 // 02024 02025 DbgPrint("Se: Query restricted sids with zero length buffer ... "); 02026 02027 Status = NtQueryInformationToken( 02028 TokenWithRestrictedSids, // Handle 02029 TokenRestrictedSids, // TokenInformationClass 02030 RestrictedSids, // TokenInformation 02031 0, // TokenInformationLength 02032 &ReturnLength // ReturnLength 02033 ); 02034 #ifdef TOKEN_DEBUG 02035 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02036 #endif //TOKEN_DEBUG 02037 02038 if (Status == STATUS_BUFFER_TOO_SMALL) { 02039 DbgPrint("Succeeded.\n"); 02040 } else { 02041 DbgPrint("********** Failed ************\n"); 02042 DbgPrint("Status is: 0x%lx \n", Status); 02043 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02044 CompletionStatus = FALSE; 02045 } 02046 02047 ASSERT(!NT_SUCCESS(Status)); 02048 02049 02050 02051 02052 RestrictedSids = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 02053 ReturnLength 02054 ); 02055 02056 // 02057 // Query Group SIDs 02058 // (This relies upon the ReturnLength returned from previous call) 02059 // 02060 02061 DbgPrint("Se: Query restricted sids ... "); 02062 02063 Status = NtQueryInformationToken( 02064 TokenWithRestrictedSids, // Handle 02065 TokenRestrictedSids, // TokenInformationClass 02066 RestrictedSids, // TokenInformation 02067 ReturnLength, // TokenInformationLength 02068 &ReturnLength // ReturnLength 02069 ); 02070 #ifdef TOKEN_DEBUG 02071 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02072 #endif //TOKEN_DEBUG 02073 02074 02075 if (NT_SUCCESS(Status)) { 02076 02077 // 02078 // Check returned value 02079 // Group count = 2 02080 // SID 0 = Flintstone 02081 // SID 1 = ChildSid 02082 // 02083 02084 ValuesCompare = TRUE; 02085 02086 if (RestrictedSids->GroupCount != RESTRICTED_SID_COUNT) { 02087 ValuesCompare = FALSE; 02088 } 02089 02090 if ( (!RtlEqualSid((RestrictedSids->Groups[FLINTSTONE_INDEX].Sid), 02091 FlintstoneSid)) || 02092 (RestrictedSids->Groups[FLINTSTONE_INDEX].Attributes != 02093 (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)) ) { 02094 ValuesCompare = FALSE; 02095 } 02096 02097 if ( (!RtlEqualSid((RestrictedSids->Groups[CHILD_INDEX].Sid), ChildSid)) || 02098 (RestrictedSids->Groups[CHILD_INDEX].Attributes != 02099 (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)) ) { 02100 ValuesCompare = FALSE; 02101 } 02102 02103 02104 if ( ValuesCompare ) { 02105 DbgPrint("Succeeded.\n"); 02106 } else { 02107 DbgPrint("********** Failed ************\n"); 02108 DbgPrint("Unexpected value returned by query.\n"); 02109 DbgPrint("Status is: 0x%lx \n", Status); 02110 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02111 DbgPrint("Returned group count is: 0x%lx \n", RestrictedSids->GroupCount); 02112 CompletionStatus = FALSE; 02113 } 02114 } else { 02115 DbgPrint("********** Failed ************\n"); 02116 DbgPrint("Status is: 0x%lx \n", Status); 02117 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02118 CompletionStatus = FALSE; 02119 } 02120 02121 ASSERT(NT_SUCCESS(Status)); 02122 02123 // 02124 // Query restricted sids with zero length buffer 02125 // 02126 02127 DbgPrint("Se: Query more restricted sids with zero length buffer ... "); 02128 02129 Status = NtQueryInformationToken( 02130 TokenWithMoreRestrictedSids, // Handle 02131 TokenRestrictedSids, // TokenInformationClass 02132 RestrictedSids, // TokenInformation 02133 0, // TokenInformationLength 02134 &ReturnLength // ReturnLength 02135 ); 02136 #ifdef TOKEN_DEBUG 02137 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02138 #endif //TOKEN_DEBUG 02139 02140 if (Status == STATUS_BUFFER_TOO_SMALL) { 02141 DbgPrint("Succeeded.\n"); 02142 } else { 02143 DbgPrint("********** Failed ************\n"); 02144 DbgPrint("Status is: 0x%lx \n", Status); 02145 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02146 CompletionStatus = FALSE; 02147 } 02148 02149 ASSERT(!NT_SUCCESS(Status)); 02150 02151 02152 02153 02154 RestrictedSids = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 02155 ReturnLength 02156 ); 02157 02158 // 02159 // Query Group SIDs 02160 // (This relies upon the ReturnLength returned from previous call) 02161 // 02162 02163 DbgPrint("Se: Query more restricted sids ... "); 02164 02165 Status = NtQueryInformationToken( 02166 TokenWithMoreRestrictedSids, // Handle 02167 TokenRestrictedSids, // TokenInformationClass 02168 RestrictedSids, // TokenInformation 02169 ReturnLength, // TokenInformationLength 02170 &ReturnLength // ReturnLength 02171 ); 02172 #ifdef TOKEN_DEBUG 02173 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02174 #endif //TOKEN_DEBUG 02175 02176 02177 if (NT_SUCCESS(Status)) { 02178 02179 // 02180 // Check returned value 02181 // Group count = 2 02182 // SID 0 = Flintstone 02183 // SID 1 = ChildSid 02184 // SID 2 = Neaderthol 02185 // SID 3 = World 02186 // 02187 02188 ValuesCompare = TRUE; 02189 02190 if (RestrictedSids->GroupCount != GROUP_COUNT) { 02191 ValuesCompare = FALSE; 02192 } 02193 02194 if ( (!RtlEqualSid((RestrictedSids->Groups[FLINTSTONE_INDEX].Sid), 02195 FlintstoneSid)) || 02196 (RestrictedSids->Groups[FLINTSTONE_INDEX].Attributes != 02197 (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)) ) { 02198 ValuesCompare = FALSE; 02199 } 02200 02201 if ( (!RtlEqualSid((RestrictedSids->Groups[CHILD_INDEX].Sid), ChildSid)) || 02202 (RestrictedSids->Groups[CHILD_INDEX].Attributes != 02203 (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)) ) { 02204 ValuesCompare = FALSE; 02205 } 02206 02207 02208 if ( (!RtlEqualSid((RestrictedSids->Groups[NEANDERTHOL_INDEX].Sid), 02209 NeandertholSid)) || 02210 (RestrictedSids->Groups[NEANDERTHOL_INDEX].Attributes != 02211 (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)) ) { 02212 ValuesCompare = FALSE; 02213 } 02214 02215 if ( (!RtlEqualSid((RestrictedSids->Groups[WORLD_INDEX].Sid), WorldSid)) || 02216 (RestrictedSids->Groups[WORLD_INDEX].Attributes != 02217 (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)) ) { 02218 ValuesCompare = FALSE; 02219 } 02220 02221 02222 02223 if ( ValuesCompare ) { 02224 DbgPrint("Succeeded.\n"); 02225 } else { 02226 DbgPrint("********** Failed ************\n"); 02227 DbgPrint("Unexpected value returned by query.\n"); 02228 DbgPrint("Status is: 0x%lx \n", Status); 02229 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02230 DbgPrint("Returned group count is: 0x%lx \n", RestrictedSids->GroupCount); 02231 CompletionStatus = FALSE; 02232 } 02233 } else { 02234 DbgPrint("********** Failed ************\n"); 02235 DbgPrint("Status is: 0x%lx \n", Status); 02236 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02237 CompletionStatus = FALSE; 02238 } 02239 02240 ASSERT(NT_SUCCESS(Status)); 02241 02242 02243 // 02244 // Query with too little buffer 02245 // (This relies upon the ReturnLength returned from previous call) 02246 // 02247 02248 DbgPrint("Se: Query groups with too small buffer ... "); 02249 02250 Status = NtQueryInformationToken( 02251 TokenWithGroups, // Handle 02252 TokenGroups, // TokenInformationClass 02253 GroupIds, // TokenInformation 02254 ReturnLength-1, // TokenInformationLength 02255 &ReturnLength // ReturnLength 02256 ); 02257 #ifdef TOKEN_DEBUG 02258 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02259 #endif //TOKEN_DEBUG 02260 02261 if (Status == STATUS_BUFFER_TOO_SMALL) { 02262 DbgPrint("Succeeded.\n"); 02263 } else { 02264 DbgPrint("********** Failed ************\n"); 02265 DbgPrint("Status is: 0x%lx \n", Status); 02266 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02267 CompletionStatus = FALSE; 02268 } 02269 02270 ASSERT(!NT_SUCCESS(Status)); 02271 02272 02274 // // 02275 // Query Privileges // 02276 // // 02278 02279 02280 // 02281 // Query groups with zero length buffer 02282 // 02283 02284 DbgPrint("Se: Query privileges with zero length buffer ... "); 02285 02286 Status = NtQueryInformationToken( 02287 TokenWithPrivileges, // Handle 02288 TokenPrivileges, // TokenInformationClass 02289 NULL, // TokenInformation 02290 0, // TokenInformationLength 02291 &ReturnLength // ReturnLength 02292 ); 02293 #ifdef TOKEN_DEBUG 02294 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02295 #endif //TOKEN_DEBUG 02296 02297 if (Status == STATUS_BUFFER_TOO_SMALL) { 02298 DbgPrint("Succeeded.\n"); 02299 } else { 02300 DbgPrint("********** Failed ************\n"); 02301 DbgPrint("Status is: 0x%lx \n", Status); 02302 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02303 CompletionStatus = FALSE; 02304 } 02305 02306 ASSERT(!NT_SUCCESS(Status)); 02307 02308 02309 02310 02311 Privileges = (PTOKEN_PRIVILEGES)TstAllocatePool( PagedPool, 02312 ReturnLength 02313 ); 02314 02315 // 02316 // Query privileges 02317 // (This relies upon the ReturnLength returned from previous call) 02318 // 02319 02320 DbgPrint("Se: Query privileges ... "); 02321 02322 Status = NtQueryInformationToken( 02323 TokenWithPrivileges, // Handle 02324 TokenPrivileges, // TokenInformationClass 02325 Privileges, // TokenInformation 02326 ReturnLength, // TokenInformationLength 02327 &ReturnLength // ReturnLength 02328 ); 02329 #ifdef TOKEN_DEBUG 02330 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02331 #endif //TOKEN_DEBUG 02332 02333 if (NT_SUCCESS(Status)) { 02334 02335 // 02336 // Check returned value 02337 // Privilege count = PRIVILEGE_COUNT 02338 // Privilege UNSOLICITED_INDEX = UnsolicitedInputPrivilege 02339 // Privilege SECURITY_INDEX = SecurityPrivilege 02340 // Privilege ASSIGN_PRIMARY_INDEX = AssignPrimaryPrivilege 02341 // 02342 02343 ValuesCompare = TRUE; 02344 02345 if (Privileges->PrivilegeCount != PRIVILEGE_COUNT) { 02346 ValuesCompare = FALSE; 02347 } 02348 02349 if ( !RtlEqualLuid(&Privileges->Privileges[UNSOLICITED_INDEX].Luid, 02350 &UnsolicitedInputPrivilege) || 02351 (Privileges->Privileges[UNSOLICITED_INDEX].Attributes != 0) ) { 02352 ValuesCompare = FALSE; 02353 } 02354 02355 if ( !RtlEqualLuid(&Privileges->Privileges[SECURITY_INDEX].Luid, 02356 &SecurityPrivilege) || 02357 (Privileges->Privileges[SECURITY_INDEX].Attributes != 0) ) { 02358 ValuesCompare = FALSE; 02359 } 02360 02361 if ( !RtlEqualLuid(&Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid, 02362 &AssignPrimaryTokenPrivilege) || 02363 (Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes != SE_PRIVILEGE_ENABLED) ) { 02364 ValuesCompare = FALSE; 02365 } 02366 02367 02368 if ( ValuesCompare ) { 02369 DbgPrint("Succeeded.\n"); 02370 } else { 02371 DbgPrint("********** Failed ************\n"); 02372 DbgPrint("Unexpected value returned by query.\n"); 02373 DbgPrint("Status is: 0x%lx \n", Status); 02374 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02375 CompletionStatus = FALSE; 02376 } 02377 } else { 02378 DbgPrint("********** Failed ************\n"); 02379 DbgPrint("Status is: 0x%lx \n", Status); 02380 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02381 CompletionStatus = FALSE; 02382 } 02383 02384 ASSERT(NT_SUCCESS(Status)); 02385 02386 02387 // 02388 // Query with too little buffer 02389 // (This relies upon the ReturnLength returned from previous call) 02390 // 02391 02392 DbgPrint("Se: Query privileges with too small buffer ... "); 02393 02394 Status = NtQueryInformationToken( 02395 TokenWithPrivileges, // Handle 02396 TokenPrivileges, // TokenInformationClass 02397 Privileges, // TokenInformation 02398 ReturnLength-1, // TokenInformationLength 02399 &ReturnLength // ReturnLength 02400 ); 02401 #ifdef TOKEN_DEBUG 02402 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02403 #endif //TOKEN_DEBUG 02404 02405 if (Status == STATUS_BUFFER_TOO_SMALL) { 02406 DbgPrint("Succeeded.\n"); 02407 } else { 02408 DbgPrint("********** Failed ************\n"); 02409 DbgPrint("Status is: 0x%lx \n", Status); 02410 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02411 CompletionStatus = FALSE; 02412 } 02413 02414 ASSERT(!NT_SUCCESS(Status)); 02415 02416 // 02417 // Query groups with zero length buffer 02418 // 02419 02420 DbgPrint("Se: Query rest privileges with zero length buffer ... "); 02421 02422 ReturnLength = 0; 02423 Status = NtQueryInformationToken( 02424 TokenWithRestrictedPrivileges, // Handle 02425 TokenPrivileges, // TokenInformationClass 02426 NULL, // TokenInformation 02427 0, // TokenInformationLength 02428 &ReturnLength // ReturnLength 02429 ); 02430 #ifdef TOKEN_DEBUG 02431 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02432 #endif //TOKEN_DEBUG 02433 02434 if (Status == STATUS_BUFFER_TOO_SMALL) { 02435 DbgPrint("Succeeded.\n"); 02436 } else { 02437 DbgPrint("********** Failed ************\n"); 02438 DbgPrint("Status is: 0x%lx \n", Status); 02439 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02440 CompletionStatus = FALSE; 02441 } 02442 02443 ASSERT(!NT_SUCCESS(Status)); 02444 02445 02446 02447 02448 Privileges = (PTOKEN_PRIVILEGES)TstAllocatePool( PagedPool, 02449 ReturnLength 02450 ); 02451 02452 // 02453 // Query privileges 02454 // (This relies upon the ReturnLength returned from previous call) 02455 // 02456 02457 DbgPrint("Se: Query rest privileges ... "); 02458 02459 Status = NtQueryInformationToken( 02460 TokenWithRestrictedPrivileges, // Handle 02461 TokenPrivileges, // TokenInformationClass 02462 Privileges, // TokenInformation 02463 ReturnLength, // TokenInformationLength 02464 &ReturnLength // ReturnLength 02465 ); 02466 #ifdef TOKEN_DEBUG 02467 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02468 #endif //TOKEN_DEBUG 02469 02470 if (NT_SUCCESS(Status)) { 02471 02472 // 02473 // Check returned value 02474 // Privilege count = PRIVILEGE_COUNT -2 02475 // Privilege ASSIGN_PRIMARY_INDEX = AssignPrimaryPrivilege 02476 // 02477 02478 ValuesCompare = TRUE; 02479 02480 if (Privileges->PrivilegeCount != PRIVILEGE_COUNT - 2) { 02481 ValuesCompare = FALSE; 02482 } 02483 02484 02485 if ( !RtlEqualLuid(&Privileges->Privileges[0].Luid, 02486 &AssignPrimaryTokenPrivilege) || 02487 (Privileges->Privileges[0].Attributes != SE_PRIVILEGE_ENABLED) ) { 02488 ValuesCompare = FALSE; 02489 } 02490 02491 02492 if ( ValuesCompare ) { 02493 DbgPrint("Succeeded.\n"); 02494 } else { 02495 DbgPrint("********** Failed ************\n"); 02496 DbgPrint("Unexpected value returned by query.\n"); 02497 DbgPrint("Status is: 0x%lx \n", Status); 02498 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02499 CompletionStatus = FALSE; 02500 } 02501 } else { 02502 DbgPrint("********** Failed ************\n"); 02503 DbgPrint("Status is: 0x%lx \n", Status); 02504 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02505 CompletionStatus = FALSE; 02506 } 02507 02508 ASSERT(NT_SUCCESS(Status)); 02509 02510 02512 // // 02513 // Query Owner // 02514 // // 02516 02517 // 02518 // Query Owner of simple token with zero length buffer 02519 // 02520 02521 DbgPrint("Se: Query Owner of simple token with zero length buffer... "); 02522 02523 Status = NtQueryInformationToken( 02524 SimpleToken, // Handle 02525 TokenOwner, // TokenInformationClass 02526 Owner, // TokenInformation 02527 0, // TokenInformationLength 02528 &ReturnLength // ReturnLength 02529 ); 02530 #ifdef TOKEN_DEBUG 02531 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02532 #endif //TOKEN_DEBUG 02533 02534 if (Status == STATUS_BUFFER_TOO_SMALL) { 02535 DbgPrint("Succeeded.\n"); 02536 } else { 02537 DbgPrint("********** Failed ************\n"); 02538 DbgPrint("Status is: 0x%lx \n", Status); 02539 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02540 CompletionStatus = FALSE; 02541 } 02542 02543 ASSERT(!NT_SUCCESS(Status)); 02544 02545 02546 02547 Owner = (PTOKEN_OWNER)TstAllocatePool( PagedPool, 02548 ReturnLength 02549 ); 02550 02551 // 02552 // Query Owner SID 02553 // (This relies upon the ReturnLength returned from previous call) 02554 // 02555 02556 DbgPrint("Se: Query owner of simple token ... "); 02557 02558 Status = NtQueryInformationToken( 02559 SimpleToken, // Handle 02560 TokenOwner, // TokenInformationClass 02561 Owner, // TokenInformation 02562 ReturnLength, // TokenInformationLength 02563 &ReturnLength // ReturnLength 02564 ); 02565 #ifdef TOKEN_DEBUG 02566 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02567 #endif //TOKEN_DEBUG 02568 02569 if (NT_SUCCESS(Status)) { 02570 02571 // 02572 // Check returned value 02573 // 02574 02575 if (RtlEqualSid((Owner->Owner), PebblesSid) ) { 02576 DbgPrint("Succeeded.\n"); 02577 } else { 02578 DbgPrint("********** Failed ************\n"); 02579 DbgPrint("Unexpected value returned by query.\n"); 02580 DbgPrint("Status is: 0x%lx \n", Status); 02581 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02582 CompletionStatus = FALSE; 02583 } 02584 } else { 02585 DbgPrint("********** Failed ************\n"); 02586 DbgPrint("Status is: 0x%lx \n", Status); 02587 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02588 CompletionStatus = FALSE; 02589 } 02590 02591 ASSERT(NT_SUCCESS(Status)); 02592 02593 02594 // 02595 // Query owner of simple token with too little buffer 02596 // (This relies upon the ReturnLength returned from previous call) 02597 // 02598 02599 DbgPrint("Se: Query owner of simple token with too small buffer ... "); 02600 02601 Status = NtQueryInformationToken( 02602 SimpleToken, // Handle 02603 TokenOwner, // TokenInformationClass 02604 Owner, // TokenInformation 02605 ReturnLength-1, // TokenInformationLength 02606 &ReturnLength // ReturnLength 02607 ); 02608 #ifdef TOKEN_DEBUG 02609 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02610 #endif //TOKEN_DEBUG 02611 02612 if (Status == STATUS_BUFFER_TOO_SMALL) { 02613 DbgPrint("Succeeded.\n"); 02614 } else { 02615 DbgPrint("********** Failed ************\n"); 02616 DbgPrint("Status is: 0x%lx \n", Status); 02617 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02618 CompletionStatus = FALSE; 02619 } 02620 02621 ASSERT(!NT_SUCCESS(Status)); 02622 02623 02624 // 02625 // Query default owner of token with zero length buffer 02626 // 02627 02628 DbgPrint("Se: Query Default Owner of token with zero length buffer..."); 02629 02630 Status = NtQueryInformationToken( 02631 TokenWithDefaultOwner, // Handle 02632 TokenOwner, // TokenInformationClass 02633 Owner, // TokenInformation 02634 0, // TokenInformationLength 02635 &ReturnLength // ReturnLength 02636 ); 02637 #ifdef TOKEN_DEBUG 02638 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02639 #endif //TOKEN_DEBUG 02640 02641 if (Status == STATUS_BUFFER_TOO_SMALL) { 02642 DbgPrint("Succeeded.\n"); 02643 } else { 02644 DbgPrint("********** Failed ************\n"); 02645 DbgPrint("Status is: 0x%lx \n", Status); 02646 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02647 CompletionStatus = FALSE; 02648 } 02649 02650 ASSERT(!NT_SUCCESS(Status)); 02651 02652 02653 02654 02655 Owner = (PTOKEN_OWNER)TstAllocatePool( PagedPool, 02656 ReturnLength 02657 ); 02658 02659 // 02660 // Query default owner of token 02661 // (This relies upon the ReturnLength returned from previous call) 02662 // 02663 02664 DbgPrint("Se: Query default owner of token ... "); 02665 02666 Status = NtQueryInformationToken( 02667 TokenWithDefaultOwner, // Handle 02668 TokenOwner, // TokenInformationClass 02669 Owner, // TokenInformation 02670 ReturnLength, // TokenInformationLength 02671 &ReturnLength // ReturnLength 02672 ); 02673 #ifdef TOKEN_DEBUG 02674 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02675 #endif //TOKEN_DEBUG 02676 02677 if (NT_SUCCESS(Status)) { 02678 02679 // 02680 // Check returned value 02681 // 02682 02683 if (RtlEqualSid((Owner->Owner), FlintstoneSid) ) { 02684 DbgPrint("Succeeded.\n"); 02685 } else { 02686 DbgPrint("********** Failed ************\n"); 02687 DbgPrint("Unexpected value returned by query.\n"); 02688 DbgPrint("Status is: 0x%lx \n", Status); 02689 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02690 CompletionStatus = FALSE; 02691 } 02692 } else { 02693 DbgPrint("********** Failed ************\n"); 02694 DbgPrint("Status is: 0x%lx \n", Status); 02695 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02696 CompletionStatus = FALSE; 02697 } 02698 02699 ASSERT(NT_SUCCESS(Status)); 02700 02701 02702 // 02703 // Query default owner of token with too little buffer 02704 // (This relies upon the ReturnLength returned from previous call) 02705 // 02706 02707 DbgPrint("Se: Query default owner of token with too small buffer ... "); 02708 02709 Status = NtQueryInformationToken( 02710 TokenWithDefaultOwner, // Handle 02711 TokenOwner, // TokenInformationClass 02712 Owner, // TokenInformation 02713 ReturnLength-1, // TokenInformationLength 02714 &ReturnLength // ReturnLength 02715 ); 02716 #ifdef TOKEN_DEBUG 02717 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02718 #endif //TOKEN_DEBUG 02719 02720 if (Status == STATUS_BUFFER_TOO_SMALL) { 02721 DbgPrint("Succeeded.\n"); 02722 } else { 02723 DbgPrint("********** Failed ************\n"); 02724 DbgPrint("Status is: 0x%lx \n", Status); 02725 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02726 CompletionStatus = FALSE; 02727 } 02728 02729 ASSERT(!NT_SUCCESS(Status)); 02730 02731 02733 // // 02734 // Query Default Dacl // 02735 // // 02737 02738 // 02739 // Query default dacl with zero length buffer 02740 // 02741 02742 DbgPrint("Se: Query default DACL with zero length buffer ... "); 02743 02744 Status = NtQueryInformationToken( 02745 TokenWithDefaultDacl, // Handle 02746 TokenDefaultDacl, // TokenInformationClass 02747 DefaultDacl, // TokenInformation 02748 0, // TokenInformationLength 02749 &ReturnLength // ReturnLength 02750 ); 02751 #ifdef TOKEN_DEBUG 02752 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02753 #endif //TOKEN_DEBUG 02754 02755 if (Status == STATUS_BUFFER_TOO_SMALL) { 02756 DbgPrint("Succeeded.\n"); 02757 } else { 02758 DbgPrint("********** Failed ************\n"); 02759 DbgPrint("Status is: 0x%lx \n", Status); 02760 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02761 CompletionStatus = FALSE; 02762 } 02763 02764 ASSERT(!NT_SUCCESS(Status)); 02765 02766 02767 02768 02769 DefaultDacl = (PTOKEN_DEFAULT_DACL)TstAllocatePool( PagedPool, 02770 ReturnLength 02771 ); 02772 02773 // 02774 // Query default dacl 02775 // (This relies upon the ReturnLength returned from previous call) 02776 // 02777 02778 DbgPrint("Se: Query default dacl ... "); 02779 02780 Status = NtQueryInformationToken( 02781 TokenWithDefaultDacl, // Handle 02782 TokenDefaultDacl, // TokenInformationClass 02783 DefaultDacl, // TokenInformation 02784 ReturnLength, // TokenInformationLength 02785 &ReturnLength // ReturnLength 02786 ); 02787 #ifdef TOKEN_DEBUG 02788 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02789 #endif //TOKEN_DEBUG 02790 02791 if (NT_SUCCESS(Status)) { 02792 02793 // 02794 // Check returned value 02795 // 02796 02797 if (RtlValidAcl(DefaultDacl->DefaultDacl)) { 02798 02799 if (DefaultDacl->DefaultDacl->AceCount == 0) { 02800 02801 DbgPrint("Succeeded.\n"); 02802 } else { 02803 DbgPrint("********** Failed ************\n"); 02804 DbgPrint("Unexpected value returned by query.\n"); 02805 DbgPrint("Status is: 0x%lx \n", Status); 02806 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02807 CompletionStatus = FALSE; 02808 } 02809 } else { 02810 DbgPrint("********** Failed ************\n"); 02811 DbgPrint("Unexpected value returned by query.\n"); 02812 DbgPrint("Status is: 0x%lx \n", Status); 02813 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02814 CompletionStatus = FALSE; 02815 } 02816 } else { 02817 DbgPrint("********** Failed ************\n"); 02818 DbgPrint("Status is: 0x%lx \n", Status); 02819 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02820 CompletionStatus = FALSE; 02821 } 02822 02823 ASSERT(NT_SUCCESS(Status)); 02824 02825 02826 // 02827 // Query with too little buffer 02828 // (This relies upon the ReturnLength returned from previous call) 02829 // 02830 02831 DbgPrint("Se: Query default Dacl with too small buffer ... "); 02832 02833 Status = NtQueryInformationToken( 02834 TokenWithDefaultDacl, // Handle 02835 TokenDefaultDacl, // TokenInformationClass 02836 DefaultDacl, // TokenInformation 02837 ReturnLength-1, // TokenInformationLength 02838 &ReturnLength // ReturnLength 02839 ); 02840 #ifdef TOKEN_DEBUG 02841 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02842 #endif //TOKEN_DEBUG 02843 02844 if (Status == STATUS_BUFFER_TOO_SMALL) { 02845 DbgPrint("Succeeded.\n"); 02846 } else { 02847 DbgPrint("********** Failed ************\n"); 02848 DbgPrint("Status is: 0x%lx \n", Status); 02849 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02850 CompletionStatus = FALSE; 02851 } 02852 02853 ASSERT(!NT_SUCCESS(Status)); 02854 02855 02856 // 02857 // Query token with no default dacl 02858 // 02859 02860 DbgPrint("Se: Query default dacl from token with none ... "); 02861 02862 Status = NtQueryInformationToken( 02863 SimpleToken, // Handle 02864 TokenDefaultDacl, // TokenInformationClass 02865 DefaultDacl, // TokenInformation 02866 sizeof(TOKEN_DEFAULT_DACL), // TokenInformationLength 02867 &ReturnLength // ReturnLength 02868 ); 02869 #ifdef TOKEN_DEBUG 02870 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02871 #endif //TOKEN_DEBUG 02872 02873 if (NT_SUCCESS(Status)) { 02874 DbgPrint("Succeeded.\n"); 02875 } else { 02876 DbgPrint("********** Failed ************\n"); 02877 DbgPrint("Status is: 0x%lx \n", Status); 02878 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02879 CompletionStatus = FALSE; 02880 } 02881 02882 ASSERT(NT_SUCCESS(Status)); 02883 02884 02886 // // 02887 // Query Token Source // 02888 // // 02890 02891 // 02892 // Query Token Source with zero length buffer 02893 // 02894 02895 DbgPrint("Se: Query Token Source with zero length buffer ... "); 02896 02897 Status = NtQueryInformationToken( 02898 TokenWithPrivileges, // Handle 02899 TokenSource, // TokenInformationClass 02900 &QueriedSource, // TokenInformation 02901 0, // TokenInformationLength 02902 &ReturnLength // ReturnLength 02903 ); 02904 #ifdef TOKEN_DEBUG 02905 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02906 #endif //TOKEN_DEBUG 02907 02908 if (Status == STATUS_BUFFER_TOO_SMALL) { 02909 if (ReturnLength == sizeof(TOKEN_SOURCE)) { 02910 DbgPrint("Succeeded.\n"); 02911 } else { 02912 DbgPrint("********** Failed ************\n"); 02913 DbgPrint("Status is: 0x%lx \n", Status); 02914 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02915 DbgPrint("TOKEN_SOURCE data size is 0x%lx \n", sizeof(TOKEN_SOURCE)); 02916 CompletionStatus = FALSE; 02917 } 02918 } else { 02919 DbgPrint("********** Failed ************\n"); 02920 DbgPrint("Status is: 0x%lx \n", Status); 02921 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02922 CompletionStatus = FALSE; 02923 } 02924 02925 ASSERT(!NT_SUCCESS(Status)); 02926 02927 02928 02929 // 02930 // Query token source 02931 // 02932 02933 DbgPrint("Se: Query token source ... "); 02934 02935 Status = NtQueryInformationToken( 02936 TokenWithPrivileges, // Handle 02937 TokenSource, // TokenInformationClass 02938 &QueriedSource, // TokenInformation 02939 sizeof(TOKEN_SOURCE), // TokenInformationLength 02940 &ReturnLength // ReturnLength 02941 ); 02942 #ifdef TOKEN_DEBUG 02943 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 02944 #endif //TOKEN_DEBUG 02945 02946 if (NT_SUCCESS(Status)) { 02947 02948 // 02949 // Check returned value against TestSource 02950 // 02951 02952 ValuesCompare = TRUE; 02953 02954 if ( (QueriedSource.SourceName[0] != TestSource.SourceName[0]) || 02955 (QueriedSource.SourceName[1] != TestSource.SourceName[1]) || 02956 (QueriedSource.SourceName[2] != TestSource.SourceName[2]) || 02957 (QueriedSource.SourceName[3] != TestSource.SourceName[3]) || 02958 (QueriedSource.SourceName[4] != TestSource.SourceName[4]) || 02959 (QueriedSource.SourceName[5] != TestSource.SourceName[5]) || 02960 (QueriedSource.SourceName[6] != TestSource.SourceName[6]) || 02961 (QueriedSource.SourceName[7] != TestSource.SourceName[7]) ) { 02962 02963 ValuesCompare = FALSE; 02964 02965 } 02966 02967 if ( !RtlEqualLuid(&QueriedSource.SourceIdentifier, 02968 &TestSource.SourceIdentifier) ) { 02969 02970 ValuesCompare = FALSE; 02971 02972 } 02973 02974 02975 if ( ValuesCompare ) { 02976 DbgPrint("Succeeded.\n"); 02977 } else { 02978 DbgPrint("********** Failed ************\n"); 02979 DbgPrint("Unexpected value returned by query.\n"); 02980 DbgPrint("Status is: 0x%lx \n", Status); 02981 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02982 CompletionStatus = FALSE; 02983 } 02984 } else { 02985 DbgPrint("********** Failed ************\n"); 02986 DbgPrint("Status is: 0x%lx \n", Status); 02987 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 02988 CompletionStatus = FALSE; 02989 } 02990 02991 ASSERT(NT_SUCCESS(Status)); 02992 02993 02994 // 02995 // Query with too little buffer 02996 // (This relies upon the ReturnLength returned from previous call) 02997 // 02998 02999 DbgPrint("Se: Query token source with too small buffer ... "); 03000 03001 Status = NtQueryInformationToken( 03002 TokenWithPrivileges, // Handle 03003 TokenSource, // TokenInformationClass 03004 &QueriedSource, // TokenInformation 03005 ReturnLength - 1, // TokenInformationLength 03006 &ReturnLength // ReturnLength 03007 ); 03008 #ifdef TOKEN_DEBUG 03009 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03010 #endif //TOKEN_DEBUG 03011 03012 if (Status == STATUS_BUFFER_TOO_SMALL) { 03013 DbgPrint("Succeeded.\n"); 03014 } else { 03015 DbgPrint("********** Failed ************\n"); 03016 DbgPrint("Status is: 0x%lx \n", Status); 03017 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03018 CompletionStatus = FALSE; 03019 } 03020 03021 ASSERT(!NT_SUCCESS(Status)); 03022 03023 03025 // // 03026 // Query Token Type // 03027 // // 03029 03030 // 03031 // Query Token type with zero length buffer 03032 // 03033 03034 DbgPrint("Se: Query Token type with zero length buffer ... "); 03035 03036 Status = NtQueryInformationToken( 03037 TokenWithPrivileges, // Handle 03038 TokenType, // TokenInformationClass 03039 &QueriedType, // TokenInformation 03040 0, // TokenInformationLength 03041 &ReturnLength // ReturnLength 03042 ); 03043 #ifdef TOKEN_DEBUG 03044 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03045 #endif //TOKEN_DEBUG 03046 03047 if (Status == STATUS_BUFFER_TOO_SMALL) { 03048 if (ReturnLength == sizeof(TOKEN_TYPE)) { 03049 DbgPrint("Succeeded.\n"); 03050 } else { 03051 DbgPrint("********** Failed ************\n"); 03052 DbgPrint("Status is: 0x%lx \n", Status); 03053 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03054 DbgPrint("TOKEN_TYPE data size is 0x%lx \n", sizeof(TOKEN_TYPE)); 03055 CompletionStatus = FALSE; 03056 } 03057 } else { 03058 DbgPrint("********** Failed ************\n"); 03059 DbgPrint("Status is: 0x%lx \n", Status); 03060 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03061 CompletionStatus = FALSE; 03062 } 03063 03064 ASSERT(!NT_SUCCESS(Status)); 03065 03066 03067 03068 03069 // 03070 // Query token type 03071 // 03072 03073 DbgPrint("Se: Query token type ... "); 03074 03075 Status = NtQueryInformationToken( 03076 TokenWithPrivileges, // Handle 03077 TokenType, // TokenInformationClass 03078 &QueriedType, // TokenInformation 03079 sizeof(TOKEN_TYPE), // TokenInformationLength 03080 &ReturnLength // ReturnLength 03081 ); 03082 #ifdef TOKEN_DEBUG 03083 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03084 #endif //TOKEN_DEBUG 03085 03086 if (NT_SUCCESS(Status)) { 03087 03088 // 03089 // Check returned value against TestSource 03090 // 03091 03092 03093 if ( QueriedType == TokenPrimary ) { 03094 DbgPrint("Succeeded.\n"); 03095 } else { 03096 DbgPrint("********** Failed ************\n"); 03097 DbgPrint("Unexpected value returned by query.\n"); 03098 DbgPrint("Status is: 0x%lx \n", Status); 03099 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03100 DbgPrint("Returned token type is: 0x%lx \n", QueriedType); 03101 CompletionStatus = FALSE; 03102 } 03103 } else { 03104 DbgPrint("********** Failed ************\n"); 03105 DbgPrint("Status is: 0x%lx \n", Status); 03106 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03107 CompletionStatus = FALSE; 03108 } 03109 03110 ASSERT(NT_SUCCESS(Status)); 03111 03112 03113 // 03114 // Query with too little buffer 03115 // (This relies upon the ReturnLength returned from previous call) 03116 // 03117 03118 DbgPrint("Se: Query token type with too small buffer ... "); 03119 03120 Status = NtQueryInformationToken( 03121 TokenWithPrivileges, // Handle 03122 TokenType, // TokenInformationClass 03123 &QueriedType, // TokenInformation 03124 ReturnLength - 1, // TokenInformationLength 03125 &ReturnLength // ReturnLength 03126 ); 03127 #ifdef TOKEN_DEBUG 03128 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03129 #endif //TOKEN_DEBUG 03130 03131 if (Status == STATUS_BUFFER_TOO_SMALL) { 03132 DbgPrint("Succeeded.\n"); 03133 } else { 03134 DbgPrint("********** Failed ************\n"); 03135 DbgPrint("Status is: 0x%lx \n", Status); 03136 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03137 CompletionStatus = FALSE; 03138 } 03139 03140 ASSERT(!NT_SUCCESS(Status)); 03141 03142 03144 // // 03145 // Query Impersonation Level // 03146 // // 03148 03149 // 03150 // Query Impersonation Level of primary token 03151 // 03152 03153 DbgPrint("Se: Query Impersonation level of primary token ... "); 03154 03155 Status = NtQueryInformationToken( 03156 TokenWithPrivileges, // Handle 03157 TokenImpersonationLevel, // TokenInformationClass 03158 &QueriedImpersonationLevel, // TokenInformation 03159 sizeof(SECURITY_IMPERSONATION_LEVEL), // TokenInformationLength 03160 &ReturnLength // ReturnLength 03161 ); 03162 #ifdef TOKEN_DEBUG 03163 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03164 #endif //TOKEN_DEBUG 03165 03166 if (Status == STATUS_INVALID_INFO_CLASS) { 03167 DbgPrint("Succeeded.\n"); 03168 } else { 03169 DbgPrint("********** Failed ************\n"); 03170 DbgPrint("Status is: 0x%lx \n", Status); 03171 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03172 CompletionStatus = FALSE; 03173 } 03174 03175 ASSERT(Status == STATUS_INVALID_INFO_CLASS); 03176 03177 03179 // // 03180 // Query Token Statistics // 03181 // // 03183 03184 // 03185 // Query Token statistics with zero length buffer 03186 // 03187 03188 DbgPrint("Se: Query Token statistics with zero length buffer ... "); 03189 03190 Status = NtQueryInformationToken( 03191 TokenWithPrivileges, // Handle 03192 TokenStatistics, // TokenInformationClass 03193 &QueriedStatistics, // TokenInformation 03194 0, // TokenInformationLength 03195 &ReturnLength // ReturnLength 03196 ); 03197 #ifdef TOKEN_DEBUG 03198 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03199 #endif //TOKEN_DEBUG 03200 03201 if (Status == STATUS_BUFFER_TOO_SMALL) { 03202 if (ReturnLength == sizeof(TOKEN_STATISTICS)) { 03203 DbgPrint("Succeeded.\n"); 03204 } else { 03205 DbgPrint("********** Failed ************\n"); 03206 DbgPrint("Status is: 0x%lx \n", Status); 03207 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03208 DbgPrint("TOKEN_STATISTICS data size is 0x%lx \n", sizeof(TOKEN_STATISTICS)); 03209 CompletionStatus = FALSE; 03210 } 03211 } else { 03212 DbgPrint("********** Failed ************\n"); 03213 DbgPrint("Status is: 0x%lx \n", Status); 03214 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03215 CompletionStatus = FALSE; 03216 } 03217 03218 ASSERT(!NT_SUCCESS(Status)); 03219 03220 03221 03222 03223 // 03224 // Query token statistics 03225 // 03226 03227 DbgPrint("Se: Query token statistics ... "); 03228 03229 Status = NtQueryInformationToken( 03230 TokenWithPrivileges, // Handle 03231 TokenStatistics, // TokenInformationClass 03232 &QueriedStatistics, // TokenInformation 03233 sizeof(TOKEN_STATISTICS), // TokenInformationLength 03234 &ReturnLength // ReturnLength 03235 ); 03236 #ifdef TOKEN_DEBUG 03237 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03238 #endif //TOKEN_DEBUG 03239 03240 if (NT_SUCCESS(Status)) { 03241 03242 // 03243 // Check returned value against TestSource 03244 // 03245 03246 if ( ( QueriedStatistics.TokenType == TokenPrimary) && 03247 ( QueriedStatistics.GroupCount == 4 ) && 03248 ( QueriedStatistics.PrivilegeCount == PRIVILEGE_COUNT) ) { 03249 DbgPrint("Succeeded.\n"); 03250 } else { 03251 DbgPrint("********** Failed ************\n"); 03252 DbgPrint("Unexpected value returned by query.\n"); 03253 DbgPrint("Status is: 0x%lx \n", Status); 03254 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03255 DbgPrint("Returned token type is: 0x%lx \n", QueriedStatistics.TokenType); 03256 DbgPrint("Returned group count is: 0x%lx \n", QueriedStatistics.GroupCount); 03257 DbgPrint("Returned privilege count is: 0x%lx \n", QueriedStatistics.PrivilegeCount); 03258 CompletionStatus = FALSE; 03259 } 03260 } else { 03261 DbgPrint("********** Failed ************\n"); 03262 DbgPrint("Status is: 0x%lx \n", Status); 03263 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03264 CompletionStatus = FALSE; 03265 } 03266 03267 ASSERT(NT_SUCCESS(Status)); 03268 03269 03270 // 03271 // Query with too little buffer 03272 // (This relies upon the ReturnLength returned from previous call) 03273 // 03274 03275 DbgPrint("Se: Query token statistics with too small buffer ... "); 03276 03277 Status = NtQueryInformationToken( 03278 TokenWithPrivileges, // Handle 03279 TokenStatistics, // TokenInformationClass 03280 &QueriedStatistics, // TokenInformation 03281 ReturnLength - 1, // TokenInformationLength 03282 &ReturnLength // ReturnLength 03283 ); 03284 #ifdef TOKEN_DEBUG 03285 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03286 #endif //TOKEN_DEBUG 03287 03288 if (Status == STATUS_BUFFER_TOO_SMALL) { 03289 DbgPrint("Succeeded.\n"); 03290 } else { 03291 DbgPrint("********** Failed ************\n"); 03292 DbgPrint("Status is: 0x%lx \n", Status); 03293 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03294 CompletionStatus = FALSE; 03295 } 03296 03297 ASSERT(!NT_SUCCESS(Status)); 03298 03299 03300 03301 return CompletionStatus; 03302 } 03303 03305 // // 03306 // Set Token Test // 03307 // // 03309 03310 BOOLEAN 03311 TestTokenSet() 03312 { 03313 BOOLEAN CompletionStatus = TRUE; 03314 ULONG InformationLength; 03315 ULONG ReturnLength; 03316 03317 TOKEN_STATISTICS QueriedStatistics; 03318 03319 TOKEN_PRIMARY_GROUP AssignedPrimaryGroup; 03320 PTOKEN_PRIMARY_GROUP QueriedPrimaryGroup = NULL; 03321 03322 TOKEN_OWNER AssignedOwner; 03323 PTOKEN_OWNER QueriedOwner = NULL; 03324 03325 TOKEN_DEFAULT_DACL AssignedDefaultDacl; 03326 PTOKEN_DEFAULT_DACL QueriedDefaultDacl = NULL; 03327 03328 PSID TooBigSid; 03329 03330 SID_IDENTIFIER_AUTHORITY BedrockAuthority = BEDROCK_AUTHORITY; 03331 03332 DbgPrint("\n"); 03333 03334 03335 // 03336 // Set owner of a token to be an invalid group 03337 // 03338 03339 DbgPrint("Se: Set default owner to be an invalid group ... "); 03340 03341 AssignedOwner.Owner = NeandertholSid; 03342 InformationLength = (ULONG)sizeof(TOKEN_OWNER); 03343 03344 Status = NtSetInformationToken( 03345 TokenWithGroups, // Handle 03346 TokenOwner, // TokenInformationClass 03347 &AssignedOwner, // TokenInformation 03348 InformationLength // TokenInformationLength 03349 ); 03350 03351 if (Status == STATUS_INVALID_OWNER) { 03352 DbgPrint("Succeeded.\n"); 03353 } else { 03354 DbgPrint("********** Failed ************\n"); 03355 DbgPrint("Status is: 0x%lx \n", Status); 03356 DbgPrint("InformationLength is: 0x%lx \n", InformationLength); 03357 CompletionStatus = FALSE; 03358 } 03359 03360 ASSERT(Status == STATUS_INVALID_OWNER); 03361 03362 03363 // 03364 // Set owner of a token to be an ID not in the token 03365 // 03366 03367 DbgPrint("Se: Set default owner to be an ID not in the token ... "); 03368 03369 AssignedOwner.Owner = BarneySid; 03370 InformationLength = (ULONG)sizeof(TOKEN_OWNER); 03371 03372 Status = NtSetInformationToken( 03373 TokenWithGroups, // Handle 03374 TokenOwner, // TokenInformationClass 03375 &AssignedOwner, // TokenInformation 03376 InformationLength // TokenInformationLength 03377 ); 03378 03379 if (Status == STATUS_INVALID_OWNER) { 03380 DbgPrint("Succeeded.\n"); 03381 } else { 03382 DbgPrint("********** Failed ************\n"); 03383 DbgPrint("Status is: 0x%lx \n", Status); 03384 DbgPrint("InformationLength is: 0x%lx \n", InformationLength); 03385 CompletionStatus = FALSE; 03386 } 03387 03388 ASSERT(Status == STATUS_INVALID_OWNER); 03389 03390 03391 // 03392 // Set owner of a token to be a valid group 03393 // 03394 03395 DbgPrint("Se: Set default owner to be a valid group ... "); 03396 03397 AssignedOwner.Owner = FlintstoneSid; 03398 InformationLength = (ULONG)sizeof(TOKEN_OWNER); 03399 03400 Status = NtSetInformationToken( 03401 TokenWithGroups, // Handle 03402 TokenOwner, // TokenInformationClass 03403 &AssignedOwner, // TokenInformation 03404 InformationLength // TokenInformationLength 03405 ); 03406 03407 if (!NT_SUCCESS(Status)) { 03408 DbgPrint("********** Failed ************\n"); 03409 DbgPrint("Status is: 0x%lx \n", Status); 03410 DbgPrint("InformationLength is: 0x%lx \n", InformationLength); 03411 CompletionStatus = FALSE; 03412 } 03413 03414 ASSERT(NT_SUCCESS(Status)); 03415 03416 // 03417 // Query the Owner to see that it was set properly 03418 // 03419 03420 Status = NtQueryInformationToken( 03421 TokenWithGroups, // Handle 03422 TokenOwner, // TokenInformationClass 03423 QueriedOwner, // TokenInformation 03424 0, // TokenInformationLength 03425 &ReturnLength // ReturnLength 03426 ); 03427 #ifdef TOKEN_DEBUG 03428 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03429 #endif //TOKEN_DEBUG 03430 03431 if (Status != STATUS_BUFFER_TOO_SMALL) { 03432 DbgPrint("********** Failed Query of length ************\n"); 03433 DbgPrint("Status is: 0x%lx \n", Status); 03434 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03435 CompletionStatus = FALSE; 03436 } 03437 03438 ASSERT(!NT_SUCCESS(Status)); 03439 03440 QueriedOwner = (PTOKEN_OWNER)TstAllocatePool( PagedPool, 03441 ReturnLength 03442 ); 03443 03444 Status = NtQueryInformationToken( 03445 TokenWithGroups, // Handle 03446 TokenOwner, // TokenInformationClass 03447 QueriedOwner, // TokenInformation 03448 ReturnLength, // TokenInformationLength 03449 &ReturnLength // ReturnLength 03450 ); 03451 #ifdef TOKEN_DEBUG 03452 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03453 #endif //TOKEN_DEBUG 03454 03455 if (NT_SUCCESS(Status)) { 03456 03457 // 03458 // Check returned value 03459 // 03460 03461 if (RtlEqualSid((QueriedOwner->Owner), AssignedOwner.Owner) ) { 03462 DbgPrint("Succeeded.\n"); 03463 } else { 03464 DbgPrint("********** Failed Comparison ************\n"); 03465 DbgPrint("Unexpected value returned by query.\n"); 03466 DbgPrint("Status is: 0x%lx \n", Status); 03467 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03468 CompletionStatus = FALSE; 03469 } 03470 } else { 03471 DbgPrint("********** Failed Query Of Value ************\n"); 03472 DbgPrint("Status is: 0x%lx \n", Status); 03473 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03474 CompletionStatus = FALSE; 03475 } 03476 03477 ASSERT(NT_SUCCESS(Status)); 03478 03479 03480 // 03481 // Set Default Dacl 03482 03483 // 03484 // Get a buffer for use in all Default Dacl assignment tests. 03485 // This will be initialized to different sizes for each test. 03486 // 03487 03488 AssignedDefaultDacl.DefaultDacl = 03489 (PACL)TstAllocatePool( PagedPool, TOO_BIG_ACL_SIZE ); 03490 03491 03492 // 03493 // Assign a discretionary ACL to a token that doesn't yet have one 03494 // 03495 03496 DbgPrint("Se: Set original discretionary ACL in token ... "); 03497 03498 InformationLength = (ULONG)sizeof(TOKEN_DEFAULT_DACL); 03499 RtlCreateAcl( AssignedDefaultDacl.DefaultDacl, 200, ACL_REVISION ); 03500 03501 Status = NtQueryInformationToken( 03502 TokenWithGroups, // Handle 03503 TokenDefaultDacl, // TokenInformationClass 03504 &QueriedDefaultDacl, // TokenInformation 03505 0, // TokenInformationLength 03506 &ReturnLength // ReturnLength 03507 ); 03508 #ifdef TOKEN_DEBUG 03509 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03510 #endif //TOKEN_DEBUG 03511 03512 ASSERT(Status == STATUS_BUFFER_TOO_SMALL); 03513 03514 if (ReturnLength != sizeof(TOKEN_DEFAULT_DACL)) { 03515 03516 // 03517 // Wait a minute, this token has a default Dacl 03518 // 03519 03520 DbgPrint("******** Failed - token has default dacl *********\n"); 03521 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03522 CompletionStatus = FALSE; 03523 03524 } else { 03525 03526 Status = NtSetInformationToken( 03527 TokenWithGroups, // Handle 03528 TokenDefaultDacl, // TokenInformationClass 03529 &AssignedDefaultDacl, // TokenInformation 03530 InformationLength // TokenInformationLength 03531 ); 03532 03533 if (NT_SUCCESS(Status)) { 03534 DbgPrint("Succeeded.\n"); 03535 } else { 03536 DbgPrint("********** Failed ************\n"); 03537 DbgPrint("Status is: 0x%lx \n", Status); 03538 CompletionStatus = FALSE; 03539 } 03540 03541 } 03542 03543 ASSERT(NT_SUCCESS(Status)); 03544 03545 // 03546 // Replace a discretionary ACL in a token that already has one 03547 // Make it big to help with future "too big" tests... 03548 // 03549 03550 03551 // 03552 // find out how much space is available 03553 // 03554 03555 Status = NtQueryInformationToken( 03556 TokenWithGroups, // Handle 03557 TokenStatistics, // TokenInformationClass 03558 &QueriedStatistics, // TokenInformation 03559 (ULONG)sizeof(TOKEN_STATISTICS), // TokenInformationLength 03560 &ReturnLength // ReturnLength 03561 ); 03562 #ifdef TOKEN_DEBUG 03563 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03564 #endif //TOKEN_DEBUG 03565 03566 ASSERT(NT_SUCCESS(Status)); 03567 03568 Status = NtQueryInformationToken( 03569 TokenWithGroups, // Handle 03570 TokenDefaultDacl, // TokenInformationClass 03571 &QueriedDefaultDacl, // TokenInformation 03572 0, // TokenInformationLength 03573 &ReturnLength // ReturnLength 03574 ); 03575 #ifdef TOKEN_DEBUG 03576 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03577 #endif //TOKEN_DEBUG 03578 03579 ASSERT(Status == STATUS_BUFFER_TOO_SMALL); 03580 03581 03582 if (ReturnLength > sizeof(TOKEN_STATISTICS)) { 03583 CurrentLength = ReturnLength - (ULONG)sizeof(TOKEN_STATISTICS); 03584 } else { 03585 CurrentLength = 0; 03586 } 03587 03588 LengthAvailable = QueriedStatistics.DynamicAvailable + CurrentLength; 03589 03590 DbgPrint("Se: Replace discretionary ACL in token ... "); 03591 03592 InformationLength = (ULONG)sizeof(TOKEN_DEFAULT_DACL); 03593 RtlCreateAcl( AssignedDefaultDacl.DefaultDacl, 03594 (ULONG)(LengthAvailable - 50), 03595 ACL_REVISION 03596 ); 03597 03598 Status = NtQueryInformationToken( 03599 TokenWithGroups, // Handle 03600 TokenDefaultDacl, // TokenInformationClass 03601 &QueriedDefaultDacl, // TokenInformation 03602 0, // TokenInformationLength 03603 &ReturnLength // ReturnLength 03604 ); 03605 #ifdef TOKEN_DEBUG 03606 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03607 #endif //TOKEN_DEBUG 03608 03609 03610 if (!(ReturnLength > sizeof(TOKEN_DEFAULT_DACL))) { 03611 03612 // 03613 // Wait a minute, this token doesn't have a default Dacl 03614 // 03615 03616 DbgPrint("******** Failed - No default dacl *********\n"); 03617 CompletionStatus = FALSE; 03618 03619 } else { 03620 03621 Status = NtSetInformationToken( 03622 TokenWithGroups, // Handle 03623 TokenDefaultDacl, // TokenInformationClass 03624 &AssignedDefaultDacl, // TokenInformation 03625 InformationLength // TokenInformationLength 03626 ); 03627 03628 if (NT_SUCCESS(Status)) { 03629 DbgPrint("Succeeded.\n"); 03630 } else { 03631 DbgPrint("********** Failed ************\n"); 03632 DbgPrint("Status is: 0x%lx \n", Status); 03633 CompletionStatus = FALSE; 03634 } 03635 03636 } 03637 03638 ASSERT(NT_SUCCESS(Status)); 03639 03640 03641 // 03642 // Assign a discretionary ACL that doesn't fit into the dynamic part of the 03643 // token. 03644 // 03645 03646 03647 // 03648 // find out how much space is available 03649 // 03650 03651 Status = NtQueryInformationToken( 03652 TokenWithGroups, // Handle 03653 TokenStatistics, // TokenInformationClass 03654 &QueriedStatistics, // TokenInformation 03655 (ULONG)sizeof(TOKEN_STATISTICS), // TokenInformationLength 03656 &ReturnLength // ReturnLength 03657 ); 03658 #ifdef TOKEN_DEBUG 03659 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03660 #endif //TOKEN_DEBUG 03661 03662 ASSERT(NT_SUCCESS(Status)); 03663 03664 Status = NtQueryInformationToken( 03665 TokenWithGroups, // Handle 03666 TokenDefaultDacl, // TokenInformationClass 03667 &QueriedDefaultDacl, // TokenInformation 03668 0, // TokenInformationLength 03669 &ReturnLength // ReturnLength 03670 ); 03671 #ifdef TOKEN_DEBUG 03672 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03673 #endif //TOKEN_DEBUG 03674 03675 ASSERT(Status == STATUS_BUFFER_TOO_SMALL); 03676 03677 03678 if (ReturnLength > sizeof(TOKEN_STATISTICS)) { 03679 CurrentLength = ReturnLength - (ULONG)sizeof(TOKEN_STATISTICS); 03680 } else { 03681 CurrentLength = 0; 03682 } 03683 03684 LengthAvailable = QueriedStatistics.DynamicAvailable + CurrentLength; 03685 03686 DbgPrint("Se: Set too big discretionary ACL ... "); 03687 03688 03689 // 03690 // Now make sure our ACL is large enough to exceed the available 03691 // space. 03692 // 03693 03694 RtlCreateAcl( AssignedDefaultDacl.DefaultDacl, 03695 TOO_BIG_ACL_SIZE, 03696 ACL_REVISION 03697 ); 03698 03699 if (TOO_BIG_ACL_SIZE < LengthAvailable) { 03700 03701 DbgPrint("********** Failed - Dynamic too big ************\n"); 03702 DbgPrint("Dynamic available is: 0x%lx \n", 03703 QueriedStatistics.DynamicAvailable); 03704 DbgPrint("Current default Dacl size is: 0x%lx \n", CurrentLength); 03705 DbgPrint("Big ACL size is: 0x%lx \n", TOO_BIG_ACL_SIZE); 03706 CompletionStatus = FALSE; 03707 } 03708 03709 03710 InformationLength = (ULONG)sizeof(TOKEN_DEFAULT_DACL); 03711 03712 Status = NtSetInformationToken( 03713 TokenWithGroups, // Handle 03714 TokenDefaultDacl, // TokenInformationClass 03715 &AssignedDefaultDacl, // TokenInformation 03716 InformationLength // TokenInformationLength 03717 ); 03718 03719 if (Status == STATUS_ALLOTTED_SPACE_EXCEEDED) { 03720 DbgPrint("Succeeded.\n"); 03721 } else { 03722 DbgPrint("********** Failed ************\n"); 03723 DbgPrint("Status is: 0x%lx \n", Status); 03724 DbgPrint("Dynamic available is: 0x%lx \n", 03725 QueriedStatistics.DynamicAvailable); 03726 DbgPrint("Current default Dacl size is: 0x%lx \n", CurrentLength); 03727 DbgPrint("Big ACL size is: 0x%lx \n", TOO_BIG_ACL_SIZE); 03728 CompletionStatus = FALSE; 03729 } 03730 03731 ASSERT(Status == STATUS_ALLOTTED_SPACE_EXCEEDED); 03732 03733 03734 // 03735 // Set primary group 03736 // 03737 03738 DbgPrint("Se: Set primary group ... "); 03739 03740 AssignedPrimaryGroup.PrimaryGroup = RubbleSid; 03741 InformationLength = (ULONG)sizeof(TOKEN_PRIMARY_GROUP); 03742 03743 Status = NtSetInformationToken( 03744 TokenWithGroups, // Handle 03745 TokenPrimaryGroup, // TokenInformationClass 03746 &AssignedPrimaryGroup, // TokenInformation 03747 InformationLength // TokenInformationLength 03748 ); 03749 03750 if (!NT_SUCCESS(Status)) { 03751 DbgPrint("********** Failed ************\n"); 03752 DbgPrint("Status is: 0x%lx \n", Status); 03753 DbgPrint("InformationLength is: 0x%lx \n", InformationLength); 03754 CompletionStatus = FALSE; 03755 } 03756 03757 ASSERT(NT_SUCCESS(Status)); 03758 03759 03760 // 03761 // Query the Primary Group to see that it was set properly 03762 // 03763 03764 Status = NtQueryInformationToken( 03765 TokenWithGroups, // Handle 03766 TokenPrimaryGroup, // TokenInformationClass 03767 QueriedPrimaryGroup, // TokenInformation 03768 0, // TokenInformationLength 03769 &ReturnLength // ReturnLength 03770 ); 03771 #ifdef TOKEN_DEBUG 03772 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03773 #endif //TOKEN_DEBUG 03774 03775 if (Status != STATUS_BUFFER_TOO_SMALL) { 03776 DbgPrint("********** Failed Query of length ************\n"); 03777 DbgPrint("Status is: 0x%lx \n", Status); 03778 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03779 CompletionStatus = FALSE; 03780 } 03781 03782 ASSERT(!NT_SUCCESS(Status)); 03783 03784 QueriedPrimaryGroup = 03785 (PTOKEN_PRIMARY_GROUP)TstAllocatePool( PagedPool, 03786 ReturnLength 03787 ); 03788 03789 Status = NtQueryInformationToken( 03790 TokenWithGroups, // Handle 03791 TokenPrimaryGroup, // TokenInformationClass 03792 QueriedPrimaryGroup, // TokenInformation 03793 ReturnLength, // TokenInformationLength 03794 &ReturnLength // ReturnLength 03795 ); 03796 #ifdef TOKEN_DEBUG 03797 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03798 #endif //TOKEN_DEBUG 03799 03800 if (NT_SUCCESS(Status)) { 03801 03802 // 03803 // Check returned value 03804 // 03805 03806 if (RtlEqualSid((QueriedPrimaryGroup->PrimaryGroup), 03807 AssignedPrimaryGroup.PrimaryGroup) ) { 03808 DbgPrint("Succeeded.\n"); 03809 } else { 03810 DbgPrint("********** Failed Comparison ************\n"); 03811 DbgPrint("Unexpected value returned by query.\n"); 03812 DbgPrint("Status is: 0x%lx \n", Status); 03813 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03814 CompletionStatus = FALSE; 03815 } 03816 } else { 03817 DbgPrint("********** Failed Query Of Value ************\n"); 03818 DbgPrint("Status is: 0x%lx \n", Status); 03819 DbgPrint("Required return length is: 0x%lx \n", ReturnLength); 03820 CompletionStatus = FALSE; 03821 } 03822 03823 ASSERT(NT_SUCCESS(Status)); 03824 03825 03826 // 03827 // Assign a primary group that doesn't fit into the dynamic part of the 03828 // token. 03829 // 03830 03831 03832 DbgPrint("Se: Set too big primary group ... "); 03833 03834 // 03835 // First, find out how much space is available 03836 // 03837 03838 Status = NtQueryInformationToken( 03839 TokenWithGroups, // Handle 03840 TokenStatistics, // TokenInformationClass 03841 &QueriedStatistics, // TokenInformation 03842 (ULONG)sizeof(TOKEN_STATISTICS), // TokenInformationLength 03843 &ReturnLength // ReturnLength 03844 ); 03845 #ifdef TOKEN_DEBUG 03846 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03847 #endif //TOKEN_DEBUG 03848 03849 ASSERT(NT_SUCCESS(Status)); 03850 03851 Status = NtQueryInformationToken( 03852 TokenWithGroups, // Handle 03853 TokenPrimaryGroup, // TokenInformationClass 03854 QueriedPrimaryGroup, // TokenInformation 03855 ReturnLength, // TokenInformationLength 03856 &ReturnLength // ReturnLength 03857 ); 03858 #ifdef TOKEN_DEBUG 03859 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 03860 #endif //TOKEN_DEBUG 03861 03862 ASSERT(NT_SUCCESS(Status)); 03863 03864 CurrentLength = SeLengthSid(QueriedPrimaryGroup->PrimaryGroup); 03865 LengthAvailable = QueriedStatistics.DynamicAvailable + CurrentLength; 03866 03867 // 03868 // Now make sure our fake group ID is large enough to exceed the available 03869 // space. 03870 // 03871 03872 TooBigSid = (PSID)TstAllocatePool( 03873 PagedPool, 03874 RtlLengthRequiredSid( TOO_BIG_PRIMARY_GROUP_SIZE ) 03875 ); 03876 03877 RtlInitializeSid( 03878 TooBigSid, 03879 &BedrockAuthority, 03880 TOO_BIG_PRIMARY_GROUP_SIZE 03881 ); 03882 03883 if ((ULONG) SeLengthSid(TooBigSid) < LengthAvailable) { 03884 03885 DbgPrint("********** Failed - Dynamic too big ************\n"); 03886 DbgPrint("Dynamic available is: 0x%lx \n", 03887 QueriedStatistics.DynamicAvailable); 03888 DbgPrint("Existing primary group length is: 0x%lx \n", CurrentLength); 03889 DbgPrint("Big SID size is: 0x%lx \n", SeLengthSid(TooBigSid)); 03890 CompletionStatus = FALSE; 03891 } 03892 03893 03894 AssignedPrimaryGroup.PrimaryGroup = TooBigSid; 03895 InformationLength = (ULONG)sizeof(TOKEN_PRIMARY_GROUP); 03896 03897 Status = NtSetInformationToken( 03898 TokenWithGroups, // Handle 03899 TokenPrimaryGroup, // TokenInformationClass 03900 &AssignedPrimaryGroup, // TokenInformation 03901 InformationLength // TokenInformationLength 03902 ); 03903 03904 if (Status == STATUS_ALLOTTED_SPACE_EXCEEDED) { 03905 DbgPrint("Succeeded.\n"); 03906 } else { 03907 DbgPrint("********** Failed ************\n"); 03908 DbgPrint("Status is: 0x%lx \n", Status); 03909 DbgPrint("Dynamic available is: 0x%lx \n", 03910 QueriedStatistics.DynamicAvailable); 03911 DbgPrint("Existing primary group length is: 0x%lx \n", CurrentLength); 03912 DbgPrint("Big SID size is: 0x%lx \n", SeLengthSid(TooBigSid)); 03913 CompletionStatus = FALSE; 03914 } 03915 03916 03917 03918 03919 return CompletionStatus; 03920 } 03921 03923 // // 03924 // Adjust Privileges Test // 03925 // // 03927 03928 BOOLEAN 03929 TestTokenAdjustPrivileges() 03930 { 03931 03932 BOOLEAN CompletionStatus = TRUE; 03933 NTSTATUS Status; 03934 NTSTATUS IgnoreStatus; 03935 03936 PTOKEN_PRIVILEGES NewState; 03937 PTOKEN_PRIVILEGES PreviousState; 03938 PTOKEN_PRIVILEGES PrePrivileges; 03939 PTOKEN_PRIVILEGES PostPrivileges; 03940 03941 ULONG NewStateBufferLength = 200; 03942 ULONG PreviousStateBufferLength = 200; 03943 ULONG PrePrivilegesLength = 200; 03944 ULONG PostPrivilegesLength = 200; 03945 03946 ULONG ReturnLength; 03947 ULONG IgnoreReturnLength; 03948 03949 DbgPrint("\n"); 03950 03951 PreviousState = (PTOKEN_PRIVILEGES)TstAllocatePool( 03952 PagedPool, 03953 PreviousStateBufferLength 03954 ); 03955 03956 PrePrivileges = (PTOKEN_PRIVILEGES)TstAllocatePool( 03957 PagedPool, 03958 PrePrivilegesLength 03959 ); 03960 03961 PostPrivileges = (PTOKEN_PRIVILEGES)TstAllocatePool( 03962 PagedPool, 03963 PostPrivilegesLength 03964 ); 03965 03966 NewState = (PTOKEN_PRIVILEGES)TstAllocatePool( 03967 PagedPool, 03968 NewStateBufferLength 03969 ); 03970 03971 03972 03973 03974 03976 // // 03977 // Adjust privileges giving no instructions // 03978 // // 03980 03981 03982 DbgPrint("Se: Adjust privileges with no instructions ... "); 03983 03984 Status = NtAdjustPrivilegesToken( 03985 SimpleToken, // TokenHandle 03986 FALSE, // DisableAllPrivileges 03987 NULL, // NewState (OPTIONAL) 03988 0, // BufferLength 03989 NULL, // PreviousState (OPTIONAL) 03990 &ReturnLength // ReturnLength 03991 ); 03992 03993 if (Status == STATUS_INVALID_PARAMETER) { 03994 03995 DbgPrint("Succeeded. \n"); 03996 03997 } else { 03998 03999 DbgPrint("********** Failed ************\n"); 04000 DbgPrint("Status is: 0x%lx \n", Status); 04001 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04002 CompletionStatus = FALSE; 04003 04004 } 04005 04006 ASSERT(Status == STATUS_INVALID_PARAMETER); 04007 04008 04010 // // 04011 // Enable privileges in token with no privileges // 04012 // // 04014 04015 04016 NewState->PrivilegeCount = 1; 04017 NewState->Privileges[0].Luid = SecurityPrivilege; 04018 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04019 04020 DbgPrint("Se: Enable privilege in token with none ... "); 04021 04022 Status = NtAdjustPrivilegesToken( 04023 SimpleToken, // TokenHandle 04024 FALSE, // DisableAllPrivileges 04025 NewState, // NewState (OPTIONAL) 04026 0, // BufferLength 04027 NULL, // PreviousState (OPTIONAL) 04028 &ReturnLength // ReturnLength 04029 ); 04030 04031 if (Status == STATUS_NOT_ALL_ASSIGNED) { 04032 04033 DbgPrint("Succeeded. \n"); 04034 04035 } else { 04036 04037 DbgPrint("********** Failed ************\n"); 04038 DbgPrint("Status is: 0x%lx \n", Status); 04039 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04040 CompletionStatus = FALSE; 04041 04042 } 04043 04044 ASSERT(Status == STATUS_NOT_ALL_ASSIGNED); 04045 04046 04048 // // 04049 // Enable a privilege that isn't assigned // 04050 // // 04052 04053 NewState->PrivilegeCount = 1; 04054 NewState->Privileges[0].Luid = CreateTokenPrivilege; 04055 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04056 04057 DbgPrint("Se: Enable unassigned privilege in token with some ... "); 04058 04059 PrePrivileges->PrivilegeCount = 77; 04060 IgnoreStatus = NtQueryInformationToken( 04061 TokenWithPrivileges, // TokenHandle 04062 TokenPrivileges, // TokenInformationClass 04063 PrePrivileges, // TokenInformation 04064 PrePrivilegesLength, // TokenInformationLength 04065 &IgnoreReturnLength // ReturnLength 04066 ); 04067 #ifdef TOKEN_DEBUG 04068 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04069 #endif //TOKEN_DEBUG 04070 04071 ASSERT( PrePrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04072 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04073 04074 Status = NtAdjustPrivilegesToken( 04075 TokenWithPrivileges, // TokenHandle 04076 FALSE, // DisableAllPrivileges 04077 NewState, // NewState (OPTIONAL) 04078 0, // BufferLength 04079 NULL, // PreviousState (OPTIONAL) 04080 &ReturnLength // ReturnLength 04081 ); 04082 04083 PostPrivileges->PrivilegeCount = 88; 04084 IgnoreStatus = NtQueryInformationToken( 04085 TokenWithPrivileges, // TokenHandle 04086 TokenPrivileges, // TokenInformationClass 04087 PostPrivileges, // TokenInformation 04088 PostPrivilegesLength, // TokenInformationLength 04089 &IgnoreReturnLength // ReturnLength 04090 ); 04091 #ifdef TOKEN_DEBUG 04092 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04093 #endif //TOKEN_DEBUG 04094 04095 ASSERT( PostPrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04096 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04097 04098 if (Status == STATUS_NOT_ALL_ASSIGNED) { 04099 04100 // 04101 // Check the privilege values 04102 // 04103 04104 if ( (PrePrivileges->Privileges[0].Attributes == 04105 PostPrivileges->Privileges[0].Attributes) && 04106 (PrePrivileges->Privileges[1].Attributes == 04107 PostPrivileges->Privileges[1].Attributes) ) { 04108 04109 DbgPrint("Succeeded. \n"); 04110 04111 } else { 04112 04113 DbgPrint("********** Failed Value Check ************\n"); 04114 DbgPrint("Status is: 0x%lx \n", Status); 04115 DbgPrint("Before and after privilege 0 state: 0x%lx, 0x%lx \n", 04116 PrePrivileges->Privileges[0].Attributes, 04117 PostPrivileges->Privileges[0].Attributes); 04118 DbgPrint("Before and after privilege 1 state: 0x%lx, 0x%lx \n", 04119 PrePrivileges->Privileges[1].Attributes, 04120 PostPrivileges->Privileges[1].Attributes); 04121 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04122 CompletionStatus = FALSE; 04123 04124 } 04125 04126 } else { 04127 04128 DbgPrint("********** Failed ************\n"); 04129 DbgPrint("Status is: 0x%lx \n", Status); 04130 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04131 CompletionStatus = FALSE; 04132 04133 } 04134 04135 ASSERT(Status == STATUS_NOT_ALL_ASSIGNED); 04136 04137 04138 04139 04141 // // 04142 // Disable All Privileges (which they already are) // 04143 // // 04145 04146 DbgPrint("Se: Disable already disabled privileges ... "); 04147 04148 PrePrivileges->PrivilegeCount = 77; 04149 IgnoreStatus = NtQueryInformationToken( 04150 TokenWithPrivileges, // TokenHandle 04151 TokenPrivileges, // TokenInformationClass 04152 PrePrivileges, // TokenInformation 04153 PrePrivilegesLength, // TokenInformationLength 04154 &IgnoreReturnLength // ReturnLength 04155 ); 04156 #ifdef TOKEN_DEBUG 04157 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04158 #endif //TOKEN_DEBUG 04159 04160 ASSERT( PrePrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04161 ASSERT( PrePrivileges->Privileges[0].Attributes == 0 ); 04162 ASSERT( PrePrivileges->Privileges[1].Attributes == 0 ); 04163 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04164 04165 Status = NtAdjustPrivilegesToken( 04166 TokenWithPrivileges, // TokenHandle 04167 TRUE, // DisableAllPrivileges 04168 NULL, // NewState (OPTIONAL) 04169 0, // BufferLength 04170 NULL, // PreviousState (OPTIONAL) 04171 &ReturnLength // ReturnLength 04172 ); 04173 04174 04175 PostPrivileges->PrivilegeCount = 88; 04176 IgnoreStatus = NtQueryInformationToken( 04177 TokenWithPrivileges, // TokenHandle 04178 TokenPrivileges, // TokenInformationClass 04179 PostPrivileges, // TokenInformation 04180 PostPrivilegesLength, // TokenInformationLength 04181 &IgnoreReturnLength // ReturnLength 04182 ); 04183 #ifdef TOKEN_DEBUG 04184 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04185 #endif //TOKEN_DEBUG 04186 04187 ASSERT( PostPrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04188 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04189 04190 if (Status == STATUS_SUCCESS) { 04191 04192 // 04193 // Check the privilege values 04194 // 04195 04196 if ( (PostPrivileges->Privileges[0].Attributes == 0) && 04197 (PostPrivileges->Privileges[1].Attributes == 0) ) { 04198 04199 DbgPrint("Succeeded. \n"); 04200 04201 } else { 04202 04203 DbgPrint("********** Failed Value Check ************\n"); 04204 DbgPrint("Status is: 0x%lx \n", Status); 04205 DbgPrint("Before and after privilege 0 state: 0x%lx, 0x%lx \n", 04206 PrePrivileges->Privileges[0].Attributes, 04207 PostPrivileges->Privileges[0].Attributes); 04208 DbgPrint("Before and after privilege 1 state: 0x%lx, 0x%lx \n", 04209 PrePrivileges->Privileges[1].Attributes, 04210 PostPrivileges->Privileges[1].Attributes); 04211 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04212 CompletionStatus = FALSE; 04213 04214 } 04215 04216 } else { 04217 04218 DbgPrint("********** Failed ************\n"); 04219 DbgPrint("Status is: 0x%lx \n", Status); 04220 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04221 CompletionStatus = FALSE; 04222 04223 } 04224 04225 ASSERT(Status == STATUS_SUCCESS); 04226 04227 04228 04230 // // 04231 // Enable currently disabled privileges // 04232 // // 04234 04235 DbgPrint("Se: Enable currently disabled privileges ... "); 04236 04237 PrePrivileges->PrivilegeCount = 77; 04238 IgnoreStatus = NtQueryInformationToken( 04239 TokenWithPrivileges, // TokenHandle 04240 TokenPrivileges, // TokenInformationClass 04241 PrePrivileges, // TokenInformation 04242 PrePrivilegesLength, // TokenInformationLength 04243 &IgnoreReturnLength // ReturnLength 04244 ); 04245 #ifdef TOKEN_DEBUG 04246 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04247 #endif //TOKEN_DEBUG 04248 04249 ASSERT( PrePrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04250 ASSERT( PrePrivileges->Privileges[0].Attributes == 0 ); 04251 ASSERT( PrePrivileges->Privileges[1].Attributes == 0 ); 04252 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04253 04254 NewState->PrivilegeCount = 2; 04255 NewState->Privileges[0].Luid = SecurityPrivilege; 04256 NewState->Privileges[1].Luid = UnsolicitedInputPrivilege; 04257 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04258 NewState->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; 04259 04260 Status = NtAdjustPrivilegesToken( 04261 TokenWithPrivileges, // TokenHandle 04262 FALSE, // DisableAllPrivileges 04263 NewState, // NewState (OPTIONAL) 04264 0, // BufferLength 04265 NULL, // PreviousState (OPTIONAL) 04266 &ReturnLength // ReturnLength 04267 ); 04268 04269 PostPrivileges->PrivilegeCount = 88; 04270 IgnoreStatus = NtQueryInformationToken( 04271 TokenWithPrivileges, // TokenHandle 04272 TokenPrivileges, // TokenInformationClass 04273 PostPrivileges, // TokenInformation 04274 PostPrivilegesLength, // TokenInformationLength 04275 &IgnoreReturnLength // ReturnLength 04276 ); 04277 #ifdef TOKEN_DEBUG 04278 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04279 #endif //TOKEN_DEBUG 04280 04281 ASSERT( PostPrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04282 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04283 04284 if (Status == STATUS_SUCCESS) { 04285 04286 // 04287 // Check the privilege values 04288 // 04289 04290 if ( (PostPrivileges->Privileges[0].Attributes == SE_PRIVILEGE_ENABLED) && 04291 (PostPrivileges->Privileges[1].Attributes == SE_PRIVILEGE_ENABLED) 04292 ) { 04293 04294 DbgPrint("Succeeded. \n"); 04295 04296 } else { 04297 04298 DbgPrint("********** Failed Value Check ************\n"); 04299 DbgPrint("Status is: 0x%lx \n", Status); 04300 DbgPrint("Before and after privilege 0 state: 0x%lx, 0x%lx \n", 04301 PrePrivileges->Privileges[0].Attributes, 04302 PostPrivileges->Privileges[0].Attributes); 04303 DbgPrint("Before and after privilege 1 state: 0x%lx, 0x%lx \n", 04304 PrePrivileges->Privileges[1].Attributes, 04305 PostPrivileges->Privileges[1].Attributes); 04306 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04307 CompletionStatus = FALSE; 04308 04309 } 04310 04311 } else { 04312 04313 DbgPrint("********** Failed ************\n"); 04314 DbgPrint("Status is: 0x%lx \n", Status); 04315 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04316 CompletionStatus = FALSE; 04317 04318 } 04319 04320 ASSERT(Status == STATUS_SUCCESS); 04321 04322 04323 04325 // // 04326 // Disable all enabled privileges // 04327 // // 04329 04330 DbgPrint("Se: Disable all enabled privileges ... "); 04331 04332 PrePrivileges->PrivilegeCount = 77; 04333 IgnoreStatus = NtQueryInformationToken( 04334 TokenWithPrivileges, // TokenHandle 04335 TokenPrivileges, // TokenInformationClass 04336 PrePrivileges, // TokenInformation 04337 PrePrivilegesLength, // TokenInformationLength 04338 &IgnoreReturnLength // ReturnLength 04339 ); 04340 04341 ASSERT( PrePrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04342 ASSERT( PrePrivileges->Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ); 04343 ASSERT( PrePrivileges->Privileges[1].Attributes == SE_PRIVILEGE_ENABLED ); 04344 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04345 04346 Status = NtAdjustPrivilegesToken( 04347 TokenWithPrivileges, // TokenHandle 04348 TRUE, // DisableAllPrivileges 04349 NULL, // NewState (OPTIONAL) 04350 0, // BufferLength 04351 NULL, // PreviousState (OPTIONAL) 04352 &ReturnLength // ReturnLength 04353 ); 04354 04355 04356 PostPrivileges->PrivilegeCount = 88; 04357 IgnoreStatus = NtQueryInformationToken( 04358 TokenWithPrivileges, // TokenHandle 04359 TokenPrivileges, // TokenInformationClass 04360 PostPrivileges, // TokenInformation 04361 PostPrivilegesLength, // TokenInformationLength 04362 &IgnoreReturnLength // ReturnLength 04363 ); 04364 #ifdef TOKEN_DEBUG 04365 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04366 #endif //TOKEN_DEBUG 04367 04368 ASSERT( PostPrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04369 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04370 04371 if (Status == STATUS_SUCCESS) { 04372 04373 // 04374 // Check the privilege values 04375 // 04376 04377 if ( (PostPrivileges->Privileges[0].Attributes == 0) && 04378 (PostPrivileges->Privileges[1].Attributes == 0) ) { 04379 04380 DbgPrint("Succeeded. \n"); 04381 04382 } else { 04383 04384 DbgPrint("********** Failed Value Check ************\n"); 04385 DbgPrint("Status is: 0x%lx \n", Status); 04386 DbgPrint("Before and after privilege 0 state: 0x%lx, 0x%lx \n", 04387 PrePrivileges->Privileges[0].Attributes, 04388 PostPrivileges->Privileges[0].Attributes); 04389 DbgPrint("Before and after privilege 1 state: 0x%lx, 0x%lx \n", 04390 PrePrivileges->Privileges[1].Attributes, 04391 PostPrivileges->Privileges[1].Attributes); 04392 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04393 CompletionStatus = FALSE; 04394 04395 } 04396 04397 } else { 04398 04399 DbgPrint("********** Failed ************\n"); 04400 DbgPrint("Status is: 0x%lx \n", Status); 04401 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04402 CompletionStatus = FALSE; 04403 04404 } 04405 04406 ASSERT(Status == STATUS_SUCCESS); 04407 04408 04409 04411 // // 04412 // Enable privileges requesting previous state with no return // 04413 // length buffer // 04414 // // 04416 04417 04418 DbgPrint("Se: PreviousState not NULL, ReturnLength NULL... "); 04419 04420 NewState->PrivilegeCount = 2; 04421 NewState->Privileges[0].Luid = SecurityPrivilege; 04422 NewState->Privileges[1].Luid = UnsolicitedInputPrivilege; 04423 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04424 NewState->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; 04425 04426 Status = NtAdjustPrivilegesToken( 04427 TokenWithPrivileges, // TokenHandle 04428 FALSE, // DisableAllPrivileges 04429 NewState, // NewState (OPTIONAL) 04430 0, // BufferLength 04431 PreviousState, // PreviousState (OPTIONAL) 04432 NULL // ReturnLength 04433 ); 04434 04435 if (Status == STATUS_ACCESS_VIOLATION) { 04436 04437 DbgPrint("Succeeded. \n"); 04438 04439 } else { 04440 04441 DbgPrint("********** Failed ************\n"); 04442 DbgPrint("Status is: 0x%lx \n", Status); 04443 CompletionStatus = FALSE; 04444 04445 } 04446 04447 ASSERT(Status == STATUS_ACCESS_VIOLATION); 04448 04449 04450 04451 04453 // // 04454 // Enable privileges without requesting previous state and // 04455 // providing no return length buffer // 04456 // // 04458 04459 04460 DbgPrint("Se: PreviousState and ReturnLength both NULL... "); 04461 04462 NewState->PrivilegeCount = 2; 04463 NewState->Privileges[0].Luid = SecurityPrivilege; 04464 NewState->Privileges[1].Luid = UnsolicitedInputPrivilege; 04465 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04466 NewState->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; 04467 04468 Status = NtAdjustPrivilegesToken( 04469 TokenWithPrivileges, // TokenHandle 04470 FALSE, // DisableAllPrivileges 04471 NewState, // NewState (OPTIONAL) 04472 0, // BufferLength 04473 NULL, // PreviousState (OPTIONAL) 04474 NULL // ReturnLength 04475 ); 04476 04477 if (Status == STATUS_SUCCESS) { 04478 04479 DbgPrint("Succeeded. \n"); 04480 04481 } else { 04482 04483 DbgPrint("********** Failed ************\n"); 04484 DbgPrint("Status is: 0x%lx \n", Status); 04485 CompletionStatus = FALSE; 04486 04487 } 04488 04489 ASSERT(Status == STATUS_SUCCESS); 04490 04491 04492 04493 04494 04495 04497 // // 04498 // Enable privileges requesting previous state with insufficient // 04499 // buffer // 04500 // // 04502 04503 04504 DbgPrint("Se: Too small buffer for previous state ... "); 04505 04506 // 04507 // Establish a known previous state first... 04508 // 04509 04510 Status = NtAdjustPrivilegesToken( 04511 TokenWithPrivileges, // TokenHandle 04512 TRUE, // DisableAllPrivileges 04513 NULL, // NewState (OPTIONAL) 04514 0, // BufferLength 04515 NULL, // PreviousState (OPTIONAL) 04516 &ReturnLength // ReturnLength 04517 ); 04518 04519 NewState->PrivilegeCount = 2; 04520 NewState->Privileges[0].Luid = SecurityPrivilege; 04521 NewState->Privileges[1].Luid = UnsolicitedInputPrivilege; 04522 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04523 NewState->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; 04524 04525 Status = NtAdjustPrivilegesToken( 04526 TokenWithPrivileges, // TokenHandle 04527 FALSE, // DisableAllPrivileges 04528 NewState, // NewState (OPTIONAL) 04529 0, // BufferLength 04530 PreviousState, // PreviousState (OPTIONAL) 04531 &ReturnLength // ReturnLength 04532 ); 04533 #ifdef TOKEN_DEBUG 04534 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 04535 #endif //TOKEN_DEBUG 04536 04537 if (Status == STATUS_BUFFER_TOO_SMALL) { 04538 04539 DbgPrint("Succeeded. \n"); 04540 04541 } else { 04542 04543 DbgPrint("********** Failed ************\n"); 04544 DbgPrint("Status is: 0x%lx \n", Status); 04545 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04546 CompletionStatus = FALSE; 04547 04548 } 04549 04550 ASSERT(Status == STATUS_BUFFER_TOO_SMALL); 04551 04552 04553 04554 04555 04557 // // 04558 // Enable one of the privileges requesting previous state // 04559 // // 04561 04562 DbgPrint("Se: Enable one requesting previous state ... "); 04563 04564 PrePrivileges->PrivilegeCount = 77; 04565 IgnoreStatus = NtQueryInformationToken( 04566 TokenWithPrivileges, // TokenHandle 04567 TokenPrivileges, // TokenInformationClass 04568 PrePrivileges, // TokenInformation 04569 PrePrivilegesLength, // TokenInformationLength 04570 &IgnoreReturnLength // ReturnLength 04571 ); 04572 #ifdef TOKEN_DEBUG 04573 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04574 #endif //TOKEN_DEBUG 04575 04576 ASSERT( PrePrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04577 ASSERT( PrePrivileges->Privileges[0].Attributes == 0 ); 04578 ASSERT( PrePrivileges->Privileges[1].Attributes == 0 ); 04579 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04580 04581 04582 NewState->PrivilegeCount = 1; 04583 NewState->Privileges[0].Luid = SecurityPrivilege; 04584 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04585 04586 Status = NtAdjustPrivilegesToken( 04587 TokenWithPrivileges, // TokenHandle 04588 FALSE, // DisableAllPrivileges 04589 NewState, // NewState (OPTIONAL) 04590 PreviousStateBufferLength, // BufferLength 04591 PreviousState, // PreviousState (OPTIONAL) 04592 &ReturnLength // ReturnLength 04593 ); 04594 #ifdef TOKEN_DEBUG 04595 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 04596 #endif //TOKEN_DEBUG 04597 04598 ASSERT(NT_SUCCESS(Status)); 04599 ASSERT(PreviousState->PrivilegeCount == 1); 04600 04601 04602 PostPrivileges->PrivilegeCount = 88; 04603 IgnoreStatus = NtQueryInformationToken( 04604 TokenWithPrivileges, // TokenHandle 04605 TokenPrivileges, // TokenInformationClass 04606 PostPrivileges, // TokenInformation 04607 PostPrivilegesLength, // TokenInformationLength 04608 &IgnoreReturnLength // ReturnLength 04609 ); 04610 #ifdef TOKEN_DEBUG 04611 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04612 #endif //TOKEN_DEBUG 04613 04614 ASSERT( PostPrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04615 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04616 04617 if (Status == STATUS_SUCCESS) { 04618 04619 // 04620 // Check the privilege values 04621 // 04622 04623 if ( (PostPrivileges->Privileges[SECURITY_INDEX].Attributes == 04624 SE_PRIVILEGE_ENABLED) && 04625 (PostPrivileges->Privileges[UNSOLICITED_INDEX].Attributes == 0) 04626 ) { 04627 04628 DbgPrint("Succeeded. \n"); 04629 04630 } else { 04631 04632 DbgPrint("********** Failed Value Check ************\n"); 04633 DbgPrint("Status is: 0x%lx \n", Status); 04634 DbgPrint("Before and after privilege 0 state: 0x%lx, 0x%lx \n", 04635 PrePrivileges->Privileges[0].Attributes, 04636 PostPrivileges->Privileges[0].Attributes); 04637 DbgPrint("Before and after privilege 1 state: 0x%lx, 0x%lx \n", 04638 PrePrivileges->Privileges[1].Attributes, 04639 PostPrivileges->Privileges[1].Attributes); 04640 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04641 CompletionStatus = FALSE; 04642 04643 } 04644 04645 } else { 04646 04647 DbgPrint("********** Failed ************\n"); 04648 DbgPrint("Status is: 0x%lx \n", Status); 04649 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04650 DbgPrint("Change Count is: 0x%lx \n", PreviousState->PrivilegeCount); 04651 CompletionStatus = FALSE; 04652 04653 } 04654 04655 ASSERT(Status == STATUS_SUCCESS); 04656 04657 04658 04659 04661 // // 04662 // Enable the other privilege requesting previous state // 04663 // // 04665 04666 DbgPrint("Se: Enable one requesting previous state ... "); 04667 04668 PrePrivileges->PrivilegeCount = 77; 04669 IgnoreStatus = NtQueryInformationToken( 04670 TokenWithPrivileges, // TokenHandle 04671 TokenPrivileges, // TokenInformationClass 04672 PrePrivileges, // TokenInformation 04673 PrePrivilegesLength, // TokenInformationLength 04674 &IgnoreReturnLength // ReturnLength 04675 ); 04676 #ifdef TOKEN_DEBUG 04677 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04678 #endif //TOKEN_DEBUG 04679 04680 ASSERT( PrePrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04681 ASSERT( PrePrivileges->Privileges[SECURITY_INDEX].Attributes == 04682 SE_PRIVILEGE_ENABLED ); 04683 ASSERT( PrePrivileges->Privileges[UNSOLICITED_INDEX].Attributes == 0 ); 04684 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04685 04686 NewState->PrivilegeCount = 1; 04687 NewState->Privileges[0].Luid = UnsolicitedInputPrivilege; 04688 NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 04689 04690 Status = NtAdjustPrivilegesToken( 04691 TokenWithPrivileges, // TokenHandle 04692 FALSE, // DisableAllPrivileges 04693 NewState, // NewState (OPTIONAL) 04694 PreviousStateBufferLength, // BufferLength 04695 PreviousState, // PreviousState (OPTIONAL) 04696 &ReturnLength // ReturnLength 04697 ); 04698 #ifdef TOKEN_DEBUG 04699 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 04700 #endif //TOKEN_DEBUG 04701 04702 ASSERT(NT_SUCCESS(Status)); 04703 ASSERT(PreviousState->PrivilegeCount == 1); 04704 04705 04706 PostPrivileges->PrivilegeCount = 88; 04707 IgnoreStatus = NtQueryInformationToken( 04708 TokenWithPrivileges, // TokenHandle 04709 TokenPrivileges, // TokenInformationClass 04710 PostPrivileges, // TokenInformation 04711 PostPrivilegesLength, // TokenInformationLength 04712 &IgnoreReturnLength // ReturnLength 04713 ); 04714 #ifdef TOKEN_DEBUG 04715 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04716 #endif //TOKEN_DEBUG 04717 04718 ASSERT( PostPrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04719 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04720 04721 if (Status == STATUS_SUCCESS) { 04722 04723 // 04724 // Check the privilege values 04725 // 04726 04727 if ( (PostPrivileges->Privileges[0].Attributes == SE_PRIVILEGE_ENABLED) && 04728 (PostPrivileges->Privileges[1].Attributes == SE_PRIVILEGE_ENABLED) 04729 ) { 04730 04731 DbgPrint("Succeeded. \n"); 04732 04733 } else { 04734 04735 DbgPrint("********** Failed Value Check ************\n"); 04736 DbgPrint("Status is: 0x%lx \n", Status); 04737 DbgPrint("Before and after privilege 0 state: 0x%lx, 0x%lx \n", 04738 PrePrivileges->Privileges[0].Attributes, 04739 PostPrivileges->Privileges[0].Attributes); 04740 DbgPrint("Before and after privilege 1 state: 0x%lx, 0x%lx \n", 04741 PrePrivileges->Privileges[1].Attributes, 04742 PostPrivileges->Privileges[1].Attributes); 04743 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04744 CompletionStatus = FALSE; 04745 04746 } 04747 04748 } else { 04749 04750 DbgPrint("********** Failed ************\n"); 04751 DbgPrint("Status is: 0x%lx \n", Status); 04752 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04753 DbgPrint("Change Count is: 0x%lx \n", PreviousState->PrivilegeCount); 04754 CompletionStatus = FALSE; 04755 04756 } 04757 04758 ASSERT(Status == STATUS_SUCCESS); 04759 04760 04761 04762 04763 04765 // // 04766 // Return privileges to their previous state // 04767 // Uses PreviousState from previous call // 04768 // // 04770 04771 DbgPrint("Se: Return privileges to previous state ... "); 04772 04773 PrePrivileges->PrivilegeCount = 77; 04774 IgnoreStatus = NtQueryInformationToken( 04775 TokenWithPrivileges, // TokenHandle 04776 TokenPrivileges, // TokenInformationClass 04777 PrePrivileges, // TokenInformation 04778 PrePrivilegesLength, // TokenInformationLength 04779 &IgnoreReturnLength // ReturnLength 04780 ); 04781 #ifdef TOKEN_DEBUG 04782 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04783 #endif //TOKEN_DEBUG 04784 04785 ASSERT( PrePrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04786 ASSERT( PrePrivileges->Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ); 04787 ASSERT( PrePrivileges->Privileges[1].Attributes == SE_PRIVILEGE_ENABLED ); 04788 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04789 04790 Status = NtAdjustPrivilegesToken( 04791 TokenWithPrivileges, // TokenHandle 04792 FALSE, // DisableAllPrivileges 04793 PreviousState, // NewState (OPTIONAL) 04794 0, // BufferLength 04795 NULL, // PreviousState (OPTIONAL) 04796 &ReturnLength // ReturnLength 04797 ); 04798 04799 ASSERT(NT_SUCCESS(Status)); 04800 ASSERT(PreviousState->PrivilegeCount == 1); 04801 04802 04803 PostPrivileges->PrivilegeCount = 88; 04804 IgnoreStatus = NtQueryInformationToken( 04805 TokenWithPrivileges, // TokenHandle 04806 TokenPrivileges, // TokenInformationClass 04807 PostPrivileges, // TokenInformation 04808 PostPrivilegesLength, // TokenInformationLength 04809 &IgnoreReturnLength // ReturnLength 04810 ); 04811 #ifdef TOKEN_DEBUG 04812 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04813 #endif //TOKEN_DEBUG 04814 04815 ASSERT( PostPrivileges->PrivilegeCount == PRIVILEGE_COUNT ); 04816 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04817 04818 if (Status == STATUS_SUCCESS) { 04819 04820 // 04821 // Check the privilege values 04822 // 04823 04824 if ( (PostPrivileges->Privileges[SECURITY_INDEX].Attributes == 04825 SE_PRIVILEGE_ENABLED) && 04826 (PostPrivileges->Privileges[UNSOLICITED_INDEX].Attributes == 0) 04827 ) { 04828 04829 DbgPrint("Succeeded. \n"); 04830 04831 } else { 04832 04833 DbgPrint("********** Failed Value Check ************\n"); 04834 DbgPrint("Status is: 0x%lx \n", Status); 04835 DbgPrint("Before and after privilege 0 state: 0x%lx, 0x%lx \n", 04836 PrePrivileges->Privileges[0].Attributes, 04837 PostPrivileges->Privileges[0].Attributes); 04838 DbgPrint("Before and after privilege 1 state: 0x%lx, 0x%lx \n", 04839 PrePrivileges->Privileges[1].Attributes, 04840 PostPrivileges->Privileges[1].Attributes); 04841 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04842 CompletionStatus = FALSE; 04843 04844 } 04845 04846 } else { 04847 04848 DbgPrint("********** Failed ************\n"); 04849 DbgPrint("Status is: 0x%lx \n", Status); 04850 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04851 CompletionStatus = FALSE; 04852 04853 } 04854 04855 04856 ASSERT(Status == STATUS_SUCCESS); 04857 04858 04859 04860 04862 // // 04863 // Done with test // 04864 // // 04866 04867 04868 04869 TstDeallocatePool( PreviousState, PreviousStateBufferLength ); 04870 TstDeallocatePool( NewState, NewStateBufferLength ); 04871 TstDeallocatePool( PrePrivileges, PrePrivilegesLength ); 04872 TstDeallocatePool( PostPrivileges, PostPrivilegesLength ); 04873 04874 04875 return CompletionStatus; 04876 } 04877 04879 // // 04880 // Adjust Groups Test // 04881 // // 04883 04884 BOOLEAN 04885 TestTokenAdjustGroups() 04886 { 04887 BOOLEAN CompletionStatus = TRUE; 04888 NTSTATUS Status; 04889 NTSTATUS IgnoreStatus; 04890 04891 PTOKEN_GROUPS NewState; 04892 PTOKEN_GROUPS PreviousState; 04893 PTOKEN_GROUPS PreGroups; 04894 PTOKEN_GROUPS PostGroups; 04895 04896 ULONG NewStateBufferLength = 600; 04897 ULONG PreviousStateBufferLength = 600; 04898 ULONG PreGroupsLength = 600; 04899 ULONG PostGroupsLength = 600; 04900 04901 ULONG ReturnLength; 04902 ULONG IgnoreReturnLength; 04903 04904 DbgPrint("\n"); 04905 04906 PreviousState = (PTOKEN_GROUPS)TstAllocatePool( 04907 PagedPool, 04908 PreviousStateBufferLength 04909 ); 04910 04911 PreGroups = (PTOKEN_GROUPS)TstAllocatePool( 04912 PagedPool, 04913 PreGroupsLength 04914 ); 04915 04916 PostGroups = (PTOKEN_GROUPS)TstAllocatePool( 04917 PagedPool, 04918 PostGroupsLength 04919 ); 04920 04921 NewState = (PTOKEN_GROUPS)TstAllocatePool( 04922 PagedPool, 04923 NewStateBufferLength 04924 ); 04925 04926 04927 04928 04929 04931 // // 04932 // Adjust groups giving no instructions // 04933 // // 04935 04936 04937 DbgPrint("Se: Adjust groups with no instructions ... "); 04938 04939 Status = NtAdjustGroupsToken( 04940 SimpleToken, // TokenHandle 04941 FALSE, // ResetToDefault 04942 NULL, // NewState (OPTIONAL) 04943 0, // BufferLength 04944 NULL, // PreviousState (OPTIONAL) 04945 &ReturnLength // ReturnLength 04946 ); 04947 04948 if (Status == STATUS_INVALID_PARAMETER) { 04949 04950 DbgPrint("Succeeded. \n"); 04951 04952 } else { 04953 04954 DbgPrint("********** Failed ************\n"); 04955 DbgPrint("Status is: 0x%lx \n", Status); 04956 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 04957 CompletionStatus = FALSE; 04958 04959 } 04960 04961 ASSERT(Status == STATUS_INVALID_PARAMETER); 04962 04963 04965 // // 04966 // Disable unknown group // 04967 // // 04969 04970 DbgPrint("Se: Disable unknown group ... "); 04971 04972 PreGroups->GroupCount = 77; 04973 IgnoreStatus = NtQueryInformationToken( 04974 TokenWithGroups, // TokenHandle 04975 TokenGroups, // TokenInformationClass 04976 PreGroups, // TokenInformation 04977 PreGroupsLength, // TokenInformationLength 04978 &IgnoreReturnLength // ReturnLength 04979 ); 04980 #ifdef TOKEN_DEBUG 04981 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 04982 #endif //TOKEN_DEBUG 04983 04984 if (IgnoreStatus != STATUS_SUCCESS) { 04985 DbgPrint(" \n IgnoreStatus = 0x%lx \n", IgnoreStatus); 04986 DbgPrint(" \n IgnoreReturnLength = 0x%lx \n", IgnoreReturnLength); 04987 } 04988 04989 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 04990 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 04991 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 04992 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 04993 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 04994 ASSERT(NT_SUCCESS(IgnoreStatus) ); 04995 04996 NewState->GroupCount = 1; 04997 NewState->Groups[0].Sid = RubbleSid; 04998 NewState->Groups[0].Attributes = DisabledGroupAttributes; 04999 05000 Status = NtAdjustGroupsToken( 05001 TokenWithGroups, // TokenHandle 05002 FALSE, // ResetToDefault 05003 NewState, // NewState (OPTIONAL) 05004 0, // BufferLength 05005 NULL, // PreviousState (OPTIONAL) 05006 &ReturnLength // ReturnLength 05007 ); 05008 05009 PostGroups->GroupCount = 88; 05010 IgnoreStatus = NtQueryInformationToken( 05011 TokenWithGroups, // TokenHandle 05012 TokenGroups, // TokenInformationClass 05013 PostGroups, // TokenInformation 05014 PostGroupsLength, // TokenInformationLength 05015 &IgnoreReturnLength // ReturnLength 05016 ); 05017 #ifdef TOKEN_DEBUG 05018 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05019 #endif //TOKEN_DEBUG 05020 05021 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05022 05023 if (Status == STATUS_NOT_ALL_ASSIGNED) { 05024 05025 // 05026 // Check the group values 05027 // 05028 05029 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05030 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05031 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 05032 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05033 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05034 ) { 05035 05036 DbgPrint("Succeeded. \n"); 05037 05038 } else { 05039 05040 DbgPrint("********** Failed Value Check ************\n"); 05041 DbgPrint("Status is: 0x%lx \n", Status); 05042 05043 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05044 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05045 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05046 05047 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05048 PreGroups->Groups[CHILD_INDEX].Attributes, 05049 PostGroups->Groups[CHILD_INDEX].Attributes); 05050 05051 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05052 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05053 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05054 05055 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05056 PreGroups->Groups[WORLD_INDEX].Attributes, 05057 PostGroups->Groups[WORLD_INDEX].Attributes); 05058 05059 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05060 05061 CompletionStatus = FALSE; 05062 05063 } 05064 05065 } else { 05066 05067 DbgPrint("********** Failed ************\n"); 05068 DbgPrint("Status is: 0x%lx \n", Status); 05069 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05070 CompletionStatus = FALSE; 05071 05072 } 05073 05074 ASSERT(Status == STATUS_NOT_ALL_ASSIGNED); 05075 05076 05077 05079 // // 05080 // Enable unknown group // 05081 // // 05083 05084 DbgPrint("Se: Enable unknown group ... "); 05085 05086 PreGroups->GroupCount = 77; 05087 IgnoreStatus = NtQueryInformationToken( 05088 TokenWithGroups, // TokenHandle 05089 TokenGroups, // TokenInformationClass 05090 PreGroups, // TokenInformation 05091 PreGroupsLength, // TokenInformationLength 05092 &IgnoreReturnLength // ReturnLength 05093 ); 05094 #ifdef TOKEN_DEBUG 05095 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05096 #endif //TOKEN_DEBUG 05097 05098 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05099 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05100 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 05101 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05102 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05103 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05104 05105 NewState->GroupCount = 1; 05106 NewState->Groups[0].Sid = RubbleSid; 05107 NewState->Groups[0].Attributes = OptionalGroupAttributes; 05108 05109 Status = NtAdjustGroupsToken( 05110 TokenWithGroups, // TokenHandle 05111 FALSE, // ResetToDefault 05112 NewState, // NewState (OPTIONAL) 05113 0, // BufferLength 05114 NULL, // PreviousState (OPTIONAL) 05115 &ReturnLength // ReturnLength 05116 ); 05117 05118 PostGroups->GroupCount = 88; 05119 IgnoreStatus = NtQueryInformationToken( 05120 TokenWithGroups, // TokenHandle 05121 TokenGroups, // TokenInformationClass 05122 PostGroups, // TokenInformation 05123 PostGroupsLength, // TokenInformationLength 05124 &IgnoreReturnLength // ReturnLength 05125 ); 05126 #ifdef TOKEN_DEBUG 05127 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05128 #endif //TOKEN_DEBUG 05129 05130 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05131 05132 if (Status == STATUS_NOT_ALL_ASSIGNED) { 05133 05134 // 05135 // Check the group values 05136 // 05137 05138 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05139 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05140 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 05141 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05142 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05143 ) { 05144 05145 DbgPrint("Succeeded. \n"); 05146 05147 } else { 05148 05149 DbgPrint("********** Failed Value Check ************\n"); 05150 DbgPrint("Status is: 0x%lx \n", Status); 05151 05152 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05153 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05154 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05155 05156 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05157 PreGroups->Groups[CHILD_INDEX].Attributes, 05158 PostGroups->Groups[CHILD_INDEX].Attributes); 05159 05160 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05161 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05162 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05163 05164 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05165 PreGroups->Groups[WORLD_INDEX].Attributes, 05166 PostGroups->Groups[WORLD_INDEX].Attributes); 05167 05168 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05169 05170 CompletionStatus = FALSE; 05171 05172 } 05173 05174 } else { 05175 05176 DbgPrint("********** Failed ************\n"); 05177 DbgPrint("Status is: 0x%lx \n", Status); 05178 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05179 CompletionStatus = FALSE; 05180 05181 } 05182 05183 ASSERT(Status == STATUS_NOT_ALL_ASSIGNED); 05184 05185 05186 05188 // // 05189 // Disable mandatory group // 05190 // // 05192 05193 DbgPrint("Se: Disable mandatory group ... "); 05194 05195 PreGroups->GroupCount = 77; 05196 IgnoreStatus = NtQueryInformationToken( 05197 TokenWithGroups, // TokenHandle 05198 TokenGroups, // TokenInformationClass 05199 PreGroups, // TokenInformation 05200 PreGroupsLength, // TokenInformationLength 05201 &IgnoreReturnLength // ReturnLength 05202 ); 05203 #ifdef TOKEN_DEBUG 05204 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05205 #endif //TOKEN_DEBUG 05206 05207 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05208 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05209 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 05210 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05211 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05212 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05213 05214 NewState->GroupCount = 1; 05215 NewState->Groups[0].Sid = WorldSid; 05216 NewState->Groups[0].Attributes = DisabledGroupAttributes; 05217 05218 Status = NtAdjustGroupsToken( 05219 TokenWithGroups, // TokenHandle 05220 FALSE, // ResetToDefault 05221 NewState, // NewState (OPTIONAL) 05222 0, // BufferLength 05223 NULL, // PreviousState (OPTIONAL) 05224 &ReturnLength // ReturnLength 05225 ); 05226 05227 PostGroups->GroupCount = 88; 05228 IgnoreStatus = NtQueryInformationToken( 05229 TokenWithGroups, // TokenHandle 05230 TokenGroups, // TokenInformationClass 05231 PostGroups, // TokenInformation 05232 PostGroupsLength, // TokenInformationLength 05233 &IgnoreReturnLength // ReturnLength 05234 ); 05235 #ifdef TOKEN_DEBUG 05236 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05237 #endif //TOKEN_DEBUG 05238 05239 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05240 05241 if (Status == STATUS_CANT_DISABLE_MANDATORY) { 05242 05243 // 05244 // Check the group values 05245 // 05246 05247 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05248 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05249 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 05250 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05251 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05252 ) { 05253 05254 DbgPrint("Succeeded. \n"); 05255 05256 } else { 05257 05258 DbgPrint("********** Failed Value Check ************\n"); 05259 DbgPrint("Status is: 0x%lx \n", Status); 05260 05261 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05262 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05263 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05264 05265 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05266 PreGroups->Groups[CHILD_INDEX].Attributes, 05267 PostGroups->Groups[CHILD_INDEX].Attributes); 05268 05269 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05270 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05271 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05272 05273 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05274 PreGroups->Groups[WORLD_INDEX].Attributes, 05275 PostGroups->Groups[WORLD_INDEX].Attributes); 05276 05277 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05278 05279 CompletionStatus = FALSE; 05280 05281 } 05282 05283 } else { 05284 05285 DbgPrint("********** Failed ************\n"); 05286 DbgPrint("Status is: 0x%lx \n", Status); 05287 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05288 CompletionStatus = FALSE; 05289 05290 } 05291 05292 ASSERT(Status == STATUS_CANT_DISABLE_MANDATORY); 05293 05294 05295 05296 05298 // // 05299 // Enable mandatory group // 05300 // // 05302 05303 DbgPrint("Se: Enable mandatory group ... "); 05304 05305 PreGroups->GroupCount = 77; 05306 IgnoreStatus = NtQueryInformationToken( 05307 TokenWithGroups, // TokenHandle 05308 TokenGroups, // TokenInformationClass 05309 PreGroups, // TokenInformation 05310 PreGroupsLength, // TokenInformationLength 05311 &IgnoreReturnLength // ReturnLength 05312 ); 05313 #ifdef TOKEN_DEBUG 05314 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05315 #endif //TOKEN_DEBUG 05316 05317 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05318 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05319 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 05320 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05321 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05322 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05323 05324 NewState->GroupCount = 1; 05325 NewState->Groups[0].Sid = WorldSid; 05326 NewState->Groups[0].Attributes = OptionalGroupAttributes; 05327 05328 Status = NtAdjustGroupsToken( 05329 TokenWithGroups, // TokenHandle 05330 FALSE, // ResetToDefault 05331 NewState, // NewState (OPTIONAL) 05332 0, // BufferLength 05333 NULL, // PreviousState (OPTIONAL) 05334 &ReturnLength // ReturnLength 05335 ); 05336 05337 PostGroups->GroupCount = 88; 05338 IgnoreStatus = NtQueryInformationToken( 05339 TokenWithGroups, // TokenHandle 05340 TokenGroups, // TokenInformationClass 05341 PostGroups, // TokenInformation 05342 PostGroupsLength, // TokenInformationLength 05343 &IgnoreReturnLength // ReturnLength 05344 ); 05345 #ifdef TOKEN_DEBUG 05346 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05347 #endif //TOKEN_DEBUG 05348 05349 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05350 05351 if (Status == STATUS_SUCCESS) { 05352 05353 // 05354 // Check the group values 05355 // 05356 05357 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05358 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05359 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 05360 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05361 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05362 ) { 05363 05364 DbgPrint("Succeeded. \n"); 05365 05366 } else { 05367 05368 DbgPrint("********** Failed Value Check ************\n"); 05369 DbgPrint("Status is: 0x%lx \n", Status); 05370 05371 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05372 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05373 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05374 05375 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05376 PreGroups->Groups[CHILD_INDEX].Attributes, 05377 PostGroups->Groups[CHILD_INDEX].Attributes); 05378 05379 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05380 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05381 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05382 05383 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05384 PreGroups->Groups[WORLD_INDEX].Attributes, 05385 PostGroups->Groups[WORLD_INDEX].Attributes); 05386 05387 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05388 05389 CompletionStatus = FALSE; 05390 05391 } 05392 05393 } else { 05394 05395 DbgPrint("********** Failed ************\n"); 05396 DbgPrint("Status is: 0x%lx \n", Status); 05397 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05398 CompletionStatus = FALSE; 05399 05400 } 05401 05402 ASSERT(Status == STATUS_SUCCESS); 05403 05404 05405 05407 // // 05408 // Disable optional group // 05409 // // 05411 05412 DbgPrint("Se: Disable optional group ... "); 05413 05414 PreGroups->GroupCount = 77; 05415 IgnoreStatus = NtQueryInformationToken( 05416 TokenWithGroups, // TokenHandle 05417 TokenGroups, // TokenInformationClass 05418 PreGroups, // TokenInformation 05419 PreGroupsLength, // TokenInformationLength 05420 &IgnoreReturnLength // ReturnLength 05421 ); 05422 #ifdef TOKEN_DEBUG 05423 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05424 #endif //TOKEN_DEBUG 05425 05426 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05427 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05428 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 05429 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05430 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05431 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05432 05433 NewState->GroupCount = 1; 05434 NewState->Groups[0].Sid = ChildSid; 05435 NewState->Groups[0].Attributes = DisabledGroupAttributes; 05436 05437 Status = NtAdjustGroupsToken( 05438 TokenWithGroups, // TokenHandle 05439 FALSE, // ResetToDefault 05440 NewState, // NewState (OPTIONAL) 05441 0, // BufferLength 05442 NULL, // PreviousState (OPTIONAL) 05443 &ReturnLength // ReturnLength 05444 ); 05445 05446 PostGroups->GroupCount = 88; 05447 IgnoreStatus = NtQueryInformationToken( 05448 TokenWithGroups, // TokenHandle 05449 TokenGroups, // TokenInformationClass 05450 PostGroups, // TokenInformation 05451 PostGroupsLength, // TokenInformationLength 05452 &IgnoreReturnLength // ReturnLength 05453 ); 05454 #ifdef TOKEN_DEBUG 05455 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05456 #endif //TOKEN_DEBUG 05457 05458 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05459 05460 if (Status == STATUS_SUCCESS) { 05461 05462 // 05463 // Check the group values 05464 // 05465 05466 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05467 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05468 (PostGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes) && 05469 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05470 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05471 ) { 05472 05473 DbgPrint("Succeeded. \n"); 05474 05475 } else { 05476 05477 DbgPrint("********** Failed Value Check ************\n"); 05478 DbgPrint("Status is: 0x%lx \n", Status); 05479 05480 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05481 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05482 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05483 05484 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05485 PreGroups->Groups[CHILD_INDEX].Attributes, 05486 PostGroups->Groups[CHILD_INDEX].Attributes); 05487 05488 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05489 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05490 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05491 05492 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05493 PreGroups->Groups[WORLD_INDEX].Attributes, 05494 PostGroups->Groups[WORLD_INDEX].Attributes); 05495 05496 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05497 05498 CompletionStatus = FALSE; 05499 05500 } 05501 05502 } else { 05503 05504 DbgPrint("********** Failed ************\n"); 05505 DbgPrint("Status is: 0x%lx \n", Status); 05506 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05507 CompletionStatus = FALSE; 05508 05509 } 05510 05511 ASSERT(Status == STATUS_SUCCESS); 05512 05513 05514 05516 // // 05517 // Disable already disabled group // 05518 // // 05520 05521 DbgPrint("Se: Disable already disabled group ... "); 05522 05523 PreGroups->GroupCount = 77; 05524 IgnoreStatus = NtQueryInformationToken( 05525 TokenWithGroups, // TokenHandle 05526 TokenGroups, // TokenInformationClass 05527 PreGroups, // TokenInformation 05528 PreGroupsLength, // TokenInformationLength 05529 &IgnoreReturnLength // ReturnLength 05530 ); 05531 #ifdef TOKEN_DEBUG 05532 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05533 #endif //TOKEN_DEBUG 05534 05535 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05536 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05537 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes); 05538 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05539 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05540 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05541 05542 NewState->GroupCount = 1; 05543 NewState->Groups[0].Sid = ChildSid; 05544 NewState->Groups[0].Attributes = 0; 05545 05546 Status = NtAdjustGroupsToken( 05547 TokenWithGroups, // TokenHandle 05548 FALSE, // ResetToDefault 05549 NewState, // NewState (OPTIONAL) 05550 0, // BufferLength 05551 NULL, // PreviousState (OPTIONAL) 05552 &ReturnLength // ReturnLength 05553 ); 05554 05555 PostGroups->GroupCount = 88; 05556 IgnoreStatus = NtQueryInformationToken( 05557 TokenWithGroups, // TokenHandle 05558 TokenGroups, // TokenInformationClass 05559 PostGroups, // TokenInformation 05560 PostGroupsLength, // TokenInformationLength 05561 &IgnoreReturnLength // ReturnLength 05562 ); 05563 #ifdef TOKEN_DEBUG 05564 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05565 #endif //TOKEN_DEBUG 05566 05567 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05568 05569 if (Status == STATUS_SUCCESS) { 05570 05571 // 05572 // Check the group values 05573 // 05574 05575 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05576 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05577 (PostGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes) && 05578 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05579 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05580 ) { 05581 05582 DbgPrint("Succeeded. \n"); 05583 05584 } else { 05585 05586 DbgPrint("********** Failed Value Check ************\n"); 05587 DbgPrint("Status is: 0x%lx \n", Status); 05588 05589 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05590 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05591 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05592 05593 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05594 PreGroups->Groups[CHILD_INDEX].Attributes, 05595 PostGroups->Groups[CHILD_INDEX].Attributes); 05596 05597 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05598 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05599 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05600 05601 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05602 PreGroups->Groups[WORLD_INDEX].Attributes, 05603 PostGroups->Groups[WORLD_INDEX].Attributes); 05604 05605 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05606 05607 CompletionStatus = FALSE; 05608 05609 } 05610 05611 } else { 05612 05613 DbgPrint("********** Failed ************\n"); 05614 DbgPrint("Status is: 0x%lx \n", Status); 05615 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05616 CompletionStatus = FALSE; 05617 05618 } 05619 05620 ASSERT(Status == STATUS_SUCCESS); 05621 05622 05623 05625 // // 05626 // Enable optional group // 05627 // // 05629 05630 DbgPrint("Se: Enable optional group ... "); 05631 05632 PreGroups->GroupCount = 77; 05633 IgnoreStatus = NtQueryInformationToken( 05634 TokenWithGroups, // TokenHandle 05635 TokenGroups, // TokenInformationClass 05636 PreGroups, // TokenInformation 05637 PreGroupsLength, // TokenInformationLength 05638 &IgnoreReturnLength // ReturnLength 05639 ); 05640 #ifdef TOKEN_DEBUG 05641 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05642 #endif //TOKEN_DEBUG 05643 05644 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05645 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05646 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes); 05647 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05648 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05649 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05650 05651 NewState->GroupCount = 1; 05652 NewState->Groups[0].Sid = ChildSid; 05653 NewState->Groups[0].Attributes = SE_GROUP_ENABLED; 05654 05655 Status = NtAdjustGroupsToken( 05656 TokenWithGroups, // TokenHandle 05657 FALSE, // ResetToDefault 05658 NewState, // NewState (OPTIONAL) 05659 0, // BufferLength 05660 NULL, // PreviousState (OPTIONAL) 05661 &ReturnLength // ReturnLength 05662 ); 05663 05664 PostGroups->GroupCount = 88; 05665 IgnoreStatus = NtQueryInformationToken( 05666 TokenWithGroups, // TokenHandle 05667 TokenGroups, // TokenInformationClass 05668 PostGroups, // TokenInformation 05669 PostGroupsLength, // TokenInformationLength 05670 &IgnoreReturnLength // ReturnLength 05671 ); 05672 #ifdef TOKEN_DEBUG 05673 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05674 #endif //TOKEN_DEBUG 05675 05676 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05677 05678 if (Status == STATUS_SUCCESS) { 05679 05680 // 05681 // Check the group values 05682 // 05683 05684 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05685 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05686 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 05687 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05688 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05689 ) { 05690 05691 DbgPrint("Succeeded. \n"); 05692 05693 } else { 05694 05695 DbgPrint("********** Failed Value Check ************\n"); 05696 DbgPrint("Status is: 0x%lx \n", Status); 05697 05698 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05699 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05700 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05701 05702 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05703 PreGroups->Groups[CHILD_INDEX].Attributes, 05704 PostGroups->Groups[CHILD_INDEX].Attributes); 05705 05706 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05707 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05708 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05709 05710 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05711 PreGroups->Groups[WORLD_INDEX].Attributes, 05712 PostGroups->Groups[WORLD_INDEX].Attributes); 05713 05714 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05715 05716 CompletionStatus = FALSE; 05717 05718 } 05719 05720 } else { 05721 05722 DbgPrint("********** Failed ************\n"); 05723 DbgPrint("Status is: 0x%lx \n", Status); 05724 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05725 CompletionStatus = FALSE; 05726 05727 } 05728 05729 ASSERT(Status == STATUS_SUCCESS); 05730 05731 05732 05734 // // 05735 // Enable already enabled group // 05736 // // 05738 05739 DbgPrint("Se: Enable already enabled group ... "); 05740 05741 PreGroups->GroupCount = 77; 05742 IgnoreStatus = NtQueryInformationToken( 05743 TokenWithGroups, // TokenHandle 05744 TokenGroups, // TokenInformationClass 05745 PreGroups, // TokenInformation 05746 PreGroupsLength, // TokenInformationLength 05747 &IgnoreReturnLength // ReturnLength 05748 ); 05749 #ifdef TOKEN_DEBUG 05750 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05751 #endif //TOKEN_DEBUG 05752 05753 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05754 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05755 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 05756 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05757 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05758 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05759 05760 NewState->GroupCount = 1; 05761 NewState->Groups[0].Sid = ChildSid; 05762 NewState->Groups[0].Attributes = SE_GROUP_ENABLED; 05763 05764 Status = NtAdjustGroupsToken( 05765 TokenWithGroups, // TokenHandle 05766 FALSE, // ResetToDefault 05767 NewState, // NewState (OPTIONAL) 05768 0, // BufferLength 05769 NULL, // PreviousState (OPTIONAL) 05770 &ReturnLength // ReturnLength 05771 ); 05772 05773 PostGroups->GroupCount = 88; 05774 IgnoreStatus = NtQueryInformationToken( 05775 TokenWithGroups, // TokenHandle 05776 TokenGroups, // TokenInformationClass 05777 PostGroups, // TokenInformation 05778 PostGroupsLength, // TokenInformationLength 05779 &IgnoreReturnLength // ReturnLength 05780 ); 05781 #ifdef TOKEN_DEBUG 05782 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05783 #endif //TOKEN_DEBUG 05784 05785 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05786 05787 if (Status == STATUS_SUCCESS) { 05788 05789 // 05790 // Check the group values 05791 // 05792 05793 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05794 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05795 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 05796 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05797 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05798 ) { 05799 05800 DbgPrint("Succeeded. \n"); 05801 05802 } else { 05803 05804 DbgPrint("********** Failed Value Check ************\n"); 05805 DbgPrint("Status is: 0x%lx \n", Status); 05806 05807 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05808 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05809 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05810 05811 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05812 PreGroups->Groups[CHILD_INDEX].Attributes, 05813 PostGroups->Groups[CHILD_INDEX].Attributes); 05814 05815 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05816 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05817 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05818 05819 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05820 PreGroups->Groups[WORLD_INDEX].Attributes, 05821 PostGroups->Groups[WORLD_INDEX].Attributes); 05822 05823 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05824 05825 CompletionStatus = FALSE; 05826 05827 } 05828 05829 } else { 05830 05831 DbgPrint("********** Failed ************\n"); 05832 DbgPrint("Status is: 0x%lx \n", Status); 05833 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05834 CompletionStatus = FALSE; 05835 05836 } 05837 05838 ASSERT(Status == STATUS_SUCCESS); 05839 05840 05841 05843 // // 05844 // Disable optional and unknown group // 05845 // // 05847 05848 DbgPrint("Se: Disable optional and unknown group ... "); 05849 05850 PreGroups->GroupCount = 77; 05851 IgnoreStatus = NtQueryInformationToken( 05852 TokenWithGroups, // TokenHandle 05853 TokenGroups, // TokenInformationClass 05854 PreGroups, // TokenInformation 05855 PreGroupsLength, // TokenInformationLength 05856 &IgnoreReturnLength // ReturnLength 05857 ); 05858 #ifdef TOKEN_DEBUG 05859 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05860 #endif //TOKEN_DEBUG 05861 05862 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05863 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05864 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 05865 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05866 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05867 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05868 05869 NewState->GroupCount = 2; 05870 NewState->Groups[0].Sid = ChildSid; 05871 NewState->Groups[1].Sid = RubbleSid; 05872 NewState->Groups[0].Attributes = DisabledGroupAttributes; 05873 NewState->Groups[1].Attributes = DisabledGroupAttributes; 05874 05875 Status = NtAdjustGroupsToken( 05876 TokenWithGroups, // TokenHandle 05877 FALSE, // ResetToDefault 05878 NewState, // NewState (OPTIONAL) 05879 0, // BufferLength 05880 NULL, // PreviousState (OPTIONAL) 05881 &ReturnLength // ReturnLength 05882 ); 05883 05884 PostGroups->GroupCount = 88; 05885 IgnoreStatus = NtQueryInformationToken( 05886 TokenWithGroups, // TokenHandle 05887 TokenGroups, // TokenInformationClass 05888 PostGroups, // TokenInformation 05889 PostGroupsLength, // TokenInformationLength 05890 &IgnoreReturnLength // ReturnLength 05891 ); 05892 #ifdef TOKEN_DEBUG 05893 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05894 #endif //TOKEN_DEBUG 05895 05896 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05897 05898 if (Status == STATUS_NOT_ALL_ASSIGNED) { 05899 05900 // 05901 // Check the group values 05902 // 05903 05904 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 05905 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 05906 (PostGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes) && 05907 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 05908 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 05909 ) { 05910 05911 DbgPrint("Succeeded. \n"); 05912 05913 } else { 05914 05915 DbgPrint("********** Failed Value Check ************\n"); 05916 DbgPrint("Status is: 0x%lx \n", Status); 05917 05918 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 05919 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 05920 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 05921 05922 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 05923 PreGroups->Groups[CHILD_INDEX].Attributes, 05924 PostGroups->Groups[CHILD_INDEX].Attributes); 05925 05926 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 05927 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 05928 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 05929 05930 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 05931 PreGroups->Groups[WORLD_INDEX].Attributes, 05932 PostGroups->Groups[WORLD_INDEX].Attributes); 05933 05934 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05935 05936 CompletionStatus = FALSE; 05937 05938 } 05939 05940 } else { 05941 05942 DbgPrint("********** Failed ************\n"); 05943 DbgPrint("Status is: 0x%lx \n", Status); 05944 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 05945 CompletionStatus = FALSE; 05946 05947 } 05948 05949 ASSERT(Status == STATUS_NOT_ALL_ASSIGNED); 05950 05951 05952 05953 05955 // // 05956 // Enable optional and unknown group // 05957 // // 05959 05960 DbgPrint("Se: Enable optional and unknown group ... "); 05961 05962 PreGroups->GroupCount = 77; 05963 IgnoreStatus = NtQueryInformationToken( 05964 TokenWithGroups, // TokenHandle 05965 TokenGroups, // TokenInformationClass 05966 PreGroups, // TokenInformation 05967 PreGroupsLength, // TokenInformationLength 05968 &IgnoreReturnLength // ReturnLength 05969 ); 05970 #ifdef TOKEN_DEBUG 05971 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 05972 #endif //TOKEN_DEBUG 05973 05974 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 05975 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 05976 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes); 05977 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 05978 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 05979 ASSERT(NT_SUCCESS(IgnoreStatus) ); 05980 05981 NewState->GroupCount = 2; 05982 NewState->Groups[0].Sid = ChildSid; 05983 NewState->Groups[1].Sid = RubbleSid; 05984 NewState->Groups[0].Attributes = OptionalGroupAttributes; 05985 NewState->Groups[1].Attributes = OptionalGroupAttributes; 05986 05987 Status = NtAdjustGroupsToken( 05988 TokenWithGroups, // TokenHandle 05989 FALSE, // ResetToDefault 05990 NewState, // NewState (OPTIONAL) 05991 0, // BufferLength 05992 NULL, // PreviousState (OPTIONAL) 05993 &ReturnLength // ReturnLength 05994 ); 05995 05996 PostGroups->GroupCount = 88; 05997 IgnoreStatus = NtQueryInformationToken( 05998 TokenWithGroups, // TokenHandle 05999 TokenGroups, // TokenInformationClass 06000 PostGroups, // TokenInformation 06001 PostGroupsLength, // TokenInformationLength 06002 &IgnoreReturnLength // ReturnLength 06003 ); 06004 #ifdef TOKEN_DEBUG 06005 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06006 #endif //TOKEN_DEBUG 06007 06008 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06009 06010 if (Status == STATUS_NOT_ALL_ASSIGNED) { 06011 06012 // 06013 // Check the group values 06014 // 06015 06016 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06017 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06018 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 06019 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 06020 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 06021 ) { 06022 06023 DbgPrint("Succeeded. \n"); 06024 06025 } else { 06026 06027 DbgPrint("********** Failed Value Check ************\n"); 06028 DbgPrint("Status is: 0x%lx \n", Status); 06029 06030 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06031 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06032 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06033 06034 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06035 PreGroups->Groups[CHILD_INDEX].Attributes, 06036 PostGroups->Groups[CHILD_INDEX].Attributes); 06037 06038 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06039 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06040 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06041 06042 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06043 PreGroups->Groups[WORLD_INDEX].Attributes, 06044 PostGroups->Groups[WORLD_INDEX].Attributes); 06045 06046 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06047 06048 CompletionStatus = FALSE; 06049 06050 } 06051 06052 } else { 06053 06054 DbgPrint("********** Failed ************\n"); 06055 DbgPrint("Status is: 0x%lx \n", Status); 06056 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06057 CompletionStatus = FALSE; 06058 06059 } 06060 06061 ASSERT(Status == STATUS_NOT_ALL_ASSIGNED); 06062 06063 06064 06065 06067 // // 06068 // Disable optional and mandatory group // 06069 // // 06071 06072 DbgPrint("Se: Disable optional and mandatory group ... "); 06073 06074 PreGroups->GroupCount = 77; 06075 IgnoreStatus = NtQueryInformationToken( 06076 TokenWithGroups, // TokenHandle 06077 TokenGroups, // TokenInformationClass 06078 PreGroups, // TokenInformation 06079 PreGroupsLength, // TokenInformationLength 06080 &IgnoreReturnLength // ReturnLength 06081 ); 06082 #ifdef TOKEN_DEBUG 06083 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06084 #endif //TOKEN_DEBUG 06085 06086 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06087 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06088 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 06089 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 06090 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06091 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06092 06093 NewState->GroupCount = 2; 06094 NewState->Groups[0].Sid = ChildSid; 06095 NewState->Groups[1].Sid = WorldSid; 06096 NewState->Groups[0].Attributes = DisabledGroupAttributes; 06097 NewState->Groups[1].Attributes = DisabledGroupAttributes; 06098 06099 Status = NtAdjustGroupsToken( 06100 TokenWithGroups, // TokenHandle 06101 FALSE, // ResetToDefault 06102 NewState, // NewState (OPTIONAL) 06103 0, // BufferLength 06104 NULL, // PreviousState (OPTIONAL) 06105 &ReturnLength // ReturnLength 06106 ); 06107 06108 PostGroups->GroupCount = 88; 06109 IgnoreStatus = NtQueryInformationToken( 06110 TokenWithGroups, // TokenHandle 06111 TokenGroups, // TokenInformationClass 06112 PostGroups, // TokenInformation 06113 PostGroupsLength, // TokenInformationLength 06114 &IgnoreReturnLength // ReturnLength 06115 ); 06116 #ifdef TOKEN_DEBUG 06117 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06118 #endif //TOKEN_DEBUG 06119 06120 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06121 06122 if (Status == STATUS_CANT_DISABLE_MANDATORY) { 06123 06124 // 06125 // Check the group values 06126 // 06127 06128 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06129 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06130 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 06131 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 06132 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 06133 ) { 06134 06135 DbgPrint("Succeeded. \n"); 06136 06137 } else { 06138 06139 DbgPrint("********** Failed Value Check ************\n"); 06140 DbgPrint("Status is: 0x%lx \n", Status); 06141 06142 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06143 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06144 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06145 06146 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06147 PreGroups->Groups[CHILD_INDEX].Attributes, 06148 PostGroups->Groups[CHILD_INDEX].Attributes); 06149 06150 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06151 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06152 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06153 06154 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06155 PreGroups->Groups[WORLD_INDEX].Attributes, 06156 PostGroups->Groups[WORLD_INDEX].Attributes); 06157 06158 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06159 06160 CompletionStatus = FALSE; 06161 06162 } 06163 06164 } else { 06165 06166 DbgPrint("********** Failed ************\n"); 06167 DbgPrint("Status is: 0x%lx \n", Status); 06168 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06169 CompletionStatus = FALSE; 06170 06171 } 06172 06173 ASSERT(Status == STATUS_CANT_DISABLE_MANDATORY); 06174 06175 06176 06178 // // 06179 // Enable optional and mandatory group // 06180 // // 06182 06183 DbgPrint("Se: Enable optional and mandatory group ... "); 06184 06185 NewState->GroupCount = 1; 06186 NewState->Groups[0].Sid = ChildSid; 06187 NewState->Groups[0].Attributes = DisabledGroupAttributes; 06188 06189 Status = NtAdjustGroupsToken( 06190 TokenWithGroups, // TokenHandle 06191 FALSE, // ResetToDefault 06192 NewState, // NewState (OPTIONAL) 06193 0, // BufferLength 06194 NULL, // PreviousState (OPTIONAL) 06195 &ReturnLength // ReturnLength 06196 ); 06197 ASSERT(Status == STATUS_SUCCESS); 06198 06199 PreGroups->GroupCount = 77; 06200 IgnoreStatus = NtQueryInformationToken( 06201 TokenWithGroups, // TokenHandle 06202 TokenGroups, // TokenInformationClass 06203 PreGroups, // TokenInformation 06204 PreGroupsLength, // TokenInformationLength 06205 &IgnoreReturnLength // ReturnLength 06206 ); 06207 #ifdef TOKEN_DEBUG 06208 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06209 #endif //TOKEN_DEBUG 06210 06211 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06212 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06213 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes); 06214 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 06215 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06216 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06217 06218 NewState->GroupCount = 2; 06219 NewState->Groups[0].Sid = ChildSid; 06220 NewState->Groups[1].Sid = WorldSid; 06221 NewState->Groups[0].Attributes = OptionalGroupAttributes; 06222 NewState->Groups[1].Attributes = OptionalGroupAttributes; 06223 06224 Status = NtAdjustGroupsToken( 06225 TokenWithGroups, // TokenHandle 06226 FALSE, // ResetToDefault 06227 NewState, // NewState (OPTIONAL) 06228 0, // BufferLength 06229 NULL, // PreviousState (OPTIONAL) 06230 &ReturnLength // ReturnLength 06231 ); 06232 06233 PostGroups->GroupCount = 88; 06234 IgnoreStatus = NtQueryInformationToken( 06235 TokenWithGroups, // TokenHandle 06236 TokenGroups, // TokenInformationClass 06237 PostGroups, // TokenInformation 06238 PostGroupsLength, // TokenInformationLength 06239 &IgnoreReturnLength // ReturnLength 06240 ); 06241 #ifdef TOKEN_DEBUG 06242 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06243 #endif //TOKEN_DEBUG 06244 06245 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06246 06247 if (Status == STATUS_SUCCESS) { 06248 06249 // 06250 // Check the group values 06251 // 06252 06253 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06254 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06255 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 06256 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 06257 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 06258 ) { 06259 06260 DbgPrint("Succeeded. \n"); 06261 06262 } else { 06263 06264 DbgPrint("********** Failed Value Check ************\n"); 06265 DbgPrint("Status is: 0x%lx \n", Status); 06266 06267 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06268 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06269 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06270 06271 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06272 PreGroups->Groups[CHILD_INDEX].Attributes, 06273 PostGroups->Groups[CHILD_INDEX].Attributes); 06274 06275 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06276 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06277 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06278 06279 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06280 PreGroups->Groups[WORLD_INDEX].Attributes, 06281 PostGroups->Groups[WORLD_INDEX].Attributes); 06282 06283 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06284 06285 CompletionStatus = FALSE; 06286 06287 } 06288 06289 } else { 06290 06291 DbgPrint("********** Failed ************\n"); 06292 DbgPrint("Status is: 0x%lx \n", Status); 06293 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06294 CompletionStatus = FALSE; 06295 06296 } 06297 06298 ASSERT(Status == STATUS_SUCCESS); 06299 06300 06301 06303 // // 06304 // Disable optional group requesting previous state with // 06305 // insufficient buffer // 06306 // // 06308 06309 06310 DbgPrint("Se: Too small buffer for previous state ... "); 06311 06312 06313 PreGroups->GroupCount = 77; 06314 IgnoreStatus = NtQueryInformationToken( 06315 TokenWithGroups, // TokenHandle 06316 TokenGroups, // TokenInformationClass 06317 PreGroups, // TokenInformation 06318 PreGroupsLength, // TokenInformationLength 06319 &IgnoreReturnLength // ReturnLength 06320 ); 06321 #ifdef TOKEN_DEBUG 06322 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06323 #endif //TOKEN_DEBUG 06324 06325 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06326 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06327 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 06328 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 06329 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06330 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06331 06332 NewState->GroupCount = 1; 06333 NewState->Groups[0].Sid = ChildSid; 06334 NewState->Groups[0].Attributes = DisabledGroupAttributes; 06335 06336 Status = NtAdjustGroupsToken( 06337 TokenWithGroups, // TokenHandle 06338 FALSE, // ResetToDefault 06339 NewState, // NewState (OPTIONAL) 06340 0, // BufferLength 06341 PreviousState, // PreviousState (OPTIONAL) 06342 &ReturnLength // ReturnLength 06343 ); 06344 #ifdef TOKEN_DEBUG 06345 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 06346 #endif //TOKEN_DEBUG 06347 06348 PostGroups->GroupCount = 88; 06349 IgnoreStatus = NtQueryInformationToken( 06350 TokenWithGroups, // TokenHandle 06351 TokenGroups, // TokenInformationClass 06352 PostGroups, // TokenInformation 06353 PostGroupsLength, // TokenInformationLength 06354 &IgnoreReturnLength // ReturnLength 06355 ); 06356 #ifdef TOKEN_DEBUG 06357 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06358 #endif //TOKEN_DEBUG 06359 06360 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06361 06362 if (Status == STATUS_BUFFER_TOO_SMALL) { 06363 06364 // 06365 // Check the group values 06366 // 06367 06368 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06369 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06370 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 06371 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 06372 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 06373 ) { 06374 06375 DbgPrint("Succeeded. \n"); 06376 06377 } else { 06378 06379 DbgPrint("********** Failed Value Check ************\n"); 06380 DbgPrint("Status is: 0x%lx \n", Status); 06381 06382 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06383 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06384 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06385 06386 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06387 PreGroups->Groups[CHILD_INDEX].Attributes, 06388 PostGroups->Groups[CHILD_INDEX].Attributes); 06389 06390 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06391 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06392 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06393 06394 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06395 PreGroups->Groups[WORLD_INDEX].Attributes, 06396 PostGroups->Groups[WORLD_INDEX].Attributes); 06397 06398 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06399 06400 CompletionStatus = FALSE; 06401 06402 } 06403 06404 } else { 06405 06406 DbgPrint("********** Failed ************\n"); 06407 DbgPrint("Status is: 0x%lx \n", Status); 06408 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06409 CompletionStatus = FALSE; 06410 06411 } 06412 06413 ASSERT(Status == STATUS_BUFFER_TOO_SMALL); 06414 06415 06416 06417 06419 // // 06420 // Disable optional requesting previous state // 06421 // // 06423 06424 DbgPrint("Se: Disable optional, requesting previous state ... "); 06425 06426 PreGroups->GroupCount = 77; 06427 IgnoreStatus = NtQueryInformationToken( 06428 TokenWithGroups, // TokenHandle 06429 TokenGroups, // TokenInformationClass 06430 PreGroups, // TokenInformation 06431 PreGroupsLength, // TokenInformationLength 06432 &IgnoreReturnLength // ReturnLength 06433 ); 06434 #ifdef TOKEN_DEBUG 06435 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06436 #endif //TOKEN_DEBUG 06437 06438 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06439 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06440 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 06441 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 06442 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06443 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06444 06445 NewState->GroupCount = 2; 06446 NewState->Groups[0].Sid = NeandertholSid; 06447 NewState->Groups[1].Sid = ChildSid; 06448 NewState->Groups[0].Attributes = DisabledGroupAttributes; 06449 NewState->Groups[1].Attributes = DisabledGroupAttributes; 06450 PreviousState->GroupCount = 99; 06451 06452 Status = NtAdjustGroupsToken( 06453 TokenWithGroups, // TokenHandle 06454 FALSE, // ResetToDefault 06455 NewState, // NewState (OPTIONAL) 06456 PreviousStateBufferLength, // BufferLength 06457 PreviousState, // PreviousState (OPTIONAL) 06458 &ReturnLength // ReturnLength 06459 ); 06460 #ifdef TOKEN_DEBUG 06461 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 06462 #endif //TOKEN_DEBUG 06463 06464 PostGroups->GroupCount = 88; 06465 IgnoreStatus = NtQueryInformationToken( 06466 TokenWithGroups, // TokenHandle 06467 TokenGroups, // TokenInformationClass 06468 PostGroups, // TokenInformation 06469 PostGroupsLength, // TokenInformationLength 06470 &IgnoreReturnLength // ReturnLength 06471 ); 06472 #ifdef TOKEN_DEBUG 06473 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06474 #endif //TOKEN_DEBUG 06475 06476 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06477 06478 if (Status == STATUS_SUCCESS) { 06479 06480 // 06481 // Check the group values 06482 // 06483 06484 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06485 ASSERT( PreviousState->GroupCount == 2 ); 06486 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06487 (PostGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes) && 06488 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == DisabledGroupAttributes) && 06489 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) && 06490 (PreviousState->Groups[0].Attributes == OptionalGroupAttributes) && 06491 (PreviousState->Groups[1].Attributes == OptionalGroupAttributes) 06492 ) { 06493 06494 DbgPrint("Succeeded. \n"); 06495 06496 } else { 06497 06498 DbgPrint("********** Failed Value Check ************\n"); 06499 DbgPrint("Status is: 0x%lx \n", Status); 06500 06501 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06502 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06503 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06504 06505 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06506 PreGroups->Groups[CHILD_INDEX].Attributes, 06507 PostGroups->Groups[CHILD_INDEX].Attributes); 06508 06509 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06510 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06511 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06512 06513 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06514 PreGroups->Groups[WORLD_INDEX].Attributes, 06515 PostGroups->Groups[WORLD_INDEX].Attributes); 06516 06517 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06518 06519 DbgPrint("Previous count is: 0x%lx \n", PreviousState->GroupCount); 06520 DbgPrint("Previous state of group 0 is: 0x%lx \n", 06521 PreviousState->Groups[0].Attributes); 06522 DbgPrint("Previous state of group 1 is: 0x%lx \n", 06523 PreviousState->Groups[1].Attributes); 06524 06525 06526 CompletionStatus = FALSE; 06527 06528 } 06529 06530 } else { 06531 06532 DbgPrint("********** Failed ************\n"); 06533 DbgPrint("Status is: 0x%lx \n", Status); 06534 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06535 CompletionStatus = FALSE; 06536 06537 } 06538 06539 ASSERT(Status == STATUS_SUCCESS); 06540 06541 06542 06544 // // 06545 // Return group to previous state // 06546 // // 06548 06549 DbgPrint("Se: Return to previous state ... "); 06550 06551 PreGroups->GroupCount = 77; 06552 IgnoreStatus = NtQueryInformationToken( 06553 TokenWithGroups, // TokenHandle 06554 TokenGroups, // TokenInformationClass 06555 PreGroups, // TokenInformation 06556 PreGroupsLength, // TokenInformationLength 06557 &IgnoreReturnLength // ReturnLength 06558 ); 06559 #ifdef TOKEN_DEBUG 06560 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06561 #endif //TOKEN_DEBUG 06562 06563 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06564 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06565 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes); 06566 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == DisabledGroupAttributes); 06567 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06568 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06569 06570 Status = NtAdjustGroupsToken( 06571 TokenWithGroups, // TokenHandle 06572 FALSE, // ResetToDefault 06573 PreviousState, // NewState (OPTIONAL) 06574 PreviousStateBufferLength, // BufferLength 06575 PreviousState, // PreviousState (OPTIONAL) 06576 &ReturnLength // ReturnLength 06577 ); 06578 #ifdef TOKEN_DEBUG 06579 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 06580 #endif //TOKEN_DEBUG 06581 06582 PostGroups->GroupCount = 88; 06583 IgnoreStatus = NtQueryInformationToken( 06584 TokenWithGroups, // TokenHandle 06585 TokenGroups, // TokenInformationClass 06586 PostGroups, // TokenInformation 06587 PostGroupsLength, // TokenInformationLength 06588 &IgnoreReturnLength // ReturnLength 06589 ); 06590 #ifdef TOKEN_DEBUG 06591 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06592 #endif //TOKEN_DEBUG 06593 06594 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06595 06596 if (Status == STATUS_SUCCESS) { 06597 06598 // 06599 // Check the group values 06600 // 06601 06602 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06603 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06604 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 06605 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 06606 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) && 06607 (PreviousState->Groups[0].Attributes == DisabledGroupAttributes) && 06608 (PreviousState->Groups[1].Attributes == DisabledGroupAttributes) 06609 ) { 06610 06611 DbgPrint("Succeeded. \n"); 06612 06613 } else { 06614 06615 DbgPrint("********** Failed Value Check ************\n"); 06616 DbgPrint("Status is: 0x%lx \n", Status); 06617 06618 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06619 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06620 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06621 06622 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06623 PreGroups->Groups[CHILD_INDEX].Attributes, 06624 PostGroups->Groups[CHILD_INDEX].Attributes); 06625 06626 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06627 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06628 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06629 06630 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06631 PreGroups->Groups[WORLD_INDEX].Attributes, 06632 PostGroups->Groups[WORLD_INDEX].Attributes); 06633 06634 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06635 06636 CompletionStatus = FALSE; 06637 06638 } 06639 06640 } else { 06641 06642 DbgPrint("********** Failed ************\n"); 06643 DbgPrint("Status is: 0x%lx \n", Status); 06644 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06645 CompletionStatus = FALSE; 06646 06647 } 06648 06649 ASSERT(Status == STATUS_SUCCESS); 06650 06651 06652 06654 // // 06655 // Return to previous state again // 06656 // // 06658 06659 DbgPrint("Se: Return to previous state again ... "); 06660 06661 PreGroups->GroupCount = 77; 06662 IgnoreStatus = NtQueryInformationToken( 06663 TokenWithGroups, // TokenHandle 06664 TokenGroups, // TokenInformationClass 06665 PreGroups, // TokenInformation 06666 PreGroupsLength, // TokenInformationLength 06667 &IgnoreReturnLength // ReturnLength 06668 ); 06669 #ifdef TOKEN_DEBUG 06670 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06671 #endif //TOKEN_DEBUG 06672 06673 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06674 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06675 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes); 06676 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes); 06677 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06678 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06679 06680 Status = NtAdjustGroupsToken( 06681 TokenWithGroups, // TokenHandle 06682 FALSE, // ResetToDefault 06683 PreviousState, // NewState (OPTIONAL) 06684 PreviousStateBufferLength, // BufferLength 06685 PreviousState, // PreviousState (OPTIONAL) 06686 &ReturnLength // ReturnLength 06687 ); 06688 #ifdef TOKEN_DEBUG 06689 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 06690 #endif //TOKEN_DEBUG 06691 06692 PostGroups->GroupCount = 88; 06693 IgnoreStatus = NtQueryInformationToken( 06694 TokenWithGroups, // TokenHandle 06695 TokenGroups, // TokenInformationClass 06696 PostGroups, // TokenInformation 06697 PostGroupsLength, // TokenInformationLength 06698 &IgnoreReturnLength // ReturnLength 06699 ); 06700 #ifdef TOKEN_DEBUG 06701 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06702 #endif //TOKEN_DEBUG 06703 06704 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06705 06706 if (Status == STATUS_SUCCESS) { 06707 06708 // 06709 // Check the group values 06710 // 06711 06712 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06713 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06714 (PostGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes) && 06715 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == DisabledGroupAttributes) && 06716 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) && 06717 (PreviousState->Groups[0].Attributes == OptionalGroupAttributes) && 06718 (PreviousState->Groups[1].Attributes == OptionalGroupAttributes) 06719 ) { 06720 06721 DbgPrint("Succeeded. \n"); 06722 06723 } else { 06724 06725 DbgPrint("********** Failed Value Check ************\n"); 06726 DbgPrint("Status is: 0x%lx \n", Status); 06727 06728 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06729 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06730 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06731 06732 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06733 PreGroups->Groups[CHILD_INDEX].Attributes, 06734 PostGroups->Groups[CHILD_INDEX].Attributes); 06735 06736 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06737 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06738 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06739 06740 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06741 PreGroups->Groups[WORLD_INDEX].Attributes, 06742 PostGroups->Groups[WORLD_INDEX].Attributes); 06743 06744 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06745 06746 CompletionStatus = FALSE; 06747 06748 } 06749 06750 } else { 06751 06752 DbgPrint("********** Failed ************\n"); 06753 DbgPrint("Status is: 0x%lx \n", Status); 06754 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06755 CompletionStatus = FALSE; 06756 06757 } 06758 06759 ASSERT(Status == STATUS_SUCCESS); 06760 06761 06762 06763 06765 // // 06766 // Return to default state (capture previous state) // 06767 // // 06769 06770 DbgPrint("Se: Return to default state (w/previous state) ... "); 06771 06772 PreGroups->GroupCount = 77; 06773 IgnoreStatus = NtQueryInformationToken( 06774 TokenWithGroups, // TokenHandle 06775 TokenGroups, // TokenInformationClass 06776 PreGroups, // TokenInformation 06777 PreGroupsLength, // TokenInformationLength 06778 &IgnoreReturnLength // ReturnLength 06779 ); 06780 #ifdef TOKEN_DEBUG 06781 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06782 #endif //TOKEN_DEBUG 06783 06784 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06785 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06786 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes); 06787 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == DisabledGroupAttributes); 06788 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06789 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06790 06791 Status = NtAdjustGroupsToken( 06792 TokenWithGroups, // TokenHandle 06793 TRUE, // ResetToDefault 06794 NULL, // NewState (OPTIONAL) 06795 PreviousStateBufferLength, // BufferLength 06796 PreviousState, // PreviousState (OPTIONAL) 06797 &ReturnLength // ReturnLength 06798 ); 06799 #ifdef TOKEN_DEBUG 06800 DbgPrint("\n (debug) return length: 0x%lx \n", ReturnLength); 06801 #endif //TOKEN_DEBUG 06802 06803 PostGroups->GroupCount = 88; 06804 IgnoreStatus = NtQueryInformationToken( 06805 TokenWithGroups, // TokenHandle 06806 TokenGroups, // TokenInformationClass 06807 PostGroups, // TokenInformation 06808 PostGroupsLength, // TokenInformationLength 06809 &IgnoreReturnLength // ReturnLength 06810 ); 06811 #ifdef TOKEN_DEBUG 06812 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06813 #endif //TOKEN_DEBUG 06814 06815 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06816 06817 if (Status == STATUS_SUCCESS) { 06818 06819 // 06820 // Check the group values 06821 // 06822 06823 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06824 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06825 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 06826 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 06827 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) && 06828 (PreviousState->Groups[0].Attributes == DisabledGroupAttributes) && 06829 (PreviousState->Groups[1].Attributes == DisabledGroupAttributes) 06830 ) { 06831 06832 DbgPrint("Succeeded. \n"); 06833 06834 } else { 06835 06836 DbgPrint("********** Failed Value Check ************\n"); 06837 DbgPrint("Status is: 0x%lx \n", Status); 06838 06839 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06840 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06841 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06842 06843 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06844 PreGroups->Groups[CHILD_INDEX].Attributes, 06845 PostGroups->Groups[CHILD_INDEX].Attributes); 06846 06847 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06848 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06849 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06850 06851 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06852 PreGroups->Groups[WORLD_INDEX].Attributes, 06853 PostGroups->Groups[WORLD_INDEX].Attributes); 06854 06855 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06856 06857 CompletionStatus = FALSE; 06858 06859 } 06860 06861 } else { 06862 06863 DbgPrint("********** Failed ************\n"); 06864 DbgPrint("Status is: 0x%lx \n", Status); 06865 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06866 CompletionStatus = FALSE; 06867 06868 } 06869 06870 ASSERT(Status == STATUS_SUCCESS); 06871 06872 06873 06875 // // 06876 // Return to default state (don't capture previous state) // 06877 // // 06879 06880 DbgPrint("Se: Return to default state (no previous state) ... "); 06881 06882 Status = NtAdjustGroupsToken( 06883 TokenWithGroups, // TokenHandle 06884 FALSE, // ResetToDefault 06885 PreviousState, // NewState (OPTIONAL) 06886 0, // BufferLength 06887 NULL, // PreviousState (OPTIONAL) 06888 &ReturnLength // ReturnLength 06889 ); 06890 06891 ASSERT(Status == STATUS_SUCCESS); 06892 06893 PreGroups->GroupCount = 77; 06894 IgnoreStatus = NtQueryInformationToken( 06895 TokenWithGroups, // TokenHandle 06896 TokenGroups, // TokenInformationClass 06897 PreGroups, // TokenInformation 06898 PreGroupsLength, // TokenInformationLength 06899 &IgnoreReturnLength // ReturnLength 06900 ); 06901 #ifdef TOKEN_DEBUG 06902 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06903 #endif //TOKEN_DEBUG 06904 06905 ASSERT(PreGroups->GroupCount == GROUP_COUNT ); 06906 ASSERT(PreGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes); 06907 ASSERT(PreGroups->Groups[CHILD_INDEX].Attributes == DisabledGroupAttributes); 06908 ASSERT(PreGroups->Groups[NEANDERTHOL_INDEX].Attributes == DisabledGroupAttributes); 06909 ASSERT(PreGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes); 06910 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06911 06912 Status = NtAdjustGroupsToken( 06913 TokenWithGroups, // TokenHandle 06914 TRUE, // ResetToDefault 06915 NULL, // NewState (OPTIONAL) 06916 0, // BufferLength 06917 NULL, // PreviousState (OPTIONAL) 06918 &ReturnLength // ReturnLength 06919 ); 06920 06921 PostGroups->GroupCount = 88; 06922 IgnoreStatus = NtQueryInformationToken( 06923 TokenWithGroups, // TokenHandle 06924 TokenGroups, // TokenInformationClass 06925 PostGroups, // TokenInformation 06926 PostGroupsLength, // TokenInformationLength 06927 &IgnoreReturnLength // ReturnLength 06928 ); 06929 #ifdef TOKEN_DEBUG 06930 DbgPrint("\n (debug) ignore return length: 0x%lx \n", IgnoreReturnLength); 06931 #endif //TOKEN_DEBUG 06932 06933 ASSERT(NT_SUCCESS(IgnoreStatus) ); 06934 06935 if (Status == STATUS_SUCCESS) { 06936 06937 // 06938 // Check the group values 06939 // 06940 06941 ASSERT( PostGroups->GroupCount == GROUP_COUNT ); 06942 if ( (PostGroups->Groups[FLINTSTONE_INDEX].Attributes == OwnerGroupAttributes) && 06943 (PostGroups->Groups[CHILD_INDEX].Attributes == OptionalGroupAttributes) && 06944 (PostGroups->Groups[NEANDERTHOL_INDEX].Attributes == OptionalGroupAttributes) && 06945 (PostGroups->Groups[WORLD_INDEX].Attributes == NormalGroupAttributes) 06946 ) { 06947 06948 DbgPrint("Succeeded. \n"); 06949 06950 } else { 06951 06952 DbgPrint("********** Failed Value Check ************\n"); 06953 DbgPrint("Status is: 0x%lx \n", Status); 06954 06955 DbgPrint("Before/after Flintstone state: 0x%lx / 0x%lx \n", 06956 PreGroups->Groups[FLINTSTONE_INDEX].Attributes, 06957 PostGroups->Groups[FLINTSTONE_INDEX].Attributes); 06958 06959 DbgPrint("Before/after Child state: 0x%lx / 0x%lx \n", 06960 PreGroups->Groups[CHILD_INDEX].Attributes, 06961 PostGroups->Groups[CHILD_INDEX].Attributes); 06962 06963 DbgPrint("Before/after Neanderthol state: 0x%lx / 0x%lx \n", 06964 PreGroups->Groups[NEANDERTHOL_INDEX].Attributes, 06965 PostGroups->Groups[NEANDERTHOL_INDEX].Attributes); 06966 06967 DbgPrint("Before/after World state: 0x%lx / 0x%lx \n", 06968 PreGroups->Groups[WORLD_INDEX].Attributes, 06969 PostGroups->Groups[WORLD_INDEX].Attributes); 06970 06971 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06972 06973 CompletionStatus = FALSE; 06974 06975 } 06976 06977 } else { 06978 06979 DbgPrint("********** Failed ************\n"); 06980 DbgPrint("Status is: 0x%lx \n", Status); 06981 DbgPrint("Return Length is: 0x%lx \n", ReturnLength); 06982 CompletionStatus = FALSE; 06983 06984 } 06985 06986 ASSERT(Status == STATUS_SUCCESS); 06987 06988 06989 06990 06992 // // 06993 // Done with test // 06994 // // 06996 06997 06998 06999 TstDeallocatePool( PreviousState, PreviousStateBufferLength ); 07000 TstDeallocatePool( NewState, NewStateBufferLength ); 07001 TstDeallocatePool( PreGroups, PreGroupsLength ); 07002 TstDeallocatePool( PostGroups, PostGroupsLength ); 07003 07004 07005 return CompletionStatus; 07006 } 07007 07008 07010 // // 07011 // Compare duplicate to original token & display test results // 07012 // // 07014 07015 BOOLEAN 07016 TestpCompareDuplicateToken( 07017 IN NTSTATUS Status, 07018 IN HANDLE OldToken, 07019 IN OBJECT_ATTRIBUTES NewAttributes, 07020 IN BOOLEAN EffectiveOnly, 07021 IN TOKEN_TYPE NewType, 07022 IN HANDLE NewToken 07023 ) 07024 07025 { 07026 BOOLEAN CompletionStatus = TRUE; 07027 07028 ULONG OldReturnLength; 07029 ULONG NewReturnLength; 07030 07031 PTOKEN_USER OldUserId = NULL; 07032 PTOKEN_USER NewUserId = NULL; 07033 07034 TOKEN_SOURCE OldSource; 07035 TOKEN_SOURCE NewSource; 07036 07037 TOKEN_STATISTICS OldStatistics; 07038 TOKEN_STATISTICS NewStatistics; 07039 07040 BOOLEAN SomeNotCompared = FALSE; 07041 07042 07043 // 07044 // Appease the compiler Gods 07045 // 07046 NewAttributes = NewAttributes; 07047 NewType = NewType; 07048 EffectiveOnly = EffectiveOnly; 07049 07050 07051 // 07052 // If the status isn't success, don't bother comparing the tokens 07053 // 07054 07055 if (!NT_SUCCESS(Status)) { 07056 07057 DbgPrint("********** Failed ************\n"); 07058 DbgPrint("Status is: 0x%lx \n", Status); 07059 return FALSE; 07060 } 07061 07062 // 07063 // Compare the user IDs 07064 // 07065 07066 Status = NtQueryInformationToken( 07067 OldToken, // Handle 07068 TokenUser, // TokenInformationClass 07069 OldUserId, // TokenInformation 07070 0, // TokenInformationLength 07071 &OldReturnLength // ReturnLength 07072 ); ASSERT(Status == STATUS_BUFFER_TOO_SMALL); 07073 OldUserId = (PTOKEN_USER)TstAllocatePool( PagedPool, OldReturnLength ); 07074 07075 Status = NtQueryInformationToken( 07076 OldToken, // Handle 07077 TokenUser, // TokenInformationClass 07078 OldUserId, // TokenInformation 07079 OldReturnLength, // TokenInformationLength 07080 &OldReturnLength // ReturnLength 07081 ); ASSERT(NT_SUCCESS(Status)); 07082 07083 07084 Status = NtQueryInformationToken( 07085 NewToken, // Handle 07086 TokenUser, // TokenInformationClass 07087 NewUserId, // TokenInformation 07088 0, // TokenInformationLength 07089 &NewReturnLength // ReturnLength 07090 ); ASSERT(Status == STATUS_BUFFER_TOO_SMALL); 07091 07092 NewUserId = (PTOKEN_USER)TstAllocatePool( PagedPool, NewReturnLength ); 07093 07094 Status = NtQueryInformationToken( 07095 NewToken, // Handle 07096 TokenUser, // TokenInformationClass 07097 NewUserId, // TokenInformation 07098 NewReturnLength, // TokenInformationLength 07099 &NewReturnLength // ReturnLength 07100 ); ASSERT(NT_SUCCESS(Status)); 07101 07102 07103 if ( !RtlEqualSid(OldUserId->User.Sid, NewUserId->User.Sid) ) { 07104 07105 if (CompletionStatus) { 07106 DbgPrint("*** Failed Value Comparison ***\n"); 07107 } 07108 DbgPrint("User IDs don't match.\n"); 07109 CompletionStatus = FALSE; 07110 } 07111 07112 TstDeallocatePool( OldUserId, OldReturnLength ); 07113 TstDeallocatePool( NewUserId, NewReturnLength ); 07114 07115 07116 // 07117 // Check the token statistics 07118 // 07119 07120 if (CompletionStatus) { 07121 Status = NtQueryInformationToken( 07122 OldToken, // Handle 07123 TokenStatistics, // TokenInformationClass 07124 &OldStatistics, // TokenInformation 07125 (ULONG)sizeof(TOKEN_STATISTICS), // TokenInformationLength 07126 &OldReturnLength // ReturnLength 07127 ); ASSERT(NT_SUCCESS(Status)); 07128 07129 Status = NtQueryInformationToken( 07130 NewToken, // Handle 07131 TokenStatistics, // TokenInformationClass 07132 &NewStatistics, // TokenInformation 07133 (ULONG)sizeof(TOKEN_STATISTICS), // TokenInformationLength 07134 &NewReturnLength // ReturnLength 07135 ); ASSERT(NT_SUCCESS(Status)); 07136 // 07137 // Must have: 07138 // Different TokenId values 07139 // Same authenticationId value 07140 // Same ExpirationTime 07141 // Same token type 07142 // Same ImpersonationLevel (if correct token type) 07143 // Same DynamicCharged & DynamicAvailable 07144 // 07145 // GroupCount and PrivilegeCount are deferred to the group and 07146 // privilege comparison due to the difficulty involved with 07147 // taking EffectiveOnly into account. 07148 // 07149 // The new token must have a ModifiedId that is the same as the 07150 // original. 07151 // 07152 07153 // 07154 // Token ID 07155 // 07156 07157 if ( (OldStatistics.TokenId.HighPart == 07158 NewStatistics.TokenId.HighPart) && 07159 (OldStatistics.TokenId.LowPart == 07160 NewStatistics.TokenId.LowPart) ) { 07161 07162 DbgPrint("*** Failed ***\n"); 07163 DbgPrint(" TokenIds are equal.\n"); 07164 DbgPrint(" Old TokenId is: (0x%xl, 0x%xl)\n", 07165 OldStatistics.TokenId.HighPart, 07166 OldStatistics.TokenId.LowPart); 07167 DbgPrint(" New TokenId is: (0x%xl, 0x%xl)\n", 07168 NewStatistics.TokenId.HighPart, 07169 NewStatistics.TokenId.LowPart); 07170 DbgPrint(" "); 07171 CompletionStatus = FALSE; 07172 } 07173 07174 07175 // 07176 // Authentication ID 07177 // 07178 07179 if ( !RtlEqualLuid(&OldStatistics.AuthenticationId, 07180 &NewStatistics.AuthenticationId) ) { 07181 07182 DbgPrint("*** Failed ***\n"); 07183 DbgPrint(" AuthenticationIds are not equal.\n"); 07184 DbgPrint("Original Authentication ID is: "); 07185 TestpPrintLuid(OldStatistics.AuthenticationId); 07186 DbgPrint("\n"); 07187 DbgPrint("New Authentication ID is: "); 07188 TestpPrintLuid(NewStatistics.AuthenticationId); 07189 DbgPrint("\n"); 07190 DbgPrint(" "); 07191 CompletionStatus = FALSE; 07192 } 07193 07194 // 07195 // ExpirationTime 07196 // 07197 07198 if ( (OldStatistics.ExpirationTime.HighPart != 07199 NewStatistics.ExpirationTime.HighPart) || 07200 (OldStatistics.ExpirationTime.LowPart != 07201 NewStatistics.ExpirationTime.LowPart) ) { 07202 07203 DbgPrint("*** Failed ***\n"); 07204 DbgPrint(" ExpirationTimes differ.\n"); 07205 DbgPrint(" "); 07206 CompletionStatus = FALSE; 07207 } 07208 07209 // 07210 // TokenType 07211 // 07212 07213 if ( OldStatistics.TokenType != NewStatistics.TokenType ) { 07214 07215 DbgPrint("*** Failed ***\n"); 07216 DbgPrint(" Token types are different.\n"); 07217 DbgPrint(" Old token type is: 0x%lx \n", OldStatistics.TokenType ); 07218 DbgPrint(" New token type is: 0x%lx \n", NewStatistics.TokenType ); 07219 DbgPrint(" "); 07220 CompletionStatus = FALSE; 07221 } 07222 07223 // 07224 // ImpersonationLevel 07225 // 07226 07227 if (NewStatistics.TokenType = TokenImpersonation) { 07228 if ( OldStatistics.ImpersonationLevel != 07229 NewStatistics.ImpersonationLevel ) { 07230 07231 DbgPrint("*** Failed ***\n"); 07232 DbgPrint(" Impersonation levels are different.\n"); 07233 DbgPrint(" Old impersonation level is: 0x%lx \n", 07234 OldStatistics.ImpersonationLevel ); 07235 DbgPrint(" New impersonation level is: 0x%lx \n", 07236 NewStatistics.ImpersonationLevel ); 07237 DbgPrint(" "); 07238 CompletionStatus = FALSE; 07239 } 07240 } 07241 07242 // 07243 // DynamicCharged 07244 // 07245 07246 if ( OldStatistics.DynamicCharged != NewStatistics.DynamicCharged ) { 07247 07248 DbgPrint("*** Failed ***\n"); 07249 DbgPrint(" DynamicCharges are different.\n"); 07250 DbgPrint(" Old value is: 0x%lx \n", OldStatistics.DynamicCharged ); 07251 DbgPrint(" New value is: 0x%lx \n", NewStatistics.DynamicCharged ); 07252 DbgPrint(" "); 07253 CompletionStatus = FALSE; 07254 } 07255 07256 // 07257 // DynamicAvailable 07258 // 07259 07260 if ( OldStatistics.DynamicAvailable != NewStatistics.DynamicAvailable ) { 07261 07262 DbgPrint("*** Failed ***\n"); 07263 DbgPrint(" DynamicAvailable are different.\n"); 07264 DbgPrint(" Old value is: 0x%lx \n", OldStatistics.DynamicAvailable ); 07265 DbgPrint(" New value is: 0x%lx \n", NewStatistics.DynamicAvailable ); 07266 DbgPrint(" "); 07267 CompletionStatus = FALSE; 07268 } 07269 07270 07271 // 07272 // ModifiedId 07273 // 07274 07275 if ( (NewStatistics.ModifiedId.HighPart != 07276 OldStatistics.ModifiedId.HighPart) || 07277 (NewStatistics.ModifiedId.LowPart != 07278 OldStatistics.ModifiedId.LowPart) ) { 07279 07280 DbgPrint("*** Failed ***\n"); 07281 DbgPrint(" ModifiedIds different.\n"); 07282 DbgPrint(" Old ModifiedId is: (0x%xl, 0x%xl)\n", 07283 OldStatistics.ModifiedId.HighPart, 07284 OldStatistics.ModifiedId.LowPart); 07285 DbgPrint(" New ModifiedId is: (0x%xl, 0x%xl)\n", 07286 NewStatistics.ModifiedId.HighPart, 07287 NewStatistics.ModifiedId.LowPart); 07288 DbgPrint(" "); 07289 CompletionStatus = FALSE; 07290 } 07291 07292 } 07293 07294 // 07295 // Compare the group IDs 07296 // 07297 07298 SomeNotCompared = TRUE; 07299 07300 // 07301 // Compare the privileges 07302 // 07303 07304 SomeNotCompared = TRUE; 07305 07306 // 07307 // Compare the owner IDs 07308 // 07309 07310 SomeNotCompared = TRUE; 07311 07312 // 07313 // Compare the primary group IDs 07314 // 07315 07316 SomeNotCompared = TRUE; 07317 07318 // 07319 // Compare the default dacls 07320 // 07321 07322 SomeNotCompared = TRUE; 07323 07324 // 07325 // Compare the token source 07326 // 07327 07328 if (CompletionStatus) { 07329 Status = NtQueryInformationToken( 07330 OldToken, // Handle 07331 TokenSource, // TokenInformationClass 07332 &OldSource, // TokenInformation 07333 (ULONG)sizeof(TOKEN_SOURCE), // TokenInformationLength 07334 &OldReturnLength // ReturnLength 07335 ); ASSERT(NT_SUCCESS(Status)); 07336 07337 Status = NtQueryInformationToken( 07338 NewToken, // Handle 07339 TokenSource, // TokenInformationClass 07340 &NewSource, // TokenInformation 07341 (ULONG)sizeof(TOKEN_SOURCE), // TokenInformationLength 07342 &NewReturnLength // ReturnLength 07343 ); ASSERT(NT_SUCCESS(Status)); 07344 07345 if ( (OldSource.SourceIdentifier.HighPart == 07346 NewSource.SourceIdentifier.HighPart) && 07347 (OldSource.SourceIdentifier.LowPart == 07348 NewSource.SourceIdentifier.LowPart) ) { 07349 if ( (OldSource.SourceName[0] != NewSource.SourceName[0]) || 07350 (OldSource.SourceName[1] != NewSource.SourceName[1]) || 07351 (OldSource.SourceName[2] != NewSource.SourceName[2]) || 07352 (OldSource.SourceName[3] != NewSource.SourceName[3]) || 07353 (OldSource.SourceName[4] != NewSource.SourceName[4]) || 07354 (OldSource.SourceName[5] != NewSource.SourceName[5]) || 07355 (OldSource.SourceName[6] != NewSource.SourceName[6]) || 07356 (OldSource.SourceName[7] != NewSource.SourceName[7]) ) { 07357 07358 DbgPrint("*** Failed Value Comparison ***\n"); 07359 DbgPrint(" SourceName changed.\n"); 07360 CompletionStatus = FALSE; 07361 07362 } 07363 } else { 07364 07365 DbgPrint("*** Failed Value Comparison ***\n"); 07366 DbgPrint(" SourceIdentifier changed.\n"); 07367 DbgPrint(" Old SourceIdentifier is: (0x%xl, 0x%xl)\n", 07368 OldSource.SourceIdentifier.HighPart, 07369 OldSource.SourceIdentifier.LowPart); 07370 DbgPrint(" New SourceIdentifier is: (0x%xl, 0x%xl)\n", 07371 NewSource.SourceIdentifier.HighPart, 07372 NewSource.SourceIdentifier.LowPart); 07373 CompletionStatus = FALSE; 07374 07375 } 07376 } 07377 07379 07380 07381 if (SomeNotCompared) { 07382 DbgPrint("Incomplete\n"); 07383 DbgPrint(" Some fields not yet compared ... "); 07384 } 07385 07386 if (CompletionStatus) { 07387 07388 DbgPrint("Succeeded. \n"); 07389 } 07390 07391 return CompletionStatus; 07392 } 07393 07394 07396 // // 07397 // Duplicate Token Test // 07398 // // 07400 07401 BOOLEAN 07402 TestTokenDuplicate() 07403 { 07404 BOOLEAN CompletionStatus = TRUE; 07405 07406 BOOLEAN EffectiveOnly; 07407 TOKEN_TYPE NewType; 07408 HANDLE NewToken; 07409 07410 OBJECT_ATTRIBUTES NewAttributes; 07411 07412 SECURITY_QUALITY_OF_SERVICE ImpersonationLevel; 07413 SECURITY_QUALITY_OF_SERVICE IdentificationLevel; 07414 07415 07416 07417 DbgPrint("\n"); 07418 07419 // 07420 // Initialize variables 07421 // 07422 07423 ImpersonationLevel.Length = (ULONG)sizeof(SECURITY_QUALITY_OF_SERVICE); 07424 ImpersonationLevel.ImpersonationLevel = SecurityImpersonation; 07425 ImpersonationLevel.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 07426 ImpersonationLevel.EffectiveOnly = FALSE; 07427 07428 IdentificationLevel.Length = (ULONG)sizeof(SECURITY_QUALITY_OF_SERVICE); 07429 IdentificationLevel.ImpersonationLevel = SecurityImpersonation; 07430 IdentificationLevel.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 07431 IdentificationLevel.EffectiveOnly = FALSE; 07432 07433 07434 InitializeObjectAttributes( 07435 &NewAttributes, 07436 NULL, 07437 OBJ_INHERIT, 07438 NULL, 07439 NULL 07440 ); 07441 07442 07443 07445 // // 07446 // Duplicate the simple token // 07447 // // 07449 07450 DbgPrint("Se: Duplicate primary token ... "); 07451 07452 EffectiveOnly = FALSE; 07453 NewType = TokenImpersonation; 07454 NewAttributes.SecurityQualityOfService = &ImpersonationLevel; 07455 07456 Status = NtDuplicateToken( 07457 SimpleToken, // ExistingTokenHandle 07458 0, // DesiredAccess 07459 &NewAttributes, // ObjectAttributes 07460 EffectiveOnly, // EffectiveOnly 07461 NewType, // TokenType 07462 &NewToken // NewTokenHandle 07463 ); 07464 07465 if (NT_SUCCESS(Status)) { 07466 DbgPrint("Succeeded.\n"); 07467 Status = NtClose( NewToken ); ASSERT(NT_SUCCESS(NewToken)); 07468 07469 } else { 07470 07471 DbgPrint("********** Failed ************\n"); 07472 DbgPrint("Status is: 0x%lx \n", Status); 07473 return FALSE; 07474 } 07475 07476 07477 07479 // // 07480 // Duplicate the restricted token // 07481 // // 07483 07484 DbgPrint("Se: Duplicate restricted sids ... "); 07485 07486 EffectiveOnly = FALSE; 07487 NewType = TokenImpersonation; 07488 NewAttributes.SecurityQualityOfService = &ImpersonationLevel; 07489 07490 Status = NtDuplicateToken( 07491 TokenWithRestrictedSids, // ExistingTokenHandle 07492 0, // DesiredAccess 07493 &NewAttributes, // ObjectAttributes 07494 EffectiveOnly, // EffectiveOnly 07495 NewType, // TokenType 07496 &NewToken // NewTokenHandle 07497 ); 07498 07499 if (NT_SUCCESS(Status)) { 07500 DbgPrint("Succeeded.\n"); 07501 Status = NtClose( NewToken ); ASSERT(NT_SUCCESS(NewToken)); 07502 07503 } else { 07504 07505 DbgPrint("********** Failed ************\n"); 07506 DbgPrint("Status is: 0x%lx \n", Status); 07507 return FALSE; 07508 } 07509 07510 07512 // // 07513 // Duplicate the token with restricted groups // 07514 // // 07516 07517 DbgPrint("Se: Duplicate restricted groups ... "); 07518 07519 EffectiveOnly = TRUE; 07520 NewType = TokenImpersonation; 07521 NewAttributes.SecurityQualityOfService = &ImpersonationLevel; 07522 07523 Status = NtDuplicateToken( 07524 TokenWithRestrictedSids, // ExistingTokenHandle 07525 0, // DesiredAccess 07526 &NewAttributes, // ObjectAttributes 07527 EffectiveOnly, // EffectiveOnly 07528 NewType, // TokenType 07529 &NewToken // NewTokenHandle 07530 ); 07531 07532 if (NT_SUCCESS(Status)) { 07533 DbgPrint("Succeeded.\n"); 07534 Status = NtClose( NewToken ); ASSERT(NT_SUCCESS(NewToken)); 07535 07536 } else { 07537 07538 DbgPrint("********** Failed ************\n"); 07539 DbgPrint("Status is: 0x%lx \n", Status); 07540 return FALSE; 07541 } 07542 07543 07545 // // 07546 // Duplicate the full impersonation token // 07547 // // 07549 07550 DbgPrint("Se: Duplicate full impersonation token ... "); 07551 07552 EffectiveOnly = FALSE; 07553 NewType = TokenImpersonation; 07554 NewAttributes.SecurityQualityOfService = &ImpersonationLevel; 07555 07556 Status = NtDuplicateToken( 07557 ImpersonationToken, // ExistingTokenHandle 07558 0, // DesiredAccess 07559 &NewAttributes, // ObjectAttributes 07560 EffectiveOnly, // EffectiveOnly 07561 NewType, // TokenType 07562 &NewToken // NewTokenHandle 07563 ); 07564 // 07565 // Check to see that the duplicate is really a duplicate of 07566 // the original and display the test results. 07567 // 07568 07569 if (!TestpCompareDuplicateToken( Status, 07570 ImpersonationToken, 07571 NewAttributes, 07572 EffectiveOnly, 07573 NewType, 07574 NewToken ) ) { 07575 07576 CompletionStatus = FALSE; 07577 } 07578 07579 if (NT_SUCCESS(Status)) { 07580 07581 Status = NtClose( NewToken ); 07582 07583 ASSERT(NT_SUCCESS(Status)); 07584 } 07585 07586 07588 // // 07589 // Duplicate the full token, effective only // 07590 // // 07592 07593 DbgPrint("Se: Duplicate full token, effective only ... "); 07594 07595 EffectiveOnly = TRUE; 07596 NewType = TokenImpersonation; 07597 NewAttributes.SecurityQualityOfService = &ImpersonationLevel; 07598 07599 Status = NtDuplicateToken( 07600 ImpersonationToken, // ExistingTokenHandle 07601 0, // DesiredAccess 07602 &NewAttributes, // ObjectAttributes 07603 EffectiveOnly, // EffectiveOnly 07604 NewType, // TokenType 07605 &NewToken // NewTokenHandle 07606 ); 07607 // 07608 // Check to see that the duplicate is really a duplicate of 07609 // the original and display the test results. 07610 // 07611 07612 if (!TestpCompareDuplicateToken( Status, 07613 ImpersonationToken, 07614 NewAttributes, 07615 EffectiveOnly, 07616 NewType, 07617 NewToken ) ) { 07618 07619 CompletionStatus = FALSE; 07620 } 07621 07622 if (NT_SUCCESS(Status)) { 07623 07624 Status = NtClose( NewToken ); 07625 07626 ASSERT(NT_SUCCESS(Status)); 07627 } 07628 07629 07630 07631 07632 07633 07634 07635 07636 07637 07638 return CompletionStatus; 07639 } 07640 07642 // // 07643 // Assign Primary Token Test // 07644 // // 07646 07647 BOOLEAN 07648 TestTokenAssignPrimary() 07649 { 07650 BOOLEAN CompletionStatus = TRUE; 07651 ULONG ReturnLength; 07652 07653 TOKEN_STATISTICS OriginalTokenStatistics; 07654 TOKEN_STATISTICS NewTokenStatistics; 07655 TOKEN_STATISTICS AssignedTokenStatistics; 07656 07657 07658 TOKEN_USER UserId; 07659 TOKEN_PRIMARY_GROUP PrimaryGroup; 07660 PTOKEN_GROUPS GroupIds; 07661 PTOKEN_PRIVILEGES Privileges; 07662 TOKEN_DEFAULT_DACL DefaultDacl; 07663 TOKEN_OWNER Owner; 07664 07665 PROCESS_ACCESS_TOKEN PrimaryTokenInfo; 07666 07667 DbgPrint("\n"); 07668 07669 07671 // // 07672 // Assign a valid primary token // 07673 // // 07675 07676 DbgPrint("Se: Assign new primary token ... "); 07677 07678 // 07679 // Get information about the current token 07680 // 07681 07682 Status = NtOpenProcessToken( 07683 NtCurrentProcess(), 07684 TOKEN_ALL_ACCESS, 07685 &ProcessToken 07686 ); 07687 ASSERT (NT_SUCCESS(Status)); 07688 07689 Status = NtQueryInformationToken( 07690 ProcessToken, // Handle 07691 TokenStatistics, // TokenInformationClass 07692 &OriginalTokenStatistics, // TokenInformation 07693 sizeof(TOKEN_STATISTICS), // TokenInformationLength 07694 &ReturnLength // ReturnLength 07695 ); 07696 ASSERT(NT_SUCCESS(Status)); 07697 07698 07699 07700 07701 // 07702 // Create a token with default DACL for use 07703 // 07704 07705 GroupIds = (PTOKEN_GROUPS)TstAllocatePool( PagedPool, 07706 GROUP_IDS_LENGTH 07707 ); 07708 07709 Privileges = (PTOKEN_PRIVILEGES)TstAllocatePool( PagedPool, 07710 PRIVILEGES_LENGTH 07711 ); 07712 07713 DefaultDacl.DefaultDacl = (PACL)TstAllocatePool( PagedPool, 07714 DEFAULT_DACL_LENGTH 07715 ); 07716 07717 GroupIds->GroupCount = GROUP_COUNT; 07718 07719 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 07720 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 07721 GroupIds->Groups[SYSTEM_INDEX].Sid = LocalSystemSid; 07722 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 07723 07724 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 07725 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 07726 GroupIds->Groups[SYSTEM_INDEX].Attributes = OptionalGroupAttributes; 07727 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 07728 07729 UserId.User.Sid = PebblesSid; 07730 UserId.User.Attributes = 0; 07731 07732 Owner.Owner = FlintstoneSid; 07733 07734 Privileges->PrivilegeCount = PRIVILEGE_COUNT; 07735 07736 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 07737 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 07738 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid = AssignPrimaryTokenPrivilege; 07739 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 07740 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 07741 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes = SE_PRIVILEGE_ENABLED; 07742 07743 PrimaryGroup.PrimaryGroup = FlintstoneSid; 07744 07745 Status = RtlCreateAcl( DefaultDacl.DefaultDacl, DEFAULT_DACL_LENGTH, ACL_REVISION); 07746 07747 ASSERT(NT_SUCCESS(Status) ); 07748 07749 Status = NtCreateToken( 07750 &Token, // Handle 07751 (TOKEN_ALL_ACCESS), // DesiredAccess 07752 &PrimaryTokenAttributes, // ObjectAttributes 07753 TokenPrimary, // TokenType 07754 &SystemAuthenticationId, // Authentication LUID 07755 &NoExpiration, // Expiration Time 07756 &UserId, // Owner ID 07757 GroupIds, // Group IDs 07758 Privileges, // Privileges 07759 &Owner, // Owner 07760 &PrimaryGroup, // Primary Group 07761 &DefaultDacl, // Default Dacl 07762 &TestSource // TokenSource 07763 ); 07764 ASSERT(NT_SUCCESS(Status)); 07765 07766 // 07767 // Make sure key data is different than what is already on the process. 07768 // 07769 07770 Status = NtQueryInformationToken( 07771 Token, // Handle 07772 TokenStatistics, // TokenInformationClass 07773 &NewTokenStatistics, // TokenInformation 07774 sizeof(TOKEN_STATISTICS), // TokenInformationLength 07775 &ReturnLength // ReturnLength 07776 ); 07777 ASSERT(NT_SUCCESS(Status)); 07778 07779 ASSERT( (OriginalTokenStatistics.TokenId.HighPart != 07780 NewTokenStatistics.TokenId.HighPart) || 07781 (OriginalTokenStatistics.TokenId.LowPart != 07782 NewTokenStatistics.TokenId.LowPart) ); 07783 07784 07785 07786 // 07787 // Assign the new token 07788 // 07789 07790 PrimaryTokenInfo.Token = Token; 07791 PrimaryTokenInfo.Thread = NtCurrentThread(); 07792 Status = NtSetInformationProcess( 07793 NtCurrentProcess(), 07794 ProcessAccessToken, 07795 (PVOID)&PrimaryTokenInfo, 07796 (ULONG)sizeof(PROCESS_ACCESS_TOKEN) 07797 ); 07798 07799 if (!NT_SUCCESS(Status)) { 07800 07801 DbgPrint("********** Failed ************\n"); 07802 DbgPrint("Status is: 0x%lx \n", Status); 07803 CompletionStatus = FALSE; 07804 07805 } else { 07806 07807 Status = NtClose( Token ); 07808 ASSERT(NT_SUCCESS(Status)); 07809 07810 07811 // 07812 // Get information about the assigned token 07813 // 07814 07815 Status = NtOpenProcessToken( 07816 NtCurrentProcess(), 07817 TOKEN_QUERY | TOKEN_QUERY_SOURCE, 07818 &Token 07819 ); 07820 ASSERT (NT_SUCCESS(Status)); 07821 07822 Status = NtQueryInformationToken( 07823 Token, // Handle 07824 TokenStatistics, // TokenInformationClass 07825 &AssignedTokenStatistics, // TokenInformation 07826 sizeof(TOKEN_STATISTICS), // TokenInformationLength 07827 &ReturnLength // ReturnLength 07828 ); 07829 ASSERT(NT_SUCCESS(Status)); 07830 07831 Status = NtClose( Token ); 07832 ASSERT(NT_SUCCESS(Status)); 07833 07834 07835 // 07836 // Information about assigned token and the new token 07837 // should be the same 07838 // 07839 07840 ASSERT(AssignedTokenStatistics.TokenType == TokenPrimary); 07841 07842 if ( (NewTokenStatistics.TokenId.HighPart == 07843 AssignedTokenStatistics.TokenId.HighPart) && 07844 (NewTokenStatistics.TokenId.LowPart == 07845 AssignedTokenStatistics.TokenId.LowPart) ) { 07846 07847 DbgPrint("Succeeded.\n"); 07848 07849 } else { 07850 07851 DbgPrint("********** Failed ************\n"); 07852 DbgPrint("Token ID mismatch.\n"); 07853 DbgPrint("New token ID is: (0x%lx, 0x%lx) \n", 07854 NewTokenStatistics.TokenId.HighPart, 07855 NewTokenStatistics.TokenId.LowPart); 07856 DbgPrint("Assigned token ID is: (0x%lx, 0x%lx) \n", 07857 AssignedTokenStatistics.TokenId.HighPart, 07858 AssignedTokenStatistics.TokenId.LowPart); 07859 CompletionStatus = FALSE; 07860 07861 } 07862 } 07863 07864 // 07865 // Change back to the original token 07866 // 07867 07868 PrimaryTokenInfo.Token = ProcessToken; 07869 PrimaryTokenInfo.Thread = NtCurrentThread(); 07870 Status = NtSetInformationProcess( 07871 NtCurrentProcess(), 07872 ProcessAccessToken, 07873 (PVOID)&PrimaryTokenInfo, 07874 (ULONG)sizeof(PROCESS_ACCESS_TOKEN) 07875 ); 07876 07877 ASSERT(NT_SUCCESS(Status)); 07878 Status = NtClose( ProcessToken ); 07879 ASSERT(NT_SUCCESS(Status)); 07880 07881 07883 // // 07884 // Attempt to assign an impersonation token as primary // 07885 // // 07887 07888 DbgPrint("Se: Assign impersonation token as primary ... "); 07889 07890 07891 // 07892 // Create an impersonation token 07893 // 07894 GroupIds->GroupCount = GROUP_COUNT; 07895 07896 GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid; 07897 GroupIds->Groups[CHILD_INDEX].Sid = ChildSid; 07898 GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid; 07899 GroupIds->Groups[WORLD_INDEX].Sid = WorldSid; 07900 07901 GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes; 07902 GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes; 07903 GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes; 07904 GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes; 07905 07906 UserId.User.Sid = PebblesSid; 07907 UserId.User.Attributes = 0; 07908 07909 Owner.Owner = FlintstoneSid; 07910 07911 Privileges->PrivilegeCount = PRIVILEGE_COUNT; 07912 07913 Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege; 07914 Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege; 07915 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Luid = AssignPrimaryTokenPrivilege; 07916 Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0; 07917 Privileges->Privileges[SECURITY_INDEX].Attributes = 0; 07918 Privileges->Privileges[ASSIGN_PRIMARY_INDEX].Attributes = SE_PRIVILEGE_ENABLED; 07919 07920 PrimaryGroup.PrimaryGroup = FlintstoneSid; 07921 07922 Status = RtlCreateAcl( DefaultDacl.DefaultDacl, DEFAULT_DACL_LENGTH, ACL_REVISION); 07923 07924 ASSERT(NT_SUCCESS(Status) ); 07925 07926 Status = NtCreateToken( 07927 &Token, // Handle 07928 (TOKEN_ALL_ACCESS), // DesiredAccess 07929 &ImpersonationTokenAttributes, // ObjectAttributes 07930 TokenImpersonation, // TokenType 07931 &OriginalAuthenticationId, // Authentication LUID 07932 &NoExpiration, // Expiration Time 07933 &UserId, // Owner ID 07934 GroupIds, // Group IDs 07935 Privileges, // Privileges 07936 &Owner, // Owner 07937 &PrimaryGroup, // Primary Group 07938 &DefaultDacl, // Default Dacl 07939 &TestSource // TokenSource 07940 ); 07941 ASSERT(NT_SUCCESS(Status)); 07942 07943 // 07944 // Assign the new token 07945 // 07946 07947 PrimaryTokenInfo.Token = Token; 07948 PrimaryTokenInfo.Thread = NtCurrentThread(); 07949 Status = NtSetInformationProcess( 07950 NtCurrentProcess(), 07951 ProcessAccessToken, 07952 (PVOID)&PrimaryTokenInfo, 07953 (ULONG)sizeof(PROCESS_ACCESS_TOKEN) 07954 ); 07955 07956 if (Status == STATUS_BAD_TOKEN_TYPE) { 07957 07958 DbgPrint("Succeeded.\n"); 07959 07960 } else { 07961 07962 DbgPrint("********** Failed ************\n"); 07963 DbgPrint("Status is: 0x%lx \n", Status); 07964 CompletionStatus = FALSE; 07965 07966 } 07967 07968 Status = NtClose( Token ); 07969 ASSERT(NT_SUCCESS(Status)); 07970 07971 07972 return CompletionStatus; 07973 } 07974 07976 // // 07977 // Impersonation Test (with open test) // 07978 // // 07980 07981 BOOLEAN 07982 TestTokenImpersonation() 07983 { 07984 BOOLEAN CompletionStatus = TRUE; 07985 07986 HANDLE OpenedToken; 07987 HANDLE NewToken; 07988 OBJECT_ATTRIBUTES NewAttributes; 07989 TOKEN_TYPE NewType; 07990 BOOLEAN EffectiveOnly = FALSE; 07991 07992 SECURITY_QUALITY_OF_SERVICE ImpersonationLevel; 07993 07994 07995 07996 DbgPrint("\n"); 07997 07998 08000 // // 08001 // Terminate impersonation using NtSetInformationThread() // 08002 // // 08004 08005 DbgPrint("Se: Revert to self (specify NULL handle) ... "); 08006 08007 NewToken = NULL; 08008 Status = NtSetInformationThread( 08009 NtCurrentThread(), 08010 ThreadImpersonationToken, 08011 (PVOID)&NewToken, 08012 (ULONG)sizeof(HANDLE) 08013 ); 08014 08015 if (NT_SUCCESS(Status)) { 08016 DbgPrint("Succeeded.\n"); 08017 } else { 08018 08019 DbgPrint("********** Failed ************\n"); 08020 DbgPrint("Status is: 0x%lx \n", Status); 08021 CompletionStatus = FALSE; 08022 08023 } 08024 08025 08027 // // 08028 // Attempt to assign a primary token as an impersonation // 08029 // token. // 08030 // // 08032 08033 DbgPrint("Se: Assigning primary token as impersonation token ... "); 08034 08035 NewToken = TokenWithGroups; 08036 Status = NtSetInformationThread( 08037 NtCurrentThread(), 08038 ThreadImpersonationToken, 08039 (PVOID)&NewToken, 08040 (ULONG)sizeof(HANDLE) 08041 ); 08042 08043 if (Status == STATUS_BAD_TOKEN_TYPE) { 08044 DbgPrint("Succeeded.\n"); 08045 } else { 08046 08047 DbgPrint("********** Failed ************\n"); 08048 DbgPrint("Status is: 0x%lx \n", Status); 08049 CompletionStatus = FALSE; 08050 08051 } 08052 08053 08055 // // 08056 // Assign a valid impersonation token // 08057 // // 08059 08060 DbgPrint("Se: Assign valid impersonation token ... "); 08061 08062 NewToken = ImpersonationToken; 08063 Status = NtSetInformationThread( 08064 NtCurrentThread(), 08065 ThreadImpersonationToken, 08066 (PVOID)&NewToken, 08067 (ULONG)sizeof(HANDLE) 08068 ); 08069 08070 if (NT_SUCCESS(Status)) { 08071 DbgPrint("Succeeded.\n"); 08072 } else { 08073 08074 DbgPrint("********** Failed ************\n"); 08075 DbgPrint("Status is: 0x%lx \n", Status); 08076 CompletionStatus = FALSE; 08077 08078 } 08079 08080 08082 // // 08083 // Open the impersonation token // 08084 // // 08086 08087 08088 DbgPrint("Se: Open an impersonation token ... "); 08089 08090 Status = NtOpenThreadToken( 08091 NtCurrentThread(), 08092 TOKEN_ALL_ACCESS, 08093 TRUE, 08094 &OpenedToken 08095 ); 08096 08097 if (NT_SUCCESS(Status)) { 08098 DbgPrint("Succeeded.\n"); 08099 Status = NtClose( OpenedToken ); 08100 ASSERT(NT_SUCCESS(Status)); 08101 } else { 08102 08103 DbgPrint("********** Failed ************\n"); 08104 DbgPrint("Status is: 0x%lx \n", Status); 08105 CompletionStatus = FALSE; 08106 08107 } 08108 08109 08110 08112 // // 08113 // Open a non-existent impersonation token // 08114 // // 08116 08117 08118 DbgPrint("Se: Open a non-existent impersonation token ... "); 08119 08120 // 08121 // Clear any existing impersonation token. 08122 // 08123 08124 NewToken = NULL; 08125 Status = NtSetInformationThread( 08126 NtCurrentThread(), 08127 ThreadImpersonationToken, 08128 (PVOID)&NewToken, 08129 (ULONG)sizeof(HANDLE) 08130 ); ASSERT(NT_SUCCESS(Status)); 08131 08132 Status = NtOpenThreadToken( 08133 NtCurrentThread(), 08134 TOKEN_ALL_ACCESS, 08135 TRUE, 08136 &OpenedToken 08137 ); 08138 08139 if (Status == STATUS_NO_TOKEN) { 08140 DbgPrint("Succeeded.\n"); 08141 } else { 08142 08143 DbgPrint("********** Failed ************\n"); 08144 DbgPrint("Status is: 0x%lx \n", Status); 08145 CompletionStatus = FALSE; 08146 08147 } 08148 08149 08151 // // 08152 // Open an anonymous impersonation token // 08153 // // 08155 08156 08157 DbgPrint("Se: Open an anonymous impersonation token ... "); 08158 08159 // 08160 // Assign an anonymous impersonation token 08161 // 08162 08163 NewToken = AnonymousToken; 08164 Status = NtSetInformationThread( 08165 ThreadHandle, 08166 ThreadImpersonationToken, 08167 (PVOID)&NewToken, 08168 (ULONG)sizeof(HANDLE) 08169 ); ASSERT(NT_SUCCESS(Status)); 08170 08171 08172 Status = NtOpenThreadToken( 08173 ThreadHandle, 08174 TOKEN_ALL_ACCESS, 08175 TRUE, 08176 &OpenedToken 08177 ); 08178 08179 if (Status == STATUS_CANT_OPEN_ANONYMOUS) { 08180 DbgPrint("Succeeded.\n"); 08181 } else { 08182 08183 DbgPrint("********** Failed ************\n"); 08184 DbgPrint("Status is: 0x%lx \n", Status); 08185 CompletionStatus = FALSE; 08186 08187 } 08188 08189 08191 // // 08192 // Change the impersonation of a thread // 08193 // // 08195 08196 08197 DbgPrint("Se: Change the impersonation token ... "); 08198 08199 NewToken = NULL; 08200 Status = NtSetInformationThread( 08201 ThreadHandle, 08202 ThreadImpersonationToken, 08203 (PVOID)&NewToken, 08204 (ULONG)sizeof(HANDLE) 08205 ); ASSERT(NT_SUCCESS(Status)); 08206 08207 NewToken = AnonymousToken; 08208 Status = NtSetInformationThread( 08209 ThreadHandle, 08210 ThreadImpersonationToken, 08211 (PVOID)&NewToken, 08212 (ULONG)sizeof(HANDLE) 08213 ); ASSERT(NT_SUCCESS(Status)); 08214 08215 NewToken = ImpersonationToken; 08216 Status = NtSetInformationThread( 08217 ThreadHandle, 08218 ThreadImpersonationToken, 08219 (PVOID)&NewToken, 08220 (ULONG)sizeof(HANDLE) 08221 ); 08222 08223 if (NT_SUCCESS(Status)) { 08224 DbgPrint("Succeeded.\n"); 08225 } else { 08226 08227 DbgPrint("********** Failed ************\n"); 08228 DbgPrint("Status is: 0x%lx \n", Status); 08229 CompletionStatus = FALSE; 08230 08231 } 08232 08234 // // 08235 // Impersonate a restricted token // 08236 // // 08238 08239 08240 DbgPrint("Se: Impersonate restricted token ... "); 08241 08242 NewToken = NULL; 08243 Status = NtSetInformationThread( 08244 NtCurrentThread(), 08245 ThreadImpersonationToken, 08246 (PVOID)&NewToken, 08247 (ULONG)sizeof(HANDLE) 08248 ); ASSERT(NT_SUCCESS(Status)); 08249 08250 08251 08252 08253 // 08254 // Initialize variables 08255 // 08256 08257 InitializeObjectAttributes( 08258 &NewAttributes, 08259 NULL, 08260 OBJ_INHERIT, 08261 NULL, 08262 NULL 08263 ); 08264 08265 08266 ImpersonationLevel.Length = (ULONG)sizeof(SECURITY_QUALITY_OF_SERVICE); 08267 ImpersonationLevel.ImpersonationLevel = SecurityImpersonation; 08268 ImpersonationLevel.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 08269 ImpersonationLevel.EffectiveOnly = FALSE; 08270 NewType = TokenImpersonation; 08271 NewAttributes.SecurityQualityOfService = &ImpersonationLevel; 08272 08273 08274 Status = NtDuplicateToken( 08275 TokenWithRestrictedSids, // ExistingTokenHandle 08276 TOKEN_ALL_ACCESS, // DesiredAccess 08277 &NewAttributes, // ObjectAttributes 08278 EffectiveOnly, // EffectiveOnly 08279 NewType, // TokenType 08280 &NewToken // NewTokenHandle 08281 ); 08282 08283 if (NT_SUCCESS(Status)) { 08284 DbgPrint("Succeeded.\n"); 08285 08286 } else { 08287 08288 DbgPrint("********** Failed ************\n"); 08289 DbgPrint("Status is: 0x%lx \n", Status); 08290 CompletionStatus = FALSE; 08291 } 08292 08293 Status = NtSetInformationThread( 08294 NtCurrentThread(), 08295 ThreadImpersonationToken, 08296 (PVOID)&NewToken, 08297 (ULONG)sizeof(HANDLE) 08298 ); ASSERT(NT_SUCCESS(Status)); 08299 08300 // 08301 // Now try to open something, like the process, which should fail 08302 // 08303 08304 Status = NtOpenProcessToken( 08305 NtCurrentProcess(), 08306 TOKEN_QUERY | TOKEN_QUERY_SOURCE, 08307 &Token 08308 ); 08309 if (Status != STATUS_ACCESS_DENIED) { 08310 DbgPrint("********** Failed ************\n"); 08311 DbgPrint("Status is: 0x%lx \n", Status); 08312 CompletionStatus = FALSE; 08313 } 08314 08315 Status = NtOpenProcessToken( 08316 NtCurrentProcess(), 08317 MAXIMUM_ALLOWED, 08318 &Token 08319 ); 08320 if (Status != STATUS_ACCESS_DENIED) { 08321 DbgPrint("********** Failed ************\n"); 08322 DbgPrint("Status is: 0x%lx \n", Status); 08323 CompletionStatus = FALSE; 08324 } 08325 08326 Status = NtDuplicateToken( 08327 TokenWithMoreRestrictedSids, // ExistingTokenHandle 08328 TOKEN_ALL_ACCESS, // DesiredAccess 08329 &NewAttributes, // ObjectAttributes 08330 EffectiveOnly, // EffectiveOnly 08331 NewType, // TokenType 08332 &NewToken // NewTokenHandle 08333 ); 08334 08335 if (NT_SUCCESS(Status)) { 08336 DbgPrint("Succeeded.\n"); 08337 08338 } else { 08339 08340 DbgPrint("********** Failed ************\n"); 08341 DbgPrint("Status is: 0x%lx \n", Status); 08342 CompletionStatus = FALSE; 08343 } 08344 08345 Status = NtSetInformationThread( 08346 NtCurrentThread(), 08347 ThreadImpersonationToken, 08348 (PVOID)&NewToken, 08349 (ULONG)sizeof(HANDLE) 08350 ); ASSERT(NT_SUCCESS(Status)); 08351 08352 08353 // 08354 // Now try to open something, like the process, which should succeed 08355 // 08356 08357 Status = NtOpenProcessToken( 08358 NtCurrentProcess(), 08359 TOKEN_QUERY | TOKEN_QUERY_SOURCE, 08360 &Token 08361 ); 08362 if (Status != STATUS_SUCCESS) { 08363 DbgPrint("********** Failed ************\n"); 08364 DbgPrint("Status is: 0x%lx \n", Status); 08365 CompletionStatus = FALSE; 08366 } 08367 08368 Status = NtOpenProcessToken( 08369 NtCurrentProcess(), 08370 MAXIMUM_ALLOWED, 08371 &Token 08372 ); 08373 if (Status != STATUS_SUCCESS) { 08374 DbgPrint("********** Failed ************\n"); 08375 DbgPrint("Status is: 0x%lx \n", Status); 08376 CompletionStatus = FALSE; 08377 } 08378 08379 NewToken = NULL; 08380 Status = NtSetInformationThread( 08381 NtCurrentThread(), 08382 ThreadImpersonationToken, 08383 (PVOID)&NewToken, 08384 (ULONG)sizeof(HANDLE) 08385 ); 08386 08387 if (NT_SUCCESS(Status)) { 08388 DbgPrint("Succeeded.\n"); 08389 } else { 08390 08391 DbgPrint("********** Failed ************\n"); 08392 DbgPrint("Status is: 0x%lx \n", Status); 08393 CompletionStatus = FALSE; 08394 08395 } 08396 08397 Status = NtTerminateThread( 08398 ThreadHandle, 08399 (NTSTATUS)0 08400 ); 08401 08402 ASSERT(NT_SUCCESS(Status)); 08403 08404 return CompletionStatus; 08405 } 08406 08408 // // 08409 // Main Program Entry // 08410 // // 08412 08413 BOOLEAN 08414 CTToken() // Common Test for Token object 08415 { 08416 BOOLEAN Result = TRUE; 08417 08418 DbgPrint("Se: Initialization..."); 08419 TestTokenInitialize(); 08420 08421 DbgPrint("Se: Token Creation Test... Test"); 08422 if (!TestTokenCreate()) { Result = FALSE; } 08423 08424 DbgPrint("Se: Token Filtering Test... Test"); 08425 if (!TestTokenFilter()) { Result = FALSE; } 08426 08427 DbgPrint("Se: Token Open Test (with primary token)... Test"); 08428 if (!TestTokenOpenPrimary()) { Result = FALSE; } 08429 08430 DbgPrint("Se: Token Query Test... Test"); 08431 if (!TestTokenQuery()) { Result = FALSE; } 08432 08433 DbgPrint("Se: Token Set Test... Test"); 08434 if (!TestTokenSet()) { Result = FALSE; } 08435 08436 DbgPrint("Se: Token Adjust Privileges Test... Test"); 08437 if (!TestTokenAdjustPrivileges()) {Result = FALSE; } 08438 08439 DbgPrint("Se: Token Adjust Group Test... Test"); 08440 if (!TestTokenAdjustGroups()) { Result = FALSE; } 08441 08442 DbgPrint("Se: Token Duplication Test... Test"); 08443 if (!TestTokenDuplicate()) { Result = FALSE; } 08444 08445 DbgPrint("Se: Primary Token Assignment Test... Test"); 08446 if (!TestTokenAssignPrimary()) { Result = FALSE; } 08447 08448 DbgPrint("Se: Impersonation Test (and impersonation open)... Test"); 08449 if (!TestTokenImpersonation()) { Result = FALSE; } 08450 08451 08452 DbgPrint("\n"); 08453 DbgPrint("\n"); 08454 DbgPrint(" ********************\n"); 08455 DbgPrint(" ** **\n"); 08456 if (Result) { 08457 DbgPrint("Se: ** Test Succeeded **\n"); 08458 } else { 08459 DbgPrint("Se: ** Test Failed **\n"); 08460 } 08461 08462 DbgPrint(" ** **\n"); 08463 DbgPrint(" ********************\n"); 08464 DbgPrint("\n"); 08465 DbgPrint("\n"); 08466 08467 return Result; 08468 } 08469

Generated on Sat May 15 19:39:37 2004 for test by doxygen 1.3.7