00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
#include "sep.h"
00031
#include "tokenp.h"
00032
00033
#ifdef ALLOC_PRAGMA
00034
#pragma alloc_text(PAGE,NtDuplicateToken)
00035
#pragma alloc_text(PAGE,SepDuplicateToken)
00036
#pragma alloc_text(PAGE,SepMakeTokenEffectiveOnly)
00037
#pragma alloc_text(PAGE,SepSidInSidAndAttributes)
00038
#pragma alloc_text(PAGE,SepRemoveDisabledGroupsAndPrivileges)
00039
#pragma alloc_text(PAGE,SeCopyClientToken)
00040
#pragma alloc_text(PAGE,NtFilterToken)
00041
#pragma alloc_text(PAGE,SepFilterToken)
00042
#endif
00043
00044
00045
NTSTATUS
00046 NtDuplicateToken(
00047 IN HANDLE ExistingTokenHandle,
00048 IN ACCESS_MASK DesiredAccess,
00049 IN POBJECT_ATTRIBUTES ObjectAttributes,
00050 IN BOOLEAN EffectiveOnly,
00051 IN TOKEN_TYPE TokenType,
00052 OUT PHANDLE NewTokenHandle
00053 )
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 {
00124
00125
PTOKEN Token;
00126
PTOKEN NewToken;
00127
KPROCESSOR_MODE PreviousMode;
00128
NTSTATUS Status;
00129
00130 SECURITY_ADVANCED_QUALITY_OF_SERVICE
SecurityQos;
00131 BOOLEAN SecurityQosPresent =
FALSE;
00132 HANDLE LocalHandle;
00133
00134
OBJECT_HANDLE_INFORMATION HandleInformation;
00135 ACCESS_MASK EffectiveDesiredAccess;
00136
00137
PAGED_CODE();
00138
00139 PreviousMode = KeGetPreviousMode();
00140
00141
00142
00143
00144
00145
if (PreviousMode !=
KernelMode) {
00146
00147
try {
00148
00149
00150
00151
00152
00153
if ( (TokenType < TokenPrimary) || (TokenType > TokenImpersonation) ) {
00154
return(STATUS_INVALID_PARAMETER);
00155 }
00156
00157
00158
00159
00160
00161
ProbeForWriteHandle(NewTokenHandle);
00162
00163
00164 } except(
EXCEPTION_EXECUTE_HANDLER) {
00165
return GetExceptionCode();
00166 }
00167
00168 }
00169
00170
00171
00172
Status =
SeCaptureSecurityQos(
00173
ObjectAttributes,
00174 PreviousMode,
00175 &SecurityQosPresent,
00176 &
SecurityQos
00177 );
00178
00179
if (!
NT_SUCCESS(
Status)) {
00180
return Status;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
Status =
ObReferenceObjectByHandle(
00191 ExistingTokenHandle,
00192 TOKEN_DUPLICATE,
00193
SepTokenObjectType,
00194 PreviousMode,
00195 (PVOID *)&
Token,
00196 &HandleInformation
00197 );
00198
00199
if ( !
NT_SUCCESS(
Status) ) {
00200
00201
if (SecurityQosPresent) {
00202
SeFreeCapturedSecurityQos( &
SecurityQos );
00203 }
00204
return Status;
00205 }
00206
00207
00208
#ifdef TOKEN_DEBUG
00209
00210
00211
00212
SepAcquireTokenReadLock(
Token );
00213
DbgPrint(
"\n");
00214
DbgPrint(
"\n");
00215
DbgPrint(
"Token being duplicated: \n");
00216 SepDumpToken(
Token );
00217
SepReleaseTokenReadLock(
Token );
00218
00219
00221
#endif //TOKEN_DEBUG
00222
00223
00224
00225
00226
00227
00228
if (ARGUMENT_PRESENT((PVOID)(ULONG_PTR)DesiredAccess)) {
00229
00230 EffectiveDesiredAccess = DesiredAccess;
00231
00232 }
else {
00233
00234 EffectiveDesiredAccess = HandleInformation.
GrantedAccess;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
if ( !SecurityQosPresent ) {
00244
00245
SecurityQos.ImpersonationLevel =
Token->ImpersonationLevel;
00246
00247 }
00248
00249
00250
00251
if (
Token->TokenType == TokenImpersonation) {
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
ASSERT( SecurityDelegation > SecurityImpersonation );
00262
ASSERT( SecurityImpersonation > SecurityIdentification );
00263
ASSERT( SecurityIdentification > SecurityAnonymous );
00264
00265
if ( (
SecurityQos.ImpersonationLevel >
Token->ImpersonationLevel) ) {
00266
00267
ObDereferenceObject( (PVOID)
Token );
00268
if (SecurityQosPresent) {
00269
SeFreeCapturedSecurityQos( &
SecurityQos );
00270 }
00271
return STATUS_BAD_IMPERSONATION_LEVEL;
00272 }
00273
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
if ( (
Token->TokenType == TokenImpersonation) &&
00283 (TokenType == TokenPrimary) &&
00284 (
Token->ImpersonationLevel < SecurityImpersonation)
00285 ) {
00286
ObDereferenceObject( (PVOID)
Token );
00287
if (SecurityQosPresent) {
00288
SeFreeCapturedSecurityQos( &
SecurityQos );
00289 }
00290
return STATUS_BAD_IMPERSONATION_LEVEL;
00291 }
00292
00293
00294
00295
00296
00297 NewToken =
NULL;
00298
Status =
SepDuplicateToken(
00299
Token,
00300
ObjectAttributes,
00301 EffectiveOnly,
00302 TokenType,
00303
SecurityQos.ImpersonationLevel,
00304 PreviousMode,
00305 &NewToken
00306 );
00307
00308
00309
if (
NT_SUCCESS(
Status)) {
00310
00311
00312
00313
00314
00315
Status =
ObInsertObject( NewToken,
00316
NULL,
00317 EffectiveDesiredAccess,
00318 0,
00319 (PVOID *)
NULL,
00320 &LocalHandle
00321 );
00322
00323
if (!
NT_SUCCESS(
Status )) {
00324
#ifdef TOKEN_DEBUG
00325
DbgPrint(
"SE: ObInsertObject failed (%x) for token at %x\n",
Status, NewToken );
00326
#endif
00327
}
00328
00329 }
else
00330
if (NewToken !=
NULL) {
00331
#ifdef TOKEN_DEBUG
00332
DbgPrint(
"SE: SepDuplicateToken failed (%x) but allocated token at %x\n",
Status, NewToken );
00333
#endif
00334
}
00335
00336
00337
00338
00339
00340
ObDereferenceObject( (PVOID)
Token );
00341
00342
if (SecurityQosPresent) {
00343
SeFreeCapturedSecurityQos( &
SecurityQos );
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
if (
NT_SUCCESS(
Status)) {
00353
try { *NewTokenHandle = LocalHandle; }
00354 except(
EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode(); }
00355 }
00356
00357
return Status;
00358 }
00359
00360
00361
NTSTATUS
00362 SepDuplicateToken(
00363 IN PTOKEN ExistingToken,
00364 IN POBJECT_ATTRIBUTES ObjectAttributes,
00365 IN BOOLEAN EffectiveOnly,
00366 IN TOKEN_TYPE TokenType,
00367 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel OPTIONAL,
00368 IN KPROCESSOR_MODE RequestorMode,
00369 OUT PTOKEN *DuplicateToken
00370 )
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 {
00430
NTSTATUS Status;
00431
00432
PTOKEN NewToken;
00433 PULONG DynamicPart;
00434 ULONG PagedPoolSize;
00435 ULONG NonPagedPoolSize;
00436 ULONG TokenBodyLength;
00437 ULONG FieldOffset;
00438
00439 ULONG
Index;
00440
00441 PSECURITY_TOKEN_PROXY_DATA NewProxyData;
00442 PSECURITY_TOKEN_AUDIT_DATA NewAuditData;
00443
00444
00445
PAGED_CODE();
00446
00447
ASSERT(
sizeof(SECURITY_IMPERSONATION_LEVEL) <=
sizeof(ULONG) );
00448
00449
00450
if ( TokenType == TokenImpersonation ) {
00451
00452
ASSERT( SecurityDelegation > SecurityImpersonation );
00453
ASSERT( SecurityImpersonation > SecurityIdentification );
00454
ASSERT( SecurityIdentification > SecurityAnonymous );
00455
00456
if ( (ImpersonationLevel > SecurityDelegation) ||
00457 (ImpersonationLevel < SecurityAnonymous) ) {
00458
00459
return STATUS_BAD_IMPERSONATION_LEVEL;
00460 }
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
Status =
SepReferenceLogonSession( &(ExistingToken->AuthenticationId) );
00471
ASSERT(
NT_SUCCESS(
Status) );
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 DynamicPart = (PULONG)
ExAllocatePoolWithTag(
00485
PagedPool,
00486 ExistingToken->DynamicCharged,
00487 'dTeS'
00488 );
00489
00490
if (DynamicPart ==
NULL) {
00491
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
00492
return( STATUS_INSUFFICIENT_RESOURCES );
00493 }
00494
00495
if (ARGUMENT_PRESENT(ExistingToken->ProxyData)) {
00496
00497
Status =
SepCopyProxyData(
00498 &NewProxyData,
00499 ExistingToken->ProxyData
00500 );
00501
00502
if (!
NT_SUCCESS(
Status)) {
00503
00504
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
00505
ExFreePool( DynamicPart );
00506
return(
Status );
00507 }
00508
00509 }
else {
00510
00511 NewProxyData =
NULL;
00512 }
00513
00514
if (ARGUMENT_PRESENT( ExistingToken->AuditData )) {
00515
00516 NewAuditData =
ExAllocatePool(
PagedPool,
sizeof( SECURITY_TOKEN_AUDIT_DATA ));
00517
00518
if (NewAuditData ==
NULL) {
00519
00520
SepFreeProxyData( NewProxyData );
00521
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
00522
ExFreePool( DynamicPart );
00523
00524
return( STATUS_INSUFFICIENT_RESOURCES );
00525
00526 }
else {
00527
00528 *NewAuditData = *(ExistingToken->AuditData);
00529 }
00530
00531 }
else {
00532
00533 NewAuditData =
NULL;
00534
00535 }
00536
00537
00538
00539
00540
00541 TokenBodyLength = (ULONG)
sizeof(
TOKEN) +
00542 ExistingToken->VariableLength;
00543
00544 NonPagedPoolSize = TokenBodyLength;
00545 PagedPoolSize = ExistingToken->DynamicCharged;
00546
00547
Status =
ObCreateObject(
00548 RequestorMode,
00549
SepTokenObjectType,
00550
ObjectAttributes,
00551 RequestorMode,
00552
NULL,
00553 TokenBodyLength,
00554 PagedPoolSize,
00555 NonPagedPoolSize,
00556 (PVOID *)&NewToken
00557 );
00558
00559
if (!
NT_SUCCESS(
Status)) {
00560
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
00561
ExFreePool( DynamicPart );
00562
SepFreeProxyData( NewProxyData );
00563
00564
if (NewAuditData !=
NULL) {
00565
ExFreePool( NewAuditData );
00566 }
00567
00568
return Status;
00569 }
00570
00571
00572
00573
00574
00575
00576
SepAcquireTokenReadLock( ExistingToken );
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 NewToken->AuthenticationId = ExistingToken->AuthenticationId;
00589 NewToken->ModifiedId = ExistingToken->ModifiedId;
00590 NewToken->ExpirationTime = ExistingToken->ExpirationTime;
00591 NewToken->TokenSource = ExistingToken->TokenSource;
00592 NewToken->DynamicCharged = ExistingToken->DynamicCharged;
00593 NewToken->DynamicAvailable = ExistingToken->DynamicAvailable;
00594 NewToken->DefaultOwnerIndex = ExistingToken->DefaultOwnerIndex;
00595 NewToken->UserAndGroupCount = ExistingToken->UserAndGroupCount;
00596 NewToken->RestrictedSidCount = ExistingToken->RestrictedSidCount;
00597 NewToken->PrivilegeCount = ExistingToken->PrivilegeCount;
00598 NewToken->VariableLength = ExistingToken->VariableLength;
00599 NewToken->TokenFlags = ExistingToken->TokenFlags;
00600 NewToken->ProxyData = NewProxyData;
00601 NewToken->AuditData = NewAuditData;
00602 NewToken->SessionId = ExistingToken->SessionId;
00603
00604
00605
00606
00607
00608
00609
ExAllocateLocallyUniqueId( &(NewToken->TokenId) );
00610 NewToken->ParentTokenId = ExistingToken->ParentTokenId;
00611 NewToken->TokenInUse =
FALSE;
00612 NewToken->TokenType = TokenType;
00613 NewToken->ImpersonationLevel = ImpersonationLevel;
00614
00615
00616
00617
00618
00619
00620
00621 RtlCopyMemory( (PVOID)&(NewToken->VariablePart),
00622 (PVOID)&(ExistingToken->VariablePart),
00623 ExistingToken->VariableLength
00624 );
00625
00626
00627
00628
00629
00630
ASSERT( ARGUMENT_PRESENT(ExistingToken->UserAndGroups ) );
00631
ASSERT( (ULONG_PTR)(ExistingToken->UserAndGroups) >=
00632 (ULONG_PTR)(&(ExistingToken->VariablePart)) );
00633
00634 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->UserAndGroups) -
00635 (ULONG_PTR)(&(ExistingToken->VariablePart)));
00636
00637 NewToken->UserAndGroups =
00638 (PSID_AND_ATTRIBUTES)(FieldOffset + (ULONG_PTR)(&(NewToken->VariablePart)));
00639
00640
00641
00642
00643
00644
00645
Index = 0;
00646
00647
while (
Index < ExistingToken->UserAndGroupCount) {
00648
00649 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->UserAndGroups[
Index].Sid) -
00650 (ULONG_PTR)(&(ExistingToken->VariablePart)));
00651
00652 NewToken->UserAndGroups[
Index].Sid =
00653 (PSID)( FieldOffset + (ULONG_PTR)(&(NewToken->VariablePart)) );
00654
00655
Index += 1;
00656
00657 }
00658
00659
00660
00661
00662
00663
if (ARGUMENT_PRESENT(ExistingToken->RestrictedSids ) ) {
00664
ASSERT( (ULONG_PTR)(ExistingToken->RestrictedSids) >=
00665 (ULONG_PTR)(&(ExistingToken->VariablePart)) );
00666
00667 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->RestrictedSids) -
00668 (ULONG_PTR)(&(ExistingToken->VariablePart)));
00669
00670 NewToken->RestrictedSids =
00671 (PSID_AND_ATTRIBUTES)(FieldOffset + (ULONG_PTR)(&(NewToken->VariablePart)) );
00672
00673
00674
00675
00676
00677
00678
Index = 0;
00679
00680
while (
Index < ExistingToken->RestrictedSidCount) {
00681
00682 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->RestrictedSids[
Index].Sid) -
00683 (ULONG_PTR)(&(ExistingToken->VariablePart)));
00684
00685 NewToken->RestrictedSids[
Index].Sid =
00686 (PSID)( FieldOffset + (ULONG_PTR)(&(NewToken->VariablePart)) );
00687
00688
Index += 1;
00689
00690 }
00691 }
else {
00692 NewToken->RestrictedSids =
NULL;
00693 }
00694
00695
00696
00697
00698
00699
00700
if (ExistingToken->PrivilegeCount > 0) {
00701
ASSERT( ARGUMENT_PRESENT(ExistingToken->Privileges ) );
00702
ASSERT( (ULONG_PTR)(ExistingToken->Privileges) >=
00703 (ULONG_PTR)(&(ExistingToken->VariablePart)) );
00704
00705 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->Privileges) -
00706 (ULONG_PTR)(&(ExistingToken->VariablePart)));
00707 NewToken->Privileges = (PLUID_AND_ATTRIBUTES)(
00708 FieldOffset +
00709 (ULONG_PTR)(&(NewToken->VariablePart))
00710 );
00711 }
else {
00712
00713 NewToken->Privileges =
NULL;
00714
00715 }
00716
00717
00718
00719
00720
00721
00722 RtlCopyMemory( (PVOID)DynamicPart,
00723 (PVOID)(ExistingToken->DynamicPart),
00724 ExistingToken->DynamicCharged
00725 );
00726
00727 NewToken->DynamicPart = DynamicPart;
00728
00729
00730
00731
00732
00733
if (ARGUMENT_PRESENT(ExistingToken->DefaultDacl)) {
00734
00735
ASSERT( (ULONG_PTR)(ExistingToken->DefaultDacl) >=
00736 (ULONG_PTR)(ExistingToken->DynamicPart) );
00737
00738 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->DefaultDacl) -
00739 (ULONG_PTR)(ExistingToken->DynamicPart));
00740
00741 NewToken->DefaultDacl = (PACL)(FieldOffset + (ULONG_PTR)DynamicPart);
00742
00743 }
else {
00744
00745 NewToken->DefaultDacl =
NULL;
00746 }
00747
00748
00749
00750
00751
00752
00753
ASSERT(ARGUMENT_PRESENT(ExistingToken->PrimaryGroup));
00754
00755
ASSERT( (ULONG_PTR)(ExistingToken->PrimaryGroup) >=
00756 (ULONG_PTR)(ExistingToken->DynamicPart) );
00757
00758 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->PrimaryGroup) -
00759 (ULONG_PTR)(ExistingToken->DynamicPart));
00760
00761 NewToken->PrimaryGroup = (PACL)(FieldOffset + (ULONG_PTR)(DynamicPart));
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
if (EffectiveOnly) {
00775
SepMakeTokenEffectiveOnly( NewToken );
00776 }
00777
00778
00779
#ifdef TOKEN_DEBUG
00780
00781
00782
00783
DbgPrint(
"\n");
00784
DbgPrint(
"\n");
00785
DbgPrint(
"\n");
00786
DbgPrint(
"Duplicate token:\n");
00787 SepDumpToken( NewToken );
00788
00789
00791
#endif //TOKEN_DEBUG
00792
00793
00794
00795
00796
00797
SepReleaseTokenReadLock( ExistingToken );
00798
00799
00800 (*DuplicateToken) = NewToken;
00801
return Status;
00802 }
00803
00804
00805
VOID
00806 SepMakeTokenEffectiveOnly(
00807 IN PTOKEN Token
00808 )
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 {
00843
00844 ULONG
Index;
00845 ULONG ElementCount;
00846
00847
PAGED_CODE();
00848
00849
00850
00851
00852
00853 ElementCount =
Token->PrivilegeCount;
00854
Index = 0;
00855
00856
while (
Index < ElementCount) {
00857
00858
00859
00860
00861
00862
00863
00864
if ( !(
SepTokenPrivilegeAttributes(
Token,
Index) & SE_PRIVILEGE_ENABLED)
00865 ) {
00866
00867 (
Token->Privileges)[
Index] =
00868 (
Token->Privileges)[ElementCount - 1];
00869 ElementCount -= 1;
00870
00871 }
else {
00872
00873
Index += 1;
00874
00875 }
00876
00877 }
00878
00879
Token->PrivilegeCount = ElementCount;
00880
00881
00882
00883
00884
00885
00886 ElementCount =
Token->UserAndGroupCount;
00887
ASSERT( ElementCount >= 1 );
00888
Index = 1;
00889
00890
while (
Index < ElementCount) {
00891
00892
00893
00894
00895
00896
00897
if ( !(
SepTokenGroupAttributes(
Token,
Index) & SE_GROUP_ENABLED) &&
00898 !(
SepTokenGroupAttributes(
Token,
Index) & SE_GROUP_USE_FOR_DENY_ONLY) ) {
00899
00900
00901
00902
00903
00904
if (
RtlEqualSid(
00905
Token->UserAndGroups[
Index].Sid,
00906
SeAliasAdminsSid
00907 )) {
00908
Token->TokenFlags &= ~
TOKEN_HAS_ADMIN_GROUP;
00909 }
00910
00911
00912 (
Token->UserAndGroups)[
Index] =
00913 (
Token->UserAndGroups)[ElementCount - 1];
00914 ElementCount -= 1;
00915
00916
00917
00918 }
else {
00919
00920
Index += 1;
00921
00922 }
00923
00924 }
00925
00926
Token->UserAndGroupCount = ElementCount;
00927
00928
return;
00929 }
00930
00931
00932 BOOLEAN
00933 SepSidInSidAndAttributes (
00934 IN PSID_AND_ATTRIBUTES SidAndAttributes,
00935 IN ULONG SidCount,
00936 IN PSID PrincipalSelfSid,
00937 IN PSID Sid
00938 )
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 {
00972
00973 ULONG i;
00974 PISID MatchSid;
00975 ULONG SidLength;
00976
PTOKEN Token;
00977 PSID_AND_ATTRIBUTES TokenSid;
00978 ULONG UserAndGroupCount;
00979
00980
PAGED_CODE();
00981
00982
00983
if (!ARGUMENT_PRESENT( SidAndAttributes ) ) {
00984
return(
FALSE);
00985 }
00986
00987
00988
00989
00990
00991
00992
if ( PrincipalSelfSid !=
NULL &&
00993
RtlEqualSid(
SePrincipalSelfSid, Sid ) ) {
00994 Sid = PrincipalSelfSid;
00995 }
00996
00997
00998
00999
01000
01001
01002 SidLength = 8 + (4 * ((PISID)Sid)->SubAuthorityCount);
01003
01004
01005
01006
01007
01008 TokenSid = SidAndAttributes;
01009 UserAndGroupCount = SidCount;
01010
01011
01012
01013
01014
01015
01016
for (i = 0 ; i < UserAndGroupCount ; i += 1) {
01017 MatchSid = (PISID)TokenSid->Sid;
01018
01019
01020
01021
01022
01023
01024
if ((((PISID)Sid)->Revision == MatchSid->Revision) &&
01025 (SidLength == (8 + (4 * (ULONG)MatchSid->SubAuthorityCount)))) {
01026
if (RtlEqualMemory(Sid, MatchSid, SidLength)) {
01027
01028
return TRUE;
01029
01030 }
01031 }
01032
01033 TokenSid += 1;
01034 }
01035
01036
return FALSE;
01037 }
01038
01039
01040
VOID
01041 SepRemoveDisabledGroupsAndPrivileges(
01042 IN PTOKEN Token,
01043 IN ULONG Flags,
01044 IN ULONG GroupCount,
01045 IN PSID_AND_ATTRIBUTES GroupsToDisable,
01046 IN ULONG PrivilegeCount,
01047 IN PLUID_AND_ATTRIBUTES PrivilegesToDelete
01048 )
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 {
01093
01094 ULONG
Index;
01095 ULONG Index2;
01096 ULONG ElementCount;
01097 BOOLEAN Found;
01098
01099
PAGED_CODE();
01100
01101
01102
01103
01104
01105 ElementCount =
Token->PrivilegeCount;
01106
Index = 0;
01107
01108
while (
Index < ElementCount) {
01109
01110
01111
01112
01113
01114
01115
if (((Flags & DISABLE_MAX_PRIVILEGE) != 0) &&
01116 !
RtlEqualLuid(
01117 &
Token->Privileges[
Index].Luid,
01118 &
SeChangeNotifyPrivilege
01119 )) {
01120
01121 (
Token->Privileges)[
Index] =
01122 (
Token->Privileges)[ElementCount - 1];
01123 ElementCount -= 1;
01124
01125 }
else {
01126
01127
01128
01129
01130
01131
01132
01133 Found =
FALSE;
01134
for (Index2 = 0; Index2 < PrivilegeCount ; Index2++ ) {
01135
if (
RtlEqualLuid(
01136 &
Token->Privileges[
Index].Luid,
01137 &PrivilegesToDelete[Index2].Luid
01138 )) {
01139 (
Token->Privileges)[
Index] =
01140 (
Token->Privileges)[ElementCount - 1];
01141 ElementCount -= 1;
01142
01143
01144
01145
01146
01147
01148
if (
RtlEqualLuid(
01149 &PrivilegesToDelete[Index2].Luid,
01150 &
SeChangeNotifyPrivilege
01151 )) {
01152
Token->TokenFlags &= ~
TOKEN_HAS_TRAVERSE_PRIVILEGE;
01153 }
01154
01155
01156 Found =
TRUE;
01157
break;
01158
01159 }
01160 }
01161
01162
if (!Found) {
01163
Index += 1;
01164 }
01165 }
01166 }
01167
01168
Token->PrivilegeCount = ElementCount;
01169
01170
01171
01172
01173
01174 ElementCount =
Token->UserAndGroupCount;
01175
ASSERT( ElementCount >= 1 );
01176
Index = 0;
01177
01178
while (
Index < ElementCount) {
01179
01180
01181
01182
01183
01184
01185
if (
SepSidInSidAndAttributes(
01186 GroupsToDisable,
01187 GroupCount,
01188
NULL,
01189
Token->UserAndGroups[
Index].Sid
01190 )){
01191
01192 (
Token->UserAndGroups)[
Index].Attributes &= ~(SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT);
01193 (
Token->UserAndGroups)[
Index].Attributes |= SE_GROUP_USE_FOR_DENY_ONLY;
01194
01195
01196
01197
01198
01199
if (
Index ==
Token->DefaultOwnerIndex) {
01200
Token->DefaultOwnerIndex = 0;
01201 }
01202
01203
01204
01205
01206
01207
if (
RtlEqualSid(
01208
Token->UserAndGroups[
Index].Sid,
01209
SeAliasAdminsSid
01210 )) {
01211
01212
Token->TokenFlags &= ~
TOKEN_HAS_ADMIN_GROUP;
01213 }
01214 }
01215
01216
Index += 1;
01217
01218
01219 }
01220
01221
01222
return;
01223 }
01224
01225
01226
NTSTATUS
01227 SeCopyClientToken(
01228 IN PACCESS_TOKEN ClientToken,
01229 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
01230 IN KPROCESSOR_MODE RequestorMode,
01231 OUT PACCESS_TOKEN *DuplicateToken
01232 )
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272 {
01273
NTSTATUS Status;
01274 OBJECT_ATTRIBUTES
ObjectAttributes;
01275
PTOKEN NewToken;
01276
01277
PAGED_CODE();
01278
01279 InitializeObjectAttributes(
01280 &
ObjectAttributes,
01281
NULL,
01282 0,
01283
NULL,
01284
NULL
01285 );
01286
01287
Status =
SepDuplicateToken(
01288 (
PTOKEN)
ClientToken,
01289 &
ObjectAttributes,
01290
FALSE,
01291 TokenImpersonation,
01292 ImpersonationLevel,
01293 RequestorMode,
01294 &NewToken
01295 );
01296
01297 (*DuplicateToken) = (PACCESS_TOKEN)NewToken;
01298
01299
return Status;
01300
01301 }
01302
01303
01304
01305
NTSTATUS
01306 NtFilterToken (
01307 IN HANDLE ExistingTokenHandle,
01308 IN ULONG Flags,
01309 IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
01310 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
01311 IN PTOKEN_GROUPS RestrictedSids OPTIONAL,
01312 OUT PHANDLE NewTokenHandle
01313 )
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362 {
01363
01364
PTOKEN Token;
01365
PTOKEN NewToken;
01366
KPROCESSOR_MODE PreviousMode;
01367
NTSTATUS Status = STATUS_SUCCESS;
01368
01369 ULONG CapturedSidCount = 0;
01370 PSID_AND_ATTRIBUTES CapturedSids =
NULL;
01371 ULONG CapturedSidsLength = 0;
01372
01373 ULONG CapturedGroupCount = 0;
01374 PSID_AND_ATTRIBUTES CapturedGroups =
NULL;
01375 ULONG CapturedGroupsLength = 0;
01376
01377 ULONG CapturedPrivilegeCount = 0;
01378 PLUID_AND_ATTRIBUTES CapturedPrivileges =
NULL;
01379 ULONG CapturedPrivilegesLength = 0;
01380 ULONG
Index;
01381
01382 HANDLE LocalHandle;
01383
01384
OBJECT_HANDLE_INFORMATION HandleInformation;
01385 ACCESS_MASK EffectiveDesiredAccess;
01386
01387
PAGED_CODE();
01388
01389 PreviousMode = KeGetPreviousMode();
01390
01391
01392
01393
01394
01395
01396
try {
01397
01398
01399
01400
01401
01402
01403
ProbeForWriteHandle(NewTokenHandle);
01404
01405
01406
01407
01408
01409
if (ARGUMENT_PRESENT(SidsToDisable)) {
01410
ProbeForRead( SidsToDisable,
sizeof(TOKEN_GROUPS),
sizeof(ULONG) );
01411
01412 CapturedGroupCount = SidsToDisable->GroupCount;
01413
Status =
SeCaptureSidAndAttributesArray(
01414 SidsToDisable->Groups,
01415 CapturedGroupCount,
01416 PreviousMode,
01417
NULL, 0,
01418
PagedPool,
01419
TRUE,
01420 &CapturedGroups,
01421 &CapturedGroupsLength
01422 );
01423
01424 }
01425
01426
01427
01428
01429
01430
if (
NT_SUCCESS(
Status) && ARGUMENT_PRESENT(PrivilegesToDelete)) {
01431
ProbeForRead( PrivilegesToDelete,
sizeof(TOKEN_PRIVILEGES),
sizeof(ULONG) );
01432
01433 CapturedPrivilegeCount = PrivilegesToDelete->PrivilegeCount;
01434
Status =
SeCaptureLuidAndAttributesArray(
01435 PrivilegesToDelete->Privileges,
01436 CapturedPrivilegeCount,
01437 PreviousMode,
01438
NULL, 0,
01439
PagedPool,
01440
TRUE,
01441 &CapturedPrivileges,
01442 &CapturedPrivilegesLength
01443 );
01444
01445 }
01446
01447
01448
01449
01450
01451
if (
NT_SUCCESS(
Status) && ARGUMENT_PRESENT(RestrictedSids)) {
01452
ProbeForRead( RestrictedSids,
sizeof(TOKEN_GROUPS),
sizeof(ULONG) );
01453
01454 CapturedSidCount = RestrictedSids->GroupCount;
01455
Status =
SeCaptureSidAndAttributesArray(
01456 RestrictedSids->Groups,
01457 CapturedSidCount,
01458 PreviousMode,
01459
NULL, 0,
01460
PagedPool,
01461
TRUE,
01462 &CapturedSids,
01463 &CapturedSidsLength
01464 );
01465
01466 }
01467
01468
01469
01470 } except(
EXCEPTION_EXECUTE_HANDLER) {
01471
01472
Status = GetExceptionCode();
01473 }
01474
01475
if (!
NT_SUCCESS(
Status)) {
01476
goto Cleanup;
01477 }
01478
01479
01480
01481
01482
01483
for (
Index = 0;
Index < CapturedSidCount ;
Index++ )
01484 {
01485
if (CapturedSids[
Index].Attributes != 0) {
01486
Status = STATUS_INVALID_PARAMETER;
01487
goto Cleanup;
01488 }
01489 }
01490
01491
01492
01493
01494
01495
01496
Status =
ObReferenceObjectByHandle(
01497 ExistingTokenHandle,
01498 TOKEN_DUPLICATE,
01499
SepTokenObjectType,
01500 PreviousMode,
01501 (PVOID *)&
Token,
01502 &HandleInformation
01503 );
01504
01505
if ( !
NT_SUCCESS(
Status) ) {
01506
01507
goto Cleanup;
01508 }
01509
01510
01511
#ifdef TOKEN_DEBUG
01512
01513
01514
01515
SepAcquireTokenReadLock(
Token );
01516
DbgPrint(
"\n");
01517
DbgPrint(
"\n");
01518
DbgPrint(
"Token being filtered: \n");
01519 SepDumpToken(
Token );
01520
SepReleaseTokenReadLock(
Token );
01521
01522
01524
#endif //TOKEN_DEBUG
01525
01526
01527
01528
01529
01530
01531
01532 EffectiveDesiredAccess = HandleInformation.
GrantedAccess;
01533
01534
01535
01536
01537
01538
01539
01540 NewToken =
NULL;
01541
Status =
SepFilterToken(
01542
Token,
01543 PreviousMode,
01544 Flags,
01545 CapturedGroupCount,
01546 CapturedGroups,
01547 CapturedPrivilegeCount,
01548 CapturedPrivileges,
01549 CapturedSidCount,
01550 CapturedSids,
01551 CapturedSidsLength,
01552 &NewToken
01553 );
01554
01555
01556
if (
NT_SUCCESS(
Status)) {
01557
01558
01559
01560
01561
01562
Status =
ObInsertObject( NewToken,
01563
NULL,
01564 EffectiveDesiredAccess,
01565 0,
01566 (PVOID *)
NULL,
01567 &LocalHandle
01568 );
01569
01570
if (!
NT_SUCCESS(
Status )) {
01571
#ifdef TOKEN_DEBUG
01572
DbgPrint(
"SE: ObInsertObject failed (%x) for token at %x\n",
Status, NewToken );
01573
#endif
01574
}
01575
01576 }
else
01577
if (NewToken !=
NULL) {
01578
#ifdef TOKEN_DEBUG
01579
DbgPrint(
"SE: SepFilterToken failed (%x) but allocated token at %x\n",
Status, NewToken );
01580
#endif
01581
}
01582
01583
01584
01585
01586
01587
ObDereferenceObject( (PVOID)
Token );
01588
01589
01590
01591
01592
01593
01594
01595
01596
if (
NT_SUCCESS(
Status)) {
01597
try { *NewTokenHandle = LocalHandle; }
01598 except(
EXCEPTION_EXECUTE_HANDLER) {
01599
Status = GetExceptionCode();
01600 }
01601 }
01602
01603 Cleanup:
01604
01605
if (CapturedGroups !=
NULL) {
01606
SeReleaseSidAndAttributesArray(
01607 CapturedGroups,
01608 PreviousMode,
01609
TRUE
01610 );
01611 }
01612
01613
if (CapturedPrivileges !=
NULL) {
01614
SeReleaseLuidAndAttributesArray(
01615 CapturedPrivileges,
01616 PreviousMode,
01617
TRUE
01618 );
01619 }
01620
01621
if (CapturedSids !=
NULL) {
01622
SeReleaseSidAndAttributesArray(
01623 CapturedSids,
01624 PreviousMode,
01625
TRUE
01626 );
01627 }
01628
01629
return Status;
01630 }
01631
01632
01633
NTSTATUS
01634 SeFilterToken (
01635 IN PACCESS_TOKEN ExistingToken,
01636 IN ULONG Flags,
01637 IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
01638 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
01639 IN PTOKEN_GROUPS RestrictedSids OPTIONAL,
01640 OUT PACCESS_TOKEN * NewToken
01641 )
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690 {
01691
01692
PTOKEN Token;
01693
PTOKEN FilteredToken =
NULL;
01694
KPROCESSOR_MODE PreviousMode;
01695
NTSTATUS Status = STATUS_SUCCESS;
01696 ULONG
Index;
01697
01698 ULONG CapturedSidCount = 0;
01699 PSID_AND_ATTRIBUTES CapturedSids =
NULL;
01700 ULONG CapturedSidsLength = 0;
01701
01702 ULONG CapturedGroupCount = 0;
01703 PSID_AND_ATTRIBUTES CapturedGroups =
NULL;
01704 ULONG CapturedGroupsLength = 0;
01705
01706 ULONG CapturedPrivilegeCount = 0;
01707 PLUID_AND_ATTRIBUTES CapturedPrivileges =
NULL;
01708 ULONG CapturedPrivilegesLength = 0;
01709
01710 HANDLE LocalHandle;
01711
01712
OBJECT_HANDLE_INFORMATION HandleInformation;
01713 ACCESS_MASK EffectiveDesiredAccess;
01714
01715
PAGED_CODE();
01716
01717 PreviousMode = KeGetPreviousMode();
01718
01719
01720
01721
01722
01723 *NewToken =
NULL;
01724
01725
01726
01727
01728
01729
01730
if (ARGUMENT_PRESENT(SidsToDisable)) {
01731
01732 CapturedGroupCount = SidsToDisable->GroupCount;
01733 CapturedGroups = SidsToDisable->Groups;
01734
01735 }
01736
01737
01738
01739
01740
01741
if (ARGUMENT_PRESENT(PrivilegesToDelete)) {
01742
01743 CapturedPrivilegeCount = PrivilegesToDelete->PrivilegeCount;
01744 CapturedPrivileges = PrivilegesToDelete->Privileges;
01745
01746 }
01747
01748
01749
01750
01751
01752
if (ARGUMENT_PRESENT(RestrictedSids)) {
01753
01754 CapturedSidCount = RestrictedSids->GroupCount;
01755 CapturedSids = RestrictedSids->Groups;
01756
01757
01758
01759
01760
01761
for (
Index = 0;
Index < CapturedSidCount ;
Index++ ) {
01762
if (CapturedSids[
Index].Attributes != 0) {
01763
return(STATUS_INVALID_PARAMETER);
01764 }
01765 }
01766
01767 }
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
Token = (
PTOKEN) ExistingToken;
01778
01779
01780
#ifdef TOKEN_DEBUG
01781
01782
01783
01784
SepAcquireTokenReadLock(
Token );
01785
DbgPrint(
"\n");
01786
DbgPrint(
"\n");
01787
DbgPrint(
"Token being filtered: \n");
01788 SepDumpToken(
Token );
01789
SepReleaseTokenReadLock(
Token );
01790
01791
01793
#endif //TOKEN_DEBUG
01794
01795
01796
01797
01798
01799
01800
Status =
SepFilterToken(
01801
Token,
01802
KernelMode,
01803 Flags,
01804 CapturedGroupCount,
01805 CapturedGroups,
01806 CapturedPrivilegeCount,
01807 CapturedPrivileges,
01808 CapturedSidCount,
01809 CapturedSids,
01810 CapturedSidsLength,
01811 &FilteredToken
01812 );
01813
01814
01815
if (
NT_SUCCESS(
Status)) {
01816
01817
01818
01819
01820
01821
Status =
ObInsertObject( FilteredToken,
01822
NULL,
01823 0,
01824 0,
01825 (PVOID *)
NULL,
01826 &LocalHandle
01827 );
01828
01829
if (!
NT_SUCCESS(
Status )) {
01830
#ifdef TOKEN_DEBUG
01831
DbgPrint(
"SE: ObInsertObject failed (%x) for token at %x\n",
Status, NewToken );
01832
#endif
01833
}
else {
01834
Status =
ObReferenceObjectByHandle(
01835 LocalHandle,
01836 TOKEN_IMPERSONATE,
01837
SepTokenObjectType,
01838
KernelMode,
01839 (PVOID * ) NewToken,
01840
NULL
01841 );
01842
01843 (
VOID)
NtClose(LocalHandle);
01844
01845 }
01846
01847 }
else if (NewToken !=
NULL) {
01848
#ifdef TOKEN_DEBUG
01849
DbgPrint(
"SE: SepFilterToken failed (%x) but allocated token at %x\n",
Status, NewToken );
01850
#endif
01851
}
01852
01853
01854
01855
return Status;
01856 }
01857
01858
NTSTATUS
01859 SeFastFilterToken(
01860 IN PACCESS_TOKEN ExistingToken,
01861 IN KPROCESSOR_MODE RequestorMode,
01862 IN ULONG Flags,
01863 IN ULONG GroupCount,
01864 IN PSID_AND_ATTRIBUTES GroupsToDisable OPTIONAL,
01865 IN ULONG PrivilegeCount,
01866 IN PLUID_AND_ATTRIBUTES PrivilegesToDelete OPTIONAL,
01867 IN ULONG SidCount,
01868 IN PSID_AND_ATTRIBUTES RestrictedSids OPTIONAL,
01869 IN ULONG SidLength,
01870 OUT PACCESS_TOKEN * FilteredToken
01871 )
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922 {
01923
return SepFilterToken( (
PTOKEN) ExistingToken,
01924 RequestorMode,
01925 Flags,
01926 GroupCount,
01927 GroupsToDisable,
01928 PrivilegeCount,
01929 PrivilegesToDelete,
01930 SidCount,
01931 RestrictedSids,
01932 SidLength,
01933 (
PTOKEN *) FilteredToken );
01934 }
01935
01936
01937
01938
NTSTATUS
01939 SepFilterToken(
01940 IN PTOKEN ExistingToken,
01941 IN KPROCESSOR_MODE RequestorMode,
01942 IN ULONG Flags,
01943 IN ULONG GroupCount,
01944 IN PSID_AND_ATTRIBUTES GroupsToDisable OPTIONAL,
01945 IN ULONG PrivilegeCount,
01946 IN PLUID_AND_ATTRIBUTES PrivilegesToDelete OPTIONAL,
01947 IN ULONG SidCount,
01948 IN PSID_AND_ATTRIBUTES RestrictedSids OPTIONAL,
01949 IN ULONG SidLength,
01950 OUT PTOKEN * FilteredToken
01951 )
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009 {
02010
NTSTATUS Status;
02011
02012
PTOKEN NewToken;
02013 PULONG DynamicPart;
02014 ULONG PagedPoolSize;
02015 ULONG NonPagedPoolSize;
02016 ULONG TokenBodyLength;
02017 ULONG FieldOffset;
02018 ULONG_PTR NextFree;
02019 PSID NextSidFree;
02020 ULONG VariableLength;
02021
02022 ULONG
Index;
02023
02024 PSECURITY_TOKEN_PROXY_DATA NewProxyData;
02025 PSECURITY_TOKEN_AUDIT_DATA NewAuditData;
02026 OBJECT_ATTRIBUTES ObjA ;
02027
02028
02029
PAGED_CODE();
02030
02031
ASSERT(
sizeof(SECURITY_IMPERSONATION_LEVEL) <=
sizeof(ULONG) );
02032
02033
02034
02035
02036
02037
02038
02039
02040
Status =
SepReferenceLogonSession( &(ExistingToken->AuthenticationId) );
02041
ASSERT(
NT_SUCCESS(
Status) );
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054 DynamicPart = (PULONG)
ExAllocatePoolWithTag(
02055
PagedPool,
02056 ExistingToken->DynamicCharged,
02057 'dTeS'
02058 );
02059
02060
if (DynamicPart ==
NULL) {
02061
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
02062
return( STATUS_INSUFFICIENT_RESOURCES );
02063 }
02064
02065
if (ARGUMENT_PRESENT(ExistingToken->ProxyData)) {
02066
02067
Status =
SepCopyProxyData(
02068 &NewProxyData,
02069 ExistingToken->ProxyData
02070 );
02071
02072
if (!
NT_SUCCESS(
Status)) {
02073
02074
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
02075
ExFreePool( DynamicPart );
02076
return(
Status );
02077 }
02078
02079 }
else {
02080
02081 NewProxyData =
NULL;
02082 }
02083
02084
if (ARGUMENT_PRESENT( ExistingToken->AuditData )) {
02085
02086 NewAuditData =
ExAllocatePool(
PagedPool,
sizeof( SECURITY_TOKEN_AUDIT_DATA ));
02087
02088
if (NewAuditData ==
NULL) {
02089
02090
SepFreeProxyData( NewProxyData );
02091
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
02092
ExFreePool( DynamicPart );
02093
02094
return( STATUS_INSUFFICIENT_RESOURCES );
02095
02096 }
else {
02097
02098 *NewAuditData = *(ExistingToken->AuditData);
02099 }
02100
02101 }
else {
02102
02103 NewAuditData =
NULL;
02104
02105 }
02106
02107
02108
02109
02110
02111 VariableLength = ExistingToken->VariableLength + SidLength;
02112
02113 TokenBodyLength = (ULONG)
sizeof(
TOKEN) +
02114 VariableLength;
02115
02116 NonPagedPoolSize = TokenBodyLength;
02117 PagedPoolSize = ExistingToken->DynamicCharged;
02118
02119 InitializeObjectAttributes( &ObjA,
NULL, 0,
NULL,
NULL );
02120
02121
Status =
ObCreateObject(
02122 RequestorMode,
02123
SepTokenObjectType,
02124
NULL,
02125 RequestorMode,
02126
NULL,
02127 TokenBodyLength,
02128 PagedPoolSize,
02129 NonPagedPoolSize,
02130 (PVOID *)&NewToken
02131 );
02132
02133
if (!
NT_SUCCESS(
Status)) {
02134
SepDeReferenceLogonSession( &(ExistingToken->AuthenticationId) );
02135
ExFreePool( DynamicPart );
02136
SepFreeProxyData( NewProxyData );
02137
02138
if (NewAuditData !=
NULL) {
02139
ExFreePool( NewAuditData );
02140 }
02141
02142
return Status;
02143 }
02144
02145
02146
02147
02148
02149
02150
SepAcquireTokenReadLock( ExistingToken );
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162 NewToken->AuthenticationId = ExistingToken->AuthenticationId;
02163 NewToken->ExpirationTime = ExistingToken->ExpirationTime;
02164 NewToken->TokenSource = ExistingToken->TokenSource;
02165 NewToken->DynamicCharged = ExistingToken->DynamicCharged;
02166 NewToken->DynamicAvailable = ExistingToken->DynamicAvailable;
02167 NewToken->DefaultOwnerIndex = ExistingToken->DefaultOwnerIndex;
02168 NewToken->UserAndGroupCount = ExistingToken->UserAndGroupCount;
02169 NewToken->SessionId = ExistingToken->SessionId;
02170 NewToken->RestrictedSidCount = 0;
02171 NewToken->PrivilegeCount = ExistingToken->PrivilegeCount;
02172 NewToken->VariableLength = VariableLength;
02173 NewToken->TokenFlags = ExistingToken->TokenFlags;
02174 NewToken->ProxyData = NewProxyData;
02175 NewToken->AuditData = NewAuditData;
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
ExAllocateLocallyUniqueId( &(NewToken->ModifiedId) );
02188
ExAllocateLocallyUniqueId( &(NewToken->TokenId) );
02189 NewToken->ParentTokenId = ExistingToken->TokenId;
02190 NewToken->TokenInUse =
FALSE;
02191 NewToken->TokenType = ExistingToken->TokenType;
02192 NewToken->ImpersonationLevel = ExistingToken->ImpersonationLevel;
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206 NextFree = (ULONG_PTR)(&NewToken->VariablePart);
02207 NewToken->Privileges = (PLUID_AND_ATTRIBUTES)NextFree;
02208
RtlCopyLuidAndAttributesArray( ExistingToken->PrivilegeCount,
02209 ExistingToken->Privileges,
02210 (PLUID_AND_ATTRIBUTES)NextFree
02211 );
02212
02213 NextFree += (ExistingToken->PrivilegeCount * (ULONG)
sizeof(LUID_AND_ATTRIBUTES));
02214 VariableLength -= ( (ExistingToken->PrivilegeCount * (ULONG)
sizeof(LUID_AND_ATTRIBUTES)) );
02215
02216
02217
02218
02219
02220
02221
02222
#define MAX(_x_,_y_) ((_x_) > (_y_) ? (_x_) : (_y_))
02223
02224 NextSidFree = (PSID) (NextFree + (ExistingToken->UserAndGroupCount +
02225
MAX(ExistingToken->RestrictedSidCount,SidCount)) *
sizeof(SID_AND_ATTRIBUTES));
02226
02227 NewToken->UserAndGroups = (PSID_AND_ATTRIBUTES) NextFree;
02228
02229
02230
02231
02232
02233
02234
Status =
RtlCopySidAndAttributesArray(
02235 ExistingToken->UserAndGroupCount,
02236 ExistingToken->UserAndGroups,
02237 VariableLength,
02238 (PSID_AND_ATTRIBUTES)NextFree,
02239 NextSidFree,
02240 &NextSidFree,
02241 &VariableLength
02242 );
02243
02244
02245
ASSERT(
NT_SUCCESS(
Status));
02246 NextFree += (ExistingToken->UserAndGroupCount * (ULONG)
sizeof(SID_AND_ATTRIBUTES));
02247
02248
02249
02250
02251
02252
02253 NewToken->RestrictedSids = (PSID_AND_ATTRIBUTES) NextFree;
02254
02255
02256
for (
Index = 0;
Index < SidCount ;
Index++ ) {
02257
if ( ( ExistingToken->RestrictedSidCount == 0 ) ||
02258
SepSidInSidAndAttributes(
02259 ExistingToken->RestrictedSids,
02260 ExistingToken->RestrictedSidCount,
02261
NULL,
02262 RestrictedSids[
Index].Sid
02263 )) {
02264
02265
Status =
RtlCopySidAndAttributesArray(
02266 1,
02267 &RestrictedSids[
Index],
02268 VariableLength,
02269 (PSID_AND_ATTRIBUTES)NextFree,
02270 NextSidFree,
02271 &NextSidFree,
02272 &VariableLength
02273 );
02274
ASSERT(
NT_SUCCESS(
Status));
02275 NextFree +=
sizeof(SID_AND_ATTRIBUTES);
02276 NewToken->RestrictedSids[NewToken->RestrictedSidCount].Attributes =
02277 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
02278 NewToken->RestrictedSidCount++;
02279
02280 }
02281 }
02282
02283
02284
02285
02286
02287
02288
02289
02290
if ((ExistingToken->RestrictedSidCount != 0) &&
02291 (NewToken->RestrictedSidCount == 0)) {
02292
02293
SepReleaseTokenReadLock( ExistingToken );
02294
02295
Status = STATUS_INVALID_PARAMETER;
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
ExFreePool( DynamicPart );
02308
02309
02310
02311
02312
02313
02314 NewToken->DynamicPart =
NULL;
02315
02316
ObDereferenceObject( NewToken );
02317
02318
return(
Status);
02319 }
02320
02321
02322
02323
02324
02325
02326
if (NewToken->RestrictedSidCount > 0) {
02327 NewToken->TokenFlags |=
TOKEN_IS_RESTRICTED;
02328 }
02329
02330
02331
02332
02333
02334
02335 RtlCopyMemory( (PVOID)DynamicPart,
02336 (PVOID)(ExistingToken->DynamicPart),
02337 ExistingToken->DynamicCharged
02338 );
02339
02340 NewToken->DynamicPart = DynamicPart;
02341
02342
02343
02344
02345
02346
if (ARGUMENT_PRESENT(ExistingToken->DefaultDacl)) {
02347
02348
ASSERT( (ULONG_PTR)(ExistingToken->DefaultDacl) >=
02349 (ULONG_PTR)(ExistingToken->DynamicPart) );
02350
02351 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->DefaultDacl) -
02352 (ULONG_PTR)(ExistingToken->DynamicPart));
02353
02354 NewToken->DefaultDacl = (PACL)(FieldOffset + (ULONG_PTR)DynamicPart);
02355
02356 }
else {
02357
02358 NewToken->DefaultDacl =
NULL;
02359 }
02360
02361
02362
02363
02364
02365
02366
ASSERT(ARGUMENT_PRESENT(ExistingToken->PrimaryGroup));
02367
02368
ASSERT( (ULONG_PTR)(ExistingToken->PrimaryGroup) >=
02369 (ULONG_PTR)(ExistingToken->DynamicPart) );
02370
02371 FieldOffset = (ULONG)((ULONG_PTR)(ExistingToken->PrimaryGroup) -
02372 (ULONG_PTR)(ExistingToken->DynamicPart));
02373
02374 NewToken->PrimaryGroup = (PACL)(FieldOffset + (ULONG_PTR)(DynamicPart));
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
SepRemoveDisabledGroupsAndPrivileges(
02388 NewToken,
02389 Flags,
02390 GroupCount,
02391 GroupsToDisable,
02392 PrivilegeCount,
02393 PrivilegesToDelete
02394 );
02395
02396
02397
02398
#ifdef TOKEN_DEBUG
02399
02400
02401
02402
DbgPrint(
"\n");
02403
DbgPrint(
"\n");
02404
DbgPrint(
"\n");
02405
DbgPrint(
"Filter token:\n");
02406 SepDumpToken( NewToken );
02407
02408
02410
#endif //TOKEN_DEBUG
02411
02412
02413
02414
02415
02416
SepReleaseTokenReadLock( ExistingToken );
02417
02418
02419 (*FilteredToken) = NewToken;
02420
return Status;
02421 }
02422
02423