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 "tokenp.h"
00031
#include <sertlp.h>
00032
00033
00034
00035
00036
00037
00038
#if DBG
00039
00040
extern BOOLEAN SepDumpSD;
00041
extern BOOLEAN SepDumpToken;
00042 BOOLEAN SepShowAccessFail;
00043
00044
#endif // DBG
00045
00046
00047
00048
VOID
00049
SepUpdateParentTypeList (
00050 IN
PIOBJECT_TYPE_LIST ObjectTypeList,
00051 IN ULONG ObjectTypeListLength,
00052 IN ULONG StartIndex
00053 );
00054
00055 typedef enum {
00056
UpdateRemaining,
00057
UpdateCurrentGranted,
00058
UpdateCurrentDenied
00059 }
ACCESS_MASK_FIELD_TO_UPDATE;
00060
00061
VOID
00062
SepAddAccessTypeList (
00063 IN
PIOBJECT_TYPE_LIST ObjectTypeList,
00064 IN ULONG ObjectTypeListLength,
00065 IN ULONG StartIndex,
00066 IN ACCESS_MASK AccessMask,
00067 IN ACCESS_MASK_FIELD_TO_UPDATE FieldToUpdate
00068 );
00069
00070
NTSTATUS
00071
SeAccessCheckByType (
00072 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00073 IN PSID PrincipalSelfSid,
00074 IN HANDLE ClientToken,
00075 IN ACCESS_MASK DesiredAccess,
00076 IN POBJECT_TYPE_LIST ObjectTypeList OPTIONAL,
00077 IN ULONG ObjectTypeListLength,
00078 IN PGENERIC_MAPPING GenericMapping,
00079 OUT PPRIVILEGE_SET PrivilegeSet,
00080 IN OUT PULONG PrivilegeSetLength,
00081 OUT PACCESS_MASK GrantedAccess,
00082 OUT PNTSTATUS AccessStatus,
00083 IN BOOLEAN ReturnResultList
00084 );
00085
00086
VOID
00087
SepMaximumAccessCheck(
00088 IN
PTOKEN EToken,
00089 IN PTOKEN PrimaryToken,
00090 IN PACL Dacl,
00091 IN PSID PrincipalSelfSid,
00092 IN ULONG LocalTypeListLength,
00093 IN
PIOBJECT_TYPE_LIST LocalTypeList,
00094 IN ULONG ObjectTypeListLength,
00095 IN BOOLEAN Restricted
00096 );
00097
00098
VOID
00099
SepNormalAccessCheck(
00100 IN ACCESS_MASK Remaining,
00101 IN PTOKEN EToken,
00102 IN PTOKEN PrimaryToken,
00103 IN PACL Dacl,
00104 IN PSID PrincipalSelfSid,
00105 IN ULONG LocalTypeListLength,
00106 IN
PIOBJECT_TYPE_LIST LocalTypeList,
00107 IN ULONG ObjectTypeListLength,
00108 IN BOOLEAN Restricted
00109 );
00110
00111 BOOLEAN
00112
SepSidInTokenEx (
00113 IN PACCESS_TOKEN AToken,
00114 IN PSID PrincipalSelfSid,
00115 IN PSID Sid,
00116 IN BOOLEAN DenyAce,
00117 IN BOOLEAN Restricted
00118 );
00119
00120
00121
#ifdef ALLOC_PRAGMA
00122
#pragma alloc_text(PAGE,SeCaptureObjectTypeList)
00123
#pragma alloc_text(PAGE,SeFreeCapturedObjectTypeList)
00124
#pragma alloc_text(PAGE,SepUpdateParentTypeList)
00125
#pragma alloc_text(PAGE,SepObjectInTypeList)
00126
#pragma alloc_text(PAGE,SepAddAccessTypeList)
00127
#pragma alloc_text(PAGE,SepSidInToken)
00128
#pragma alloc_text(PAGE,SepSidInTokenEx)
00129
#pragma alloc_text(PAGE,SepAccessCheck)
00130
#pragma alloc_text(PAGE,NtAccessCheck)
00131
#pragma alloc_text(PAGE,NtAccessCheckByType)
00132
#pragma alloc_text(PAGE,SeAccessCheckByType)
00133
#pragma alloc_text(PAGE,SeFreePrivileges)
00134
#pragma alloc_text(PAGE,SeAccessCheck)
00135
#pragma alloc_text(PAGE,SePrivilegePolicyCheck)
00136
#pragma alloc_text(PAGE,SepTokenIsOwner)
00137
#pragma alloc_text(PAGE,SeFastTraverseCheck)
00138
#pragma alloc_text(PAGE,SepMaximumAccessCheck)
00139
#pragma alloc_text(PAGE,SepNormalAccessCheck)
00140
#endif
00141
00142
00143
NTSTATUS
00144 SeCaptureObjectTypeList (
00145 IN POBJECT_TYPE_LIST ObjectTypeList OPTIONAL,
00146 IN ULONG ObjectTypeListLength,
00147 IN KPROCESSOR_MODE RequestorMode,
00148 OUT
PIOBJECT_TYPE_LIST *CapturedObjectTypeList
00149 )
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 {
00185
NTSTATUS Status = STATUS_SUCCESS;
00186 ULONG i;
00187
PIOBJECT_TYPE_LIST LocalTypeList =
NULL;
00188
00189 ULONG Levels[ACCESS_MAX_LEVEL+1];
00190
00191
PAGED_CODE();
00192
00193
00194
00195
00196
00197 *CapturedObjectTypeList =
NULL;
00198
00199
if (RequestorMode !=
UserMode) {
00200
return STATUS_NOT_IMPLEMENTED;
00201 }
00202
00203
try {
00204
00205
if ( ObjectTypeListLength == 0 ) {
00206
00207
00208
00209 }
else if ( !ARGUMENT_PRESENT(ObjectTypeList) ) {
00210
00211
Status = STATUS_INVALID_PARAMETER;
00212
00213 }
else {
00214
00215
if ( !
IsValidElementCount( ObjectTypeListLength,
IOBJECT_TYPE_LIST ) )
00216 {
00217
Status = STATUS_INVALID_PARAMETER ;
00218
00219
00220
00221
00222
00223 leave ;
00224 }
00225
00226
ProbeForRead( ObjectTypeList,
00227
sizeof(OBJECT_TYPE_LIST) * ObjectTypeListLength,
00228
sizeof(ULONG)
00229 );
00230
00231
00232
00233
00234
00235 LocalTypeList =
ExAllocatePoolWithTag(
PagedPool,
sizeof(
IOBJECT_TYPE_LIST) * ObjectTypeListLength, 'tOeS' );
00236
00237
if ( LocalTypeList ==
NULL ) {
00238
Status = STATUS_INSUFFICIENT_RESOURCES;
00239
00240
00241
00242
00243
00244 }
else {
00245 GUID * CapturedObjectType;
00246
for ( i=0; i<ObjectTypeListLength; i++ ) {
00247
USHORT CurrentLevel;
00248
00249
00250
00251
00252 CurrentLevel = ObjectTypeList[i].Level;
00253
if ( CurrentLevel > ACCESS_MAX_LEVEL ) {
00254
Status = STATUS_INVALID_PARAMETER;
00255
break;
00256 }
00257
00258
00259
00260
00261 LocalTypeList[i].
Level = CurrentLevel;
00262 LocalTypeList[i].
Flags = 0;
00263 CapturedObjectType = ObjectTypeList[i].ObjectType;
00264
ProbeForRead(
00265 CapturedObjectType,
00266
sizeof(GUID),
00267
sizeof(ULONG)
00268 );
00269 LocalTypeList[i].
ObjectType = *CapturedObjectType;
00270 LocalTypeList[i].
Remaining = 0;
00271 LocalTypeList[i].
CurrentGranted = 0;
00272 LocalTypeList[i].
CurrentDenied = 0;
00273
00274
00275
00276
00277
00278
00279
if ( i == 0 ) {
00280
if ( CurrentLevel != 0 ) {
00281
Status = STATUS_INVALID_PARAMETER;
00282
break;
00283 }
00284
00285 }
else {
00286
00287
00288
00289
00290
00291
00292
00293
if ( CurrentLevel > LocalTypeList[i-1].
Level + 1 ) {
00294
Status = STATUS_INVALID_PARAMETER;
00295
break;
00296 }
00297
00298
00299
00300
00301
if ( CurrentLevel == 0 ) {
00302
Status = STATUS_INVALID_PARAMETER;
00303
break;
00304 }
00305
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
if ( CurrentLevel == 0 ) {
00315 LocalTypeList[i].
ParentIndex = -1;
00316 }
else {
00317 LocalTypeList[i].
ParentIndex = Levels[CurrentLevel-1];
00318 }
00319
00320
00321
00322
00323
00324 Levels[CurrentLevel] = i;
00325
00326 }
00327
00328 }
00329
00330 }
00331
00332 } except(
EXCEPTION_EXECUTE_HANDLER) {
00333
00334
00335
00336
00337
00338
00339
if ( LocalTypeList !=
NULL ) {
00340
ExFreePool( LocalTypeList );
00341 LocalTypeList =
NULL;
00342 }
00343
00344
Status = GetExceptionCode();
00345 }
00346
00347 *CapturedObjectTypeList = LocalTypeList;
00348
return Status;
00349 }
00350
00351
00352
VOID
00353 SeFreeCapturedObjectTypeList(
00354 IN PVOID ObjectTypeList
00355 )
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 {
00375
PAGED_CODE();
00376
00377
if ( ObjectTypeList !=
NULL ) {
00378
ExFreePool( ObjectTypeList );
00379 }
00380
00381
return;
00382 }
00383
00384
00385
00386
00387 BOOLEAN
00388 SepObjectInTypeList (
00389 IN GUID *ObjectType,
00390 IN
PIOBJECT_TYPE_LIST ObjectTypeList,
00391 IN ULONG ObjectTypeListLength,
00392 OUT PULONG ReturnedIndex
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 ULONG
Index;
00421 GUID *LocalObjectType;
00422
00423
PAGED_CODE();
00424
00425
ASSERT(
sizeof(GUID) ==
sizeof(ULONG) * 4 );
00426
for (
Index=0;
Index<ObjectTypeListLength;
Index++ ) {
00427
00428 LocalObjectType = &ObjectTypeList[
Index].ObjectType;
00429
00430
if ( RtlpIsEqualGuid( ObjectType, LocalObjectType ) ) {
00431 *ReturnedIndex =
Index;
00432
return TRUE;
00433 }
00434 }
00435
00436
return FALSE;
00437 }
00438
00439
00440
VOID
00441 SepUpdateParentTypeList (
00442 IN
PIOBJECT_TYPE_LIST ObjectTypeList,
00443 IN ULONG ObjectTypeListLength,
00444 IN ULONG StartIndex
00445 )
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 {
00481 ULONG
Index;
00482 ULONG ParentIndex;
00483 ULONG Level;
00484 ACCESS_MASK NewRemaining = 0;
00485 ACCESS_MASK NewCurrentGranted = 0xFFFFFFFF;
00486 ACCESS_MASK NewCurrentDenied = 0;
00487
00488
PAGED_CODE();
00489
00490
00491
00492
00493
00494
00495
if ( ObjectTypeList[StartIndex].ParentIndex == -1 ) {
00496
return;
00497 }
00498
00499
00500
00501
00502
00503
00504 ParentIndex = ObjectTypeList[StartIndex].ParentIndex;
00505 Level = ObjectTypeList[StartIndex].Level;
00506
00507
00508
00509
00510
00511
for (
Index=ParentIndex+1;
Index<ObjectTypeListLength;
Index++ ) {
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
if ( ObjectTypeList[
Index].Level <= ObjectTypeList[ParentIndex].Level ) {
00522
break;
00523 }
00524
00525
00526
00527
00528
00529
if ( ObjectTypeList[
Index].Level != Level ) {
00530
continue;
00531 }
00532
00533
00534
00535
00536
00537 NewRemaining |= ObjectTypeList[
Index].Remaining;
00538 NewCurrentGranted &= ObjectTypeList[
Index].CurrentGranted;
00539 NewCurrentDenied |= ObjectTypeList[
Index].CurrentDenied;
00540
00541 }
00542
00543
00544
00545
00546
00547
00548
if ( NewRemaining == ObjectTypeList[ParentIndex].Remaining &&
00549 NewCurrentGranted == ObjectTypeList[ParentIndex].CurrentGranted &&
00550 NewCurrentDenied == ObjectTypeList[ParentIndex].CurrentDenied ) {
00551
return;
00552 }
00553
00554
00555
00556
00557
00558
00559 ObjectTypeList[ParentIndex].Remaining = NewRemaining;
00560 ObjectTypeList[ParentIndex].CurrentGranted = NewCurrentGranted;
00561 ObjectTypeList[ParentIndex].CurrentDenied = NewCurrentDenied;
00562
00563
00564
00565
00566
00567
SepUpdateParentTypeList( ObjectTypeList,
00568 ObjectTypeListLength,
00569 ParentIndex );
00570 }
00571
00572
00573
VOID
00574 SepAddAccessTypeList (
00575 IN
PIOBJECT_TYPE_LIST ObjectTypeList,
00576 IN ULONG ObjectTypeListLength,
00577 IN ULONG StartIndex,
00578 IN ACCESS_MASK AccessMask,
00579 IN ACCESS_MASK_FIELD_TO_UPDATE FieldToUpdate
00580 )
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 {
00613 ULONG
Index;
00614 ACCESS_MASK OldRemaining;
00615 ACCESS_MASK OldCurrentGranted;
00616 ACCESS_MASK OldCurrentDenied;
00617 BOOLEAN AvoidParent =
FALSE;
00618
00619
PAGED_CODE();
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
switch (FieldToUpdate ) {
00631
case UpdateRemaining:
00632
00633 OldRemaining = ObjectTypeList[StartIndex].Remaining;
00634 ObjectTypeList[StartIndex].Remaining = OldRemaining & ~AccessMask;
00635
00636
if ( OldRemaining == ObjectTypeList[StartIndex].Remaining ) {
00637
return;
00638 }
00639
break;
00640
00641
case UpdateCurrentGranted:
00642
00643 OldCurrentGranted = ObjectTypeList[StartIndex].CurrentGranted;
00644 ObjectTypeList[StartIndex].CurrentGranted |=
00645 AccessMask & ~ObjectTypeList[StartIndex].CurrentDenied;
00646
00647
if ( OldCurrentGranted == ObjectTypeList[StartIndex].CurrentGranted ) {
00648
00649
00650
00651
00652
00653
00654
00655
00656 AvoidParent =
TRUE;
00657 }
00658
break;
00659
00660
case UpdateCurrentDenied:
00661
00662 OldCurrentDenied = ObjectTypeList[StartIndex].CurrentDenied;
00663 ObjectTypeList[StartIndex].CurrentDenied |=
00664 AccessMask & ~ObjectTypeList[StartIndex].CurrentGranted;
00665
00666
if ( OldCurrentDenied == ObjectTypeList[StartIndex].CurrentDenied ) {
00667
return;
00668 }
00669
break;
00670
00671
default:
00672
return;
00673 }
00674
00675
00676
00677
00678
00679
00680
if ( !AvoidParent ) {
00681
SepUpdateParentTypeList( ObjectTypeList,
00682 ObjectTypeListLength,
00683 StartIndex );
00684 }
00685
00686
00687
00688
00689
00690
for (
Index=StartIndex+1;
Index<ObjectTypeListLength;
Index++ ) {
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
if ( ObjectTypeList[
Index].Level <= ObjectTypeList[StartIndex].Level ) {
00701
break;
00702 }
00703
00704
00705
00706
00707
00708
switch (FieldToUpdate) {
00709
case UpdateRemaining:
00710
00711 ObjectTypeList[
Index].Remaining &= ~AccessMask;
00712
break;
00713
00714
case UpdateCurrentGranted:
00715
00716 ObjectTypeList[
Index].CurrentGranted |=
00717 AccessMask & ~ObjectTypeList[
Index].CurrentDenied;
00718
break;
00719
00720
case UpdateCurrentDenied:
00721
00722 ObjectTypeList[
Index].CurrentDenied |=
00723 AccessMask & ~ObjectTypeList[
Index].CurrentGranted;
00724
break;
00725
00726
default:
00727
return;
00728 }
00729 }
00730 }
00731
00732 BOOLEAN
00733 SepSidInToken (
00734 IN PACCESS_TOKEN AToken,
00735 IN PSID PrincipalSelfSid,
00736 IN PSID Sid,
00737 IN BOOLEAN DenyAce
00738 )
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 {
00772
00773 ULONG i;
00774 PISID MatchSid;
00775 ULONG SidLength;
00776
PTOKEN Token;
00777 PSID_AND_ATTRIBUTES TokenSid;
00778 ULONG UserAndGroupCount;
00779
00780
PAGED_CODE();
00781
00782
#if DBG
00783
00784
SepDumpTokenInfo(AToken);
00785
00786
#endif
00787
00788
00789
00790
00791
00792
00793
if ( PrincipalSelfSid !=
NULL &&
00794
RtlEqualSid(
SePrincipalSelfSid, Sid ) ) {
00795 Sid = PrincipalSelfSid;
00796 }
00797
00798
00799
00800
00801
00802
00803 SidLength = 8 + (4 * ((PISID)Sid)->SubAuthorityCount);
00804
00805
00806
00807
00808
00809
Token = (
PTOKEN)AToken;
00810 TokenSid =
Token->UserAndGroups;
00811 UserAndGroupCount =
Token->UserAndGroupCount;
00812
00813
00814
00815
00816
00817
00818
for (i = 0 ; i < UserAndGroupCount ; i += 1) {
00819 MatchSid = (PISID)TokenSid->Sid;
00820
00821
00822
00823
00824
00825
00826
if ((((PISID)Sid)->Revision == MatchSid->Revision) &&
00827 (SidLength == (8 + (4 * (ULONG)MatchSid->SubAuthorityCount)))) {
00828
if (RtlEqualMemory(Sid, MatchSid, SidLength)) {
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
if ((i == 0) || (TokenSid->Attributes & SE_GROUP_ENABLED) ||
00840 (DenyAce && (TokenSid->Attributes & SE_GROUP_USE_FOR_DENY_ONLY))) {
00841
return TRUE;
00842
00843 }
else {
00844
return FALSE;
00845 }
00846 }
00847 }
00848
00849 TokenSid += 1;
00850 }
00851
00852
return FALSE;
00853 }
00854
00855 BOOLEAN
00856 SepSidInTokenEx (
00857 IN PACCESS_TOKEN AToken,
00858 IN PSID PrincipalSelfSid,
00859 IN PSID Sid,
00860 IN BOOLEAN DenyAce,
00861 IN BOOLEAN Restricted
00862 )
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 {
00900
00901 ULONG i;
00902 PISID MatchSid;
00903 ULONG SidLength;
00904
PTOKEN Token;
00905 PSID_AND_ATTRIBUTES TokenSid;
00906 ULONG UserAndGroupCount;
00907
00908
PAGED_CODE();
00909
00910
#if DBG
00911
00912
SepDumpTokenInfo(AToken);
00913
00914
#endif
00915
00916
00917
00918
00919
00920
00921
if ( PrincipalSelfSid !=
NULL &&
00922
RtlEqualSid(
SePrincipalSelfSid, Sid ) ) {
00923 Sid = PrincipalSelfSid;
00924 }
00925
00926
00927
00928
00929
00930
00931 SidLength = 8 + (4 * ((PISID)Sid)->SubAuthorityCount);
00932
00933
00934
00935
00936
00937
Token = (
PTOKEN)AToken;
00938
if (
Restricted) {
00939 TokenSid =
Token->RestrictedSids;
00940 UserAndGroupCount =
Token->RestrictedSidCount;
00941 }
else {
00942 TokenSid =
Token->UserAndGroups;
00943 UserAndGroupCount =
Token->UserAndGroupCount;
00944 }
00945
00946
00947
00948
00949
00950
00951
for (i = 0; i < UserAndGroupCount ; i += 1) {
00952 MatchSid = (PISID)TokenSid->Sid;
00953
00954
00955
00956
00957
00958
00959
if ((((PISID)Sid)->Revision == MatchSid->Revision) &&
00960 (SidLength == (8 + (4 * (ULONG)MatchSid->SubAuthorityCount)))) {
00961
if (RtlEqualMemory(Sid, MatchSid, SidLength)) {
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
if ((!
Restricted && (i == 0) && ((TokenSid->Attributes & SE_GROUP_USE_FOR_DENY_ONLY) == 0)) ||
00974 (TokenSid->Attributes & SE_GROUP_ENABLED) ||
00975 (DenyAce && (TokenSid->Attributes & SE_GROUP_USE_FOR_DENY_ONLY))) {
00976
return TRUE;
00977
00978 }
else {
00979
return FALSE;
00980 }
00981
00982 }
00983 }
00984
00985 TokenSid += 1;
00986 }
00987
00988
return FALSE;
00989 }
00990
00991
VOID
00992 SepMaximumAccessCheck(
00993 IN PTOKEN EToken,
00994 IN PTOKEN PrimaryToken,
00995 IN PACL Dacl,
00996 IN PSID PrincipalSelfSid,
00997 IN ULONG LocalTypeListLength,
00998 IN
PIOBJECT_TYPE_LIST LocalTypeList,
00999 IN ULONG ObjectTypeListLength,
01000 IN BOOLEAN Restricted
01001 )
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 {
01035 ULONG i,j;
01036 PVOID Ace;
01037 ULONG AceCount;
01038 ULONG
Index;
01039 ULONG ResultListIndex;
01040
01041
01042
01043
01044
01045
01046
if (
Restricted ) {
01047
for ( j=0; j<LocalTypeListLength; j++ ) {
01048 LocalTypeList[j].Remaining = LocalTypeList[j].CurrentGranted;
01049 LocalTypeList[j].CurrentGranted = 0;
01050 }
01051 }
01052
01053
01054 AceCount =
Dacl->AceCount;
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
for ( i = 0, Ace =
FirstAce(
Dacl ) ;
01072 i < AceCount ;
01073 i++, Ace =
NextAce( Ace )
01074 ) {
01075
01076
if ( !(((PACE_HEADER)Ace)->AceFlags & INHERIT_ONLY_ACE)) {
01077
01078
if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_ACE_TYPE) ) {
01079
01080
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, &((PACCESS_ALLOWED_ACE)Ace)->SidStart,
FALSE,
Restricted )) {
01081
01082
01083
01084
01085
01086
01087
01088
if ( LocalTypeListLength == 1 ) {
01089 LocalTypeList->CurrentGranted |=
01090 (((PACCESS_ALLOWED_ACE)Ace)->Mask & ~LocalTypeList->CurrentDenied);
01091 }
else {
01092
01093
01094
01095
SepAddAccessTypeList(
01096 LocalTypeList,
01097 LocalTypeListLength,
01098 0,
01099 ((PACCESS_ALLOWED_ACE)Ace)->Mask,
01100
UpdateCurrentGranted );
01101 }
01102 }
01103
01104
01105
01106
01107
01108 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE) ) {
01109 GUID *ObjectTypeInAce;
01110
01111
01112
01113
01114
01115
01116 ObjectTypeInAce = RtlObjectAceObjectType(Ace);
01117
01118
if ( ObjectTypeInAce ==
NULL ) {
01119
01120
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
FALSE,
Restricted ) ) {
01121
01122
01123
if ( LocalTypeListLength == 1 ) {
01124 LocalTypeList->CurrentGranted |=
01125 (((PACCESS_ALLOWED_OBJECT_ACE)Ace)->Mask & ~LocalTypeList->CurrentDenied);
01126 }
else {
01127
SepAddAccessTypeList(
01128 LocalTypeList,
01129 LocalTypeListLength,
01130 0,
01131 ((PACCESS_ALLOWED_OBJECT_ACE)Ace)->Mask,
01132
UpdateCurrentGranted );
01133 }
01134 }
01135
01136
01137
01138
01139
01140
01141 }
else if ( ObjectTypeListLength == 0 ) {
01142
01143
01144
01145
01146
01147
01148
01149
01150 }
else {
01151
01152
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
FALSE,
Restricted ) ) {
01153
01154
if (
SepObjectInTypeList( ObjectTypeInAce,
01155 LocalTypeList,
01156 LocalTypeListLength,
01157 &
Index ) ) {
01158
SepAddAccessTypeList(
01159 LocalTypeList,
01160 LocalTypeListLength,
01161
Index,
01162 ((PACCESS_ALLOWED_OBJECT_ACE)Ace)->Mask,
01163
UpdateCurrentGranted );
01164 }
01165 }
01166 }
01167
01168 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE) ) {
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
if (
SepSidInTokenEx(EToken, PrincipalSelfSid, RtlCompoundAceClientSid( Ace ),
FALSE,
Restricted) &&
01180
SepSidInTokenEx(
PrimaryToken,
NULL, RtlCompoundAceServerSid( Ace ),
FALSE,
FALSE)
01181 ) {
01182
01183
01184
01185
01186
01187
01188
01189
if ( LocalTypeListLength == 1 ) {
01190 LocalTypeList->CurrentGranted |=
01191 (((PCOMPOUND_ACCESS_ALLOWED_ACE)Ace)->Mask & ~LocalTypeList->CurrentDenied);
01192 }
else {
01193
01194
01195
01196
SepAddAccessTypeList(
01197 LocalTypeList,
01198 LocalTypeListLength,
01199 0,
01200 ((PCOMPOUND_ACCESS_ALLOWED_ACE)Ace)->Mask,
01201
UpdateCurrentGranted );
01202 }
01203
01204 }
01205
01206
01207 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_DENIED_ACE_TYPE) ) {
01208
01209
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, &((PACCESS_DENIED_ACE)Ace)->SidStart,
TRUE,
Restricted )) {
01210
01211
01212
01213
01214
01215
01216
01217
if ( LocalTypeListLength == 1 ) {
01218 LocalTypeList->CurrentDenied |=
01219 (((PACCESS_DENIED_ACE)Ace)->Mask & ~LocalTypeList->CurrentGranted);
01220 }
else {
01221
01222
01223
01224
SepAddAccessTypeList(
01225 LocalTypeList,
01226 LocalTypeListLength,
01227 0,
01228 ((PACCESS_DENIED_ACE)Ace)->Mask,
01229
UpdateCurrentDenied );
01230 }
01231 }
01232
01233
01234
01235
01236
01237 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_DENIED_OBJECT_ACE_TYPE) ) {
01238
01239
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
TRUE,
Restricted ) ) {
01240 GUID *ObjectTypeInAce;
01241
01242
01243
01244
01245
01246
01247
01248 ObjectTypeInAce = RtlObjectAceObjectType(Ace);
01249
01250
if ( ObjectTypeInAce ==
NULL ) {
01251
01252
if ( LocalTypeListLength == 1 ) {
01253 LocalTypeList->CurrentDenied |=
01254 (((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask & ~LocalTypeList->CurrentGranted);
01255 }
else {
01256
01257
01258
01259
01260
01261
SepAddAccessTypeList(
01262 LocalTypeList,
01263 LocalTypeListLength,
01264 0,
01265 ((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask,
01266
UpdateCurrentDenied );
01267 }
01268
01269
01270
01271
01272
01273 }
else if ( ObjectTypeListLength == 0 ) {
01274
01275 LocalTypeList->CurrentDenied |=
01276 (((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask & ~LocalTypeList->CurrentGranted);
01277
01278
01279
01280
01281
01282
01283
01284 }
else if (
SepObjectInTypeList( ObjectTypeInAce,
01285 LocalTypeList,
01286 LocalTypeListLength,
01287 &
Index ) ) {
01288
01289
SepAddAccessTypeList(
01290 LocalTypeList,
01291 LocalTypeListLength,
01292
Index,
01293 ((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask,
01294
UpdateCurrentDenied );
01295
01296 }
01297 }
01298 }
01299 }
01300 }
01301 }
01302
01303
VOID
01304 SepNormalAccessCheck(
01305 IN ACCESS_MASK Remaining,
01306 IN PTOKEN EToken,
01307 IN PTOKEN PrimaryToken,
01308 IN PACL Dacl,
01309 IN PSID PrincipalSelfSid,
01310 IN ULONG LocalTypeListLength,
01311 IN
PIOBJECT_TYPE_LIST LocalTypeList,
01312 IN ULONG ObjectTypeListLength,
01313 IN BOOLEAN Restricted
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 ULONG i,j;
01351 PVOID Ace;
01352 ULONG AceCount;
01353 ULONG
Index;
01354
01355 AceCount =
Dacl->AceCount;
01356
01357
01358
01359
01360
01361
for ( j=0; j<LocalTypeListLength; j++ ) {
01362 LocalTypeList[j].Remaining = Remaining;
01363 }
01364
01365
01366
01367
01368
01369
for ( i = 0, Ace =
FirstAce(
Dacl ) ;
01370 ( i < AceCount ) && ( LocalTypeList->Remaining != 0 ) ;
01371 i++, Ace =
NextAce( Ace ) ) {
01372
01373
if ( !(((PACE_HEADER)Ace)->AceFlags & INHERIT_ONLY_ACE)) {
01374
01375
01376
01377
01378
01379
if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_ACE_TYPE) ) {
01380
01381
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, &((PACCESS_ALLOWED_ACE )Ace)->SidStart,
FALSE,
Restricted ) ) {
01382
01383
01384
if ( LocalTypeListLength == 1 ) {
01385 LocalTypeList->Remaining &= ~((PACCESS_ALLOWED_ACE)Ace)->Mask;
01386 }
else {
01387
01388
01389
01390
SepAddAccessTypeList(
01391 LocalTypeList,
01392 LocalTypeListLength,
01393 0,
01394 ((PACCESS_ALLOWED_ACE)Ace)->Mask,
01395
UpdateRemaining );
01396 }
01397
01398 }
01399
01400
01401
01402
01403
01404 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE) ) {
01405 GUID *ObjectTypeInAce;
01406
01407
01408
01409
01410
01411
01412 ObjectTypeInAce = RtlObjectAceObjectType(Ace);
01413
01414
if ( ObjectTypeInAce ==
NULL ) {
01415
01416
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
FALSE,
Restricted ) ) {
01417
01418
01419
if ( LocalTypeListLength == 1 ) {
01420 LocalTypeList->Remaining &= ~((PACCESS_ALLOWED_ACE)Ace)->Mask;
01421 }
else {
01422
SepAddAccessTypeList(
01423 LocalTypeList,
01424 LocalTypeListLength,
01425 0,
01426 ((PACCESS_ALLOWED_OBJECT_ACE)Ace)->Mask,
01427
UpdateRemaining );
01428 }
01429 }
01430
01431
01432
01433
01434
01435
01436 }
else if ( ObjectTypeListLength == 0 ) {
01437
01438
01439
01440
01441
01442
01443
01444
01445 }
else {
01446
01447
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
FALSE,
Restricted ) ) {
01448
01449
if (
SepObjectInTypeList( ObjectTypeInAce,
01450 LocalTypeList,
01451 LocalTypeListLength,
01452 &
Index ) ) {
01453
SepAddAccessTypeList(
01454 LocalTypeList,
01455 LocalTypeListLength,
01456
Index,
01457 ((PACCESS_ALLOWED_OBJECT_ACE)Ace)->Mask,
01458
UpdateRemaining );
01459 }
01460 }
01461 }
01462
01463
01464
01465
01466
01467
01468 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE) ) {
01469
01470
01471
01472
01473
01474
01475
if (
SepSidInTokenEx(EToken, PrincipalSelfSid, RtlCompoundAceClientSid( Ace ),
FALSE,
Restricted) &&
01476
SepSidInTokenEx(
PrimaryToken,
NULL, RtlCompoundAceServerSid( Ace ),
FALSE,
Restricted) ) {
01477
01478
01479
if ( LocalTypeListLength == 1 ) {
01480 LocalTypeList->Remaining &= ~((PCOMPOUND_ACCESS_ALLOWED_ACE)Ace)->Mask;
01481 }
else {
01482
SepAddAccessTypeList(
01483 LocalTypeList,
01484 LocalTypeListLength,
01485 0,
01486 ((PCOMPOUND_ACCESS_ALLOWED_ACE)Ace)->Mask,
01487
UpdateRemaining );
01488 }
01489 }
01490
01491
01492
01493
01494
01495
01496
01497 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_DENIED_ACE_TYPE) ) {
01498
01499
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, &((PACCESS_DENIED_ACE)Ace)->SidStart,
TRUE,
Restricted ) ) {
01500
01501
01502
01503
01504
01505
if (LocalTypeList->Remaining & ((PACCESS_DENIED_ACE)Ace)->Mask) {
01506
01507
break;
01508 }
01509 }
01510
01511
01512
01513
01514
01515 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_DENIED_OBJECT_ACE_TYPE) ) {
01516
01517
if (
SepSidInTokenEx( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
TRUE,
Restricted ) ) {
01518 GUID *ObjectTypeInAce;
01519
01520
01521
01522
01523
01524
01525
01526 ObjectTypeInAce = RtlObjectAceObjectType(Ace);
01527
if ( ObjectTypeInAce ==
NULL ||
01528 ObjectTypeListLength == 0 ) {
01529
01530
01531
01532
01533
01534
if (LocalTypeList->Remaining & ((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask) {
01535
break;
01536 }
01537
01538
01539
01540
01541
01542
01543 }
else if (
SepObjectInTypeList( ObjectTypeInAce,
01544 LocalTypeList,
01545 LocalTypeListLength,
01546 &
Index ) ) {
01547
01548
if (LocalTypeList[
Index].Remaining & ((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask) {
01549
break;
01550 }
01551
01552 }
01553 }
01554 }
01555
01556 }
01557 }
01558
01559
01560 }
01561
01562
01563
VOID
01564 SepAccessCheck (
01565 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
01566 IN PSID PrincipalSelfSid,
01567 IN PTOKEN PrimaryToken,
01568 IN PTOKEN ClientToken OPTIONAL,
01569 IN ACCESS_MASK DesiredAccess,
01570 IN
PIOBJECT_TYPE_LIST ObjectTypeList OPTIONAL,
01571 IN ULONG ObjectTypeListLength,
01572 IN PGENERIC_MAPPING GenericMapping,
01573 IN ACCESS_MASK PreviouslyGrantedAccess,
01574 IN KPROCESSOR_MODE PreviousMode,
01575 OUT PACCESS_MASK GrantedAccess,
01576 OUT PPRIVILEGE_SET *Privileges OPTIONAL,
01577 OUT PNTSTATUS AccessStatus,
01578 IN BOOLEAN ReturnResultList,
01579 OUT PBOOLEAN ReturnSomeAccessGranted,
01580 OUT PBOOLEAN ReturnSomeAccessDenied
01581 )
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
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
NTSTATUS Status;
01674 ACCESS_MASK Remaining;
01675
01676
01677 PACL
Dacl;
01678
01679 PVOID Ace;
01680 ULONG AceCount;
01681
01682 ULONG i;
01683 ULONG j;
01684 ULONG
Index;
01685 ULONG PrivilegeCount = 0;
01686 BOOLEAN Success =
FALSE;
01687 BOOLEAN SystemSecurity =
FALSE;
01688 BOOLEAN WriteOwner =
FALSE;
01689
PTOKEN EToken;
01690
01691
IOBJECT_TYPE_LIST FixedTypeList;
01692
PIOBJECT_TYPE_LIST LocalTypeList;
01693 ULONG LocalTypeListLength;
01694 ULONG ResultListIndex;
01695
01696
PAGED_CODE();
01697
01698
#if DBG
01699
01700
SepDumpSecurityDescriptor(
01701 SecurityDescriptor,
01702
"Input to SeAccessCheck\n"
01703 );
01704
01705
if (ARGUMENT_PRESENT(
ClientToken )) {
01706
SepDumpTokenInfo(
ClientToken );
01707 }
01708
01709
SepDumpTokenInfo(
PrimaryToken );
01710
01711
#endif
01712
01713
01714 EToken = ARGUMENT_PRESENT(
ClientToken ) ?
ClientToken :
PrimaryToken;
01715
01716
01717
01718
01719
01720
SeAssertMappedCanonicalAccess( DesiredAccess );
01721
01722 Remaining = DesiredAccess;
01723
01724
01725
01726
01727
01728
01729
01730
01731
if ( Remaining & ACCESS_SYSTEM_SECURITY ) {
01732
01733
01734
01735
01736
01737
01738
01739
ASSERT( ARGUMENT_PRESENT( Privileges ));
01740
01741 Success =
SepSinglePrivilegeCheck (
01742
SeSecurityPrivilege,
01743 EToken,
01744 PreviousMode
01745 );
01746
01747
if (!Success) {
01748 PreviouslyGrantedAccess = 0;
01749
Status = STATUS_PRIVILEGE_NOT_HELD;
01750
goto ReturnOneStatus;
01751 }
01752
01753
01754
01755
01756
01757
01758 Remaining &= ~ACCESS_SYSTEM_SECURITY;
01759 PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
01760
01761 PrivilegeCount++;
01762 SystemSecurity =
TRUE;
01763
01764
if ( Remaining == 0 ) {
01765
Status = STATUS_SUCCESS;
01766
goto ReturnOneStatus;
01767 }
01768
01769 }
01770
01771
01772
01773
01774
01775
01776
Dacl = RtlpDaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)SecurityDescriptor );
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
if ( !RtlpAreControlBitsSet(
01788 (PISECURITY_DESCRIPTOR)SecurityDescriptor,
01789 SE_DACL_PRESENT) || (
Dacl ==
NULL)) {
01790
01791
01792
01793
01794
01795
01796
#ifdef SECURE_NULL_DACLS
01797
if (
SeTokenIsRestricted( EToken )) {
01798
01799
01800
01801
01802
01803
01804
01805
ASSERT( Remaining != 0 );
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
if ( (Remaining == MAXIMUM_ALLOWED) && (PreviouslyGrantedAccess != (ACCESS_MASK)0) ) {
01817
Status = STATUS_SUCCESS;
01818
goto ReturnOneStatus;
01819
01820 }
else {
01821 PreviouslyGrantedAccess = 0;
01822
Status = STATUS_ACCESS_DENIED;
01823
goto ReturnOneStatus;
01824 }
01825 }
01826
#endif //SECURE_NULL_DACLS
01827
if (DesiredAccess & MAXIMUM_ALLOWED) {
01828
01829
01830
01831
01832
01833
01834
01835 PreviouslyGrantedAccess =
01836 GenericMapping->GenericAll |
01837 (DesiredAccess | PreviouslyGrantedAccess) & ~MAXIMUM_ALLOWED;
01838
01839 }
else {
01840
01841 PreviouslyGrantedAccess |= DesiredAccess;
01842 }
01843
01844
Status = STATUS_SUCCESS;
01845
goto ReturnOneStatus;
01846 }
01847
01848
01849
01850
01851
01852
01853
01854
if ( (Remaining & WRITE_OWNER) && ARGUMENT_PRESENT( Privileges ) ) {
01855
01856 Success =
SepSinglePrivilegeCheck (
01857
SeTakeOwnershipPrivilege,
01858 EToken,
01859 PreviousMode
01860 );
01861
01862
if (Success) {
01863
01864
01865
01866
01867
01868
01869 Remaining &= ~WRITE_OWNER;
01870 PreviouslyGrantedAccess |= WRITE_OWNER;
01871
01872 PrivilegeCount++;
01873 WriteOwner =
TRUE;
01874
01875
if ( Remaining == 0 ) {
01876
Status = STATUS_SUCCESS;
01877
goto ReturnOneStatus;
01878 }
01879 }
01880 }
01881
01882
01883
01884
01885
01886
01887
01888
if ((AceCount =
Dacl->AceCount) == 0) {
01889
01890
01891
01892
01893
01894
01895
01896
01897
ASSERT( Remaining != 0 );
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
if ( (Remaining == MAXIMUM_ALLOWED) && (PreviouslyGrantedAccess != (ACCESS_MASK)0) ) {
01909
Status = STATUS_SUCCESS;
01910
goto ReturnOneStatus;
01911
01912 }
else {
01913 PreviouslyGrantedAccess = 0;
01914
Status = STATUS_ACCESS_DENIED;
01915
goto ReturnOneStatus;
01916 }
01917 }
01918
01919
01920
01921
01922
01923
if ( ObjectTypeListLength == 0 ) {
01924 LocalTypeList = &FixedTypeList;
01925 LocalTypeListLength = 1;
01926 RtlZeroMemory( &FixedTypeList,
sizeof(FixedTypeList) );
01927 FixedTypeList.ParentIndex = -1;
01928 }
else {
01929 LocalTypeList = ObjectTypeList;
01930 LocalTypeListLength = ObjectTypeListLength;
01931 }
01932
01933
01934
01935
01936
01937
01938
01939
if ( (DesiredAccess & MAXIMUM_ALLOWED) != 0 ||
01940 ReturnResultList ) {
01941
01942
01943
01944
01945
01946
SepMaximumAccessCheck(
01947 EToken,
01948
PrimaryToken,
01949
Dacl,
01950 PrincipalSelfSid,
01951 LocalTypeListLength,
01952 LocalTypeList,
01953 ObjectTypeListLength,
01954
FALSE
01955 );
01956
01957
01958
01959
01960
01961
if (
SeTokenIsRestricted( EToken ) ) {
01962
SepMaximumAccessCheck(
01963 EToken,
01964
PrimaryToken,
01965
Dacl,
01966 PrincipalSelfSid,
01967 LocalTypeListLength,
01968 LocalTypeList,
01969 ObjectTypeListLength,
01970
TRUE
01971 );
01972 }
01973
01974
01975
01976
01977
01978
01979
01980
01981
if ( ReturnResultList ) {
01982 ACCESS_MASK GrantedAccessMask;
01983 ACCESS_MASK RequiredAccessMask;
01984 BOOLEAN SomeAccessGranted =
FALSE;
01985 BOOLEAN SomeAccessDenied =
FALSE;
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
if (DesiredAccess & MAXIMUM_ALLOWED) {
01996 GrantedAccessMask = (ACCESS_MASK) ~MAXIMUM_ALLOWED;
01997 RequiredAccessMask = (DesiredAccess | PreviouslyGrantedAccess) & ~MAXIMUM_ALLOWED;
01998 }
else {
01999 GrantedAccessMask = DesiredAccess | PreviouslyGrantedAccess;
02000 RequiredAccessMask = DesiredAccess | PreviouslyGrantedAccess;
02001 }
02002
02003
02004
02005
02006
02007
02008
02009
for ( ResultListIndex=0;
02010 ResultListIndex<LocalTypeListLength;
02011 ResultListIndex++ ) {
02012
02013
02014
02015
02016
02017
02018 GrantedAccess[ResultListIndex] =
02019 (LocalTypeList[ResultListIndex].
CurrentGranted |
02020 PreviouslyGrantedAccess ) &
02021 GrantedAccessMask;
02022
02023
02024
02025
02026
02027
if ( GrantedAccess[ResultListIndex] == 0 ) {
02028 AccessStatus[ResultListIndex] = STATUS_ACCESS_DENIED;
02029 SomeAccessDenied =
TRUE;
02030 }
else {
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
if ( ((~GrantedAccess[ResultListIndex]) & RequiredAccessMask ) != 0 ) {
02042 AccessStatus[ResultListIndex] = STATUS_ACCESS_DENIED;
02043 SomeAccessDenied =
TRUE;
02044 }
else {
02045 AccessStatus[ResultListIndex] = STATUS_SUCCESS;
02046 SomeAccessGranted =
TRUE;
02047 }
02048 }
02049 }
02050
02051
if ( SomeAccessGranted && PrivilegeCount != 0 ) {
02052
02053
SepAssemblePrivileges(
02054 PrivilegeCount,
02055 SystemSecurity,
02056 WriteOwner,
02057 Privileges
02058 );
02059 }
02060
02061
if ( ARGUMENT_PRESENT(ReturnSomeAccessGranted)) {
02062 *ReturnSomeAccessGranted = SomeAccessGranted;
02063 }
02064
if ( ARGUMENT_PRESENT(ReturnSomeAccessDenied)) {
02065 *ReturnSomeAccessDenied = SomeAccessDenied;
02066 }
02067
return;
02068
02069
02070
02071
02072
02073
02074 }
else {
02075
02076
02077
02078
02079
02080
02081
02082
02083 Remaining &= ~(MAXIMUM_ALLOWED | LocalTypeList->
CurrentGranted);
02084
02085
if (Remaining != 0) {
02086
02087
Status = STATUS_ACCESS_DENIED;
02088 PreviouslyGrantedAccess = 0;
02089
goto ReturnOneStatus;
02090
02091 }
02092
02093
02094
02095 PreviouslyGrantedAccess |= LocalTypeList->
CurrentGranted;
02096
Status = STATUS_SUCCESS;
02097
goto ReturnOneStatus;
02098
02099 }
02100
02101 }
02102
02103
02104
#ifdef notdef
02105
02106
02107
02108
for ( j=0; j<LocalTypeListLength; j++ ) {
02109 LocalTypeList[j].
Remaining = Remaining;
02110 }
02111
02112
02113
02114
02115
02116
for ( i = 0, Ace =
FirstAce(
Dacl ) ;
02117 ( i < AceCount ) && ( LocalTypeList->
Remaining != 0 ) ;
02118 i++, Ace =
NextAce( Ace ) ) {
02119
02120
if ( !(((PACE_HEADER)Ace)->AceFlags & INHERIT_ONLY_ACE)) {
02121
02122
02123
02124
02125
02126
if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_ACE_TYPE) ) {
02127
02128
if (
SepSidInToken( EToken, PrincipalSelfSid, &((PACCESS_ALLOWED_ACE)Ace)->SidStart,
FALSE ) ) {
02129
02130
02131
if ( LocalTypeListLength == 1 ) {
02132 LocalTypeList->
Remaining &= ~((PACCESS_ALLOWED_ACE)Ace)->Mask;
02133 }
else {
02134
02135
02136
02137
SepAddAccessTypeList(
02138 LocalTypeList,
02139 LocalTypeListLength,
02140 0,
02141 ((PACCESS_ALLOWED_ACE)Ace)->Mask,
02142
UpdateRemaining );
02143 }
02144
02145 }
02146
02147
02148
02149
02150
02151 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE) ) {
02152 GUID *ObjectTypeInAce;
02153
02154
02155
02156
02157
02158
02159 ObjectTypeInAce = RtlObjectAceObjectType(Ace);
02160
02161
if ( ObjectTypeInAce ==
NULL ) {
02162
02163
if (
SepSidInToken( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
FALSE ) ) {
02164
02165
02166
if ( LocalTypeListLength == 1 ) {
02167 LocalTypeList->
Remaining &= ~((PACCESS_ALLOWED_ACE)Ace)->Mask;
02168 }
else {
02169
SepAddAccessTypeList(
02170 LocalTypeList,
02171 LocalTypeListLength,
02172 0,
02173 ((PACCESS_ALLOWED_OBJECT_ACE)Ace)->Mask,
02174
UpdateRemaining );
02175 }
02176 }
02177
02178
02179
02180
02181
02182
02183 }
else if ( ObjectTypeListLength == 0 ) {
02184
02185
02186
02187
02188
02189
02190
02191
02192 }
else {
02193
02194
if (
SepSidInToken( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
FALSE ) ) {
02195
02196
if (
SepObjectInTypeList( ObjectTypeInAce,
02197 LocalTypeList,
02198 LocalTypeListLength,
02199 &
Index ) ) {
02200
SepAddAccessTypeList(
02201 LocalTypeList,
02202 LocalTypeListLength,
02203
Index,
02204 ((PACCESS_ALLOWED_OBJECT_ACE)Ace)->Mask,
02205
UpdateRemaining );
02206 }
02207 }
02208 }
02209
02210
02211
02212
02213
02214 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE) ) {
02215
02216
02217
02218
02219
02220
02221
if (
SepSidInToken(EToken, PrincipalSelfSid, RtlCompoundAceClientSid( Ace ),
FALSE) &&
02222
SepSidInToken(
PrimaryToken,
NULL, RtlCompoundAceServerSid( Ace ),
FALSE) ) {
02223
02224
02225
if ( LocalTypeListLength == 1 ) {
02226 LocalTypeList->
Remaining &= ~((PCOMPOUND_ACCESS_ALLOWED_ACE)Ace)->Mask;
02227 }
else {
02228
SepAddAccessTypeList(
02229 LocalTypeList,
02230 LocalTypeListLength,
02231 0,
02232 ((PCOMPOUND_ACCESS_ALLOWED_ACE)Ace)->Mask,
02233
UpdateRemaining );
02234 }
02235 }
02236
02237
02238
02239
02240
02241
02242
02243 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_DENIED_ACE_TYPE) ) {
02244
02245
if (
SepSidInToken( EToken, PrincipalSelfSid, &((PACCESS_DENIED_ACE)Ace)->SidStart,
TRUE ) ) {
02246
02247
02248
02249
02250
02251
if (LocalTypeList->
Remaining & ((PACCESS_DENIED_ACE)Ace)->Mask) {
02252
02253
break;
02254 }
02255 }
02256
02257
02258
02259
02260
02261 }
else if ( (((PACE_HEADER)Ace)->AceType == ACCESS_DENIED_OBJECT_ACE_TYPE) ) {
02262
02263
if (
SepSidInToken( EToken, PrincipalSelfSid, RtlObjectAceSid(Ace),
TRUE ) ) {
02264 GUID *ObjectTypeInAce;
02265
02266
02267
02268
02269
02270
02271
02272 ObjectTypeInAce = RtlObjectAceObjectType(Ace);
02273
if ( ObjectTypeInAce ==
NULL ||
02274 ObjectTypeListLength == 0 ) {
02275
02276
02277
02278
02279
02280
if (LocalTypeList->
Remaining & ((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask) {
02281
break;
02282 }
02283
02284
02285
02286
02287
02288
02289 }
else if (
SepObjectInTypeList( ObjectTypeInAce,
02290 LocalTypeList,
02291 LocalTypeListLength,
02292 &
Index ) ) {
02293
02294
if (LocalTypeList[
Index].
Remaining & ((PACCESS_DENIED_OBJECT_ACE)Ace)->Mask) {
02295
break;
02296 }
02297
02298 }
02299 }
02300 }
02301
02302 }
02303 }
02304
02305
#endif
02306
02307
02308
02309
02310
02311
SepNormalAccessCheck(
02312 Remaining,
02313 EToken,
02314
PrimaryToken,
02315
Dacl,
02316 PrincipalSelfSid,
02317 LocalTypeListLength,
02318 LocalTypeList,
02319 ObjectTypeListLength,
02320
FALSE
02321 );
02322
02323
if (LocalTypeList->
Remaining != 0) {
02324
Status = STATUS_ACCESS_DENIED;
02325 PreviouslyGrantedAccess = 0;
02326
goto ReturnOneStatus;
02327 }
02328
02329
02330
02331
02332
02333
if (
SeTokenIsRestricted( EToken ) ) {
02334
SepNormalAccessCheck(
02335 Remaining,
02336 EToken,
02337
PrimaryToken,
02338
Dacl,
02339 PrincipalSelfSid,
02340 LocalTypeListLength,
02341 LocalTypeList,
02342 ObjectTypeListLength,
02343
TRUE
02344 );
02345 }
02346
02347
02348
if (LocalTypeList->
Remaining != 0) {
02349
Status = STATUS_ACCESS_DENIED;
02350 PreviouslyGrantedAccess = 0;
02351
goto ReturnOneStatus;
02352 }
02353
02354
Status = STATUS_SUCCESS;
02355 PreviouslyGrantedAccess |= DesiredAccess;
02356
02357
02358
02359
02360
02361 ReturnOneStatus:
02362
if (
Status == STATUS_SUCCESS && PreviouslyGrantedAccess == 0 ) {
02363
Status = STATUS_ACCESS_DENIED;
02364 }
02365
02366
02367
02368
02369
02370
if ( ReturnResultList ) {
02371
for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) {
02372 AccessStatus[ResultListIndex] =
Status;
02373 GrantedAccess[ResultListIndex] = PreviouslyGrantedAccess;
02374 }
02375 }
else {
02376 *AccessStatus =
Status;
02377 *GrantedAccess = PreviouslyGrantedAccess;
02378 }
02379
02380
if (
NT_SUCCESS(
Status) ) {
02381
if ( PrivilegeCount > 0 ) {
02382
02383
SepAssemblePrivileges(
02384 PrivilegeCount,
02385 SystemSecurity,
02386 WriteOwner,
02387 Privileges
02388 );
02389 }
02390
02391
if ( ARGUMENT_PRESENT(ReturnSomeAccessGranted)) {
02392 *ReturnSomeAccessGranted =
TRUE;
02393 }
02394
if ( ARGUMENT_PRESENT(ReturnSomeAccessDenied)) {
02395 *ReturnSomeAccessDenied =
FALSE;
02396 }
02397 }
else {
02398
if ( ARGUMENT_PRESENT(ReturnSomeAccessGranted)) {
02399 *ReturnSomeAccessGranted =
FALSE;
02400 }
02401
if ( ARGUMENT_PRESENT(ReturnSomeAccessDenied)) {
02402 *ReturnSomeAccessDenied =
TRUE;;
02403 }
02404 }
02405
return;
02406
02407 }
02408
02409
02410
02411
02412
NTSTATUS
02413 NtAccessCheck (
02414 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02415 IN HANDLE ClientToken,
02416 IN ACCESS_MASK DesiredAccess,
02417 IN PGENERIC_MAPPING GenericMapping,
02418 OUT PPRIVILEGE_SET PrivilegeSet,
02419 IN OUT PULONG PrivilegeSetLength,
02420 OUT PACCESS_MASK GrantedAccess,
02421 OUT PNTSTATUS AccessStatus
02422 )
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474 {
02475
02476
PAGED_CODE();
02477
02478
return SeAccessCheckByType (
02479 SecurityDescriptor,
02480
NULL,
02481
ClientToken,
02482 DesiredAccess,
02483
NULL,
02484 0,
02485 GenericMapping,
02486 PrivilegeSet,
02487 PrivilegeSetLength,
02488 GrantedAccess,
02489 AccessStatus,
02490
FALSE );
02491
02492
02493 }
02494
02495
02496
02497
02498
02499
02500
NTSTATUS
02501 NtAccessCheckByType (
02502 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02503 IN PSID PrincipalSelfSid,
02504 IN HANDLE ClientToken,
02505 IN ACCESS_MASK DesiredAccess,
02506 IN POBJECT_TYPE_LIST ObjectTypeList OPTIONAL,
02507 IN ULONG ObjectTypeListLength,
02508 IN PGENERIC_MAPPING GenericMapping,
02509 OUT PPRIVILEGE_SET PrivilegeSet,
02510 IN OUT PULONG PrivilegeSetLength,
02511 OUT PACCESS_MASK GrantedAccess,
02512 OUT PNTSTATUS AccessStatus
02513 )
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578 {
02579
02580
PAGED_CODE();
02581
02582
return SeAccessCheckByType (
02583 SecurityDescriptor,
02584 PrincipalSelfSid,
02585
ClientToken,
02586 DesiredAccess,
02587 ObjectTypeList,
02588 ObjectTypeListLength,
02589 GenericMapping,
02590 PrivilegeSet,
02591 PrivilegeSetLength,
02592 GrantedAccess,
02593 AccessStatus,
02594
FALSE );
02595 }
02596
02597
02598
02599
02600
02601
NTSTATUS
02602 NtAccessCheckByTypeResultList (
02603 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02604 IN PSID PrincipalSelfSid,
02605 IN HANDLE ClientToken,
02606 IN ACCESS_MASK DesiredAccess,
02607 IN POBJECT_TYPE_LIST ObjectTypeList OPTIONAL,
02608 IN ULONG ObjectTypeListLength,
02609 IN PGENERIC_MAPPING GenericMapping,
02610 OUT PPRIVILEGE_SET PrivilegeSet,
02611 IN OUT PULONG PrivilegeSetLength,
02612 OUT PACCESS_MASK GrantedAccess,
02613 OUT PNTSTATUS AccessStatus
02614 )
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679 {
02680
02681
PAGED_CODE();
02682
02683
return SeAccessCheckByType (
02684 SecurityDescriptor,
02685 PrincipalSelfSid,
02686
ClientToken,
02687 DesiredAccess,
02688 ObjectTypeList,
02689 ObjectTypeListLength,
02690 GenericMapping,
02691 PrivilegeSet,
02692 PrivilegeSetLength,
02693 GrantedAccess,
02694 AccessStatus,
02695
TRUE );
02696 }
02697
02698
02699
02700
02701
02702
02703
NTSTATUS
02704 SeAccessCheckByType (
02705 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02706 IN PSID PrincipalSelfSid,
02707 IN HANDLE ClientToken,
02708 IN ACCESS_MASK DesiredAccess,
02709 IN POBJECT_TYPE_LIST ObjectTypeList OPTIONAL,
02710 IN ULONG ObjectTypeListLength,
02711 IN PGENERIC_MAPPING GenericMapping,
02712 OUT PPRIVILEGE_SET PrivilegeSet,
02713 IN OUT PULONG PrivilegeSetLength,
02714 OUT PACCESS_MASK GrantedAccess,
02715 OUT PNTSTATUS AccessStatus,
02716 IN BOOLEAN ReturnResultList
02717 )
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785 {
02786 ACCESS_MASK LocalGrantedAccess;
02787 PACCESS_MASK LocalGrantedAccessPointer =
NULL;
02788
NTSTATUS LocalAccessStatus;
02789 PNTSTATUS LocalAccessStatusPointer =
NULL;
02790
KPROCESSOR_MODE PreviousMode;
02791
NTSTATUS Status = STATUS_SUCCESS;
02792
PTOKEN Token =
NULL;
02793 PSECURITY_DESCRIPTOR CapturedSecurityDescriptor =
NULL;
02794 PSID CapturedPrincipalSelfSid =
NULL;
02795 ACCESS_MASK PreviouslyGrantedAccess = 0;
02796 GENERIC_MAPPING LocalGenericMapping;
02797
PIOBJECT_TYPE_LIST LocalObjectTypeList =
NULL;
02798 PPRIVILEGE_SET Privileges =
NULL;
02799
SECURITY_SUBJECT_CONTEXT SubjectContext;
02800 ULONG LocalPrivilegeSetLength;
02801 ULONG ResultListIndex;
02802
02803
PAGED_CODE();
02804
02805 PreviousMode = KeGetPreviousMode();
02806
02807
if (PreviousMode ==
KernelMode) {
02808
ASSERT( !ReturnResultList );
02809 *AccessStatus = STATUS_SUCCESS;
02810 *GrantedAccess = DesiredAccess;
02811
return(STATUS_SUCCESS);
02812 }
02813
02814
try {
02815
02816
if ( ReturnResultList ) {
02817
02818
if ( ObjectTypeListLength == 0 ) {
02819
Status = STATUS_INVALID_PARAMETER;
02820 leave ;
02821 }
02822
02823
if ( !
IsValidElementCount( ObjectTypeListLength, OBJECT_TYPE_LIST ) )
02824 {
02825
Status = STATUS_INVALID_PARAMETER ;
02826
02827 leave ;
02828 }
02829
02830
ProbeForWrite(
02831 AccessStatus,
02832
sizeof(
NTSTATUS) * ObjectTypeListLength,
02833
sizeof(ULONG)
02834 );
02835
02836
ProbeForWrite(
02837 GrantedAccess,
02838
sizeof(ACCESS_MASK) * ObjectTypeListLength,
02839
sizeof(ULONG)
02840 );
02841
02842 }
else {
02843
ProbeForWriteUlong((PULONG)AccessStatus);
02844
ProbeForWriteUlong((PULONG)GrantedAccess);
02845 }
02846
02847 LocalPrivilegeSetLength =
ProbeAndReadUlong( PrivilegeSetLength );
02848
ProbeForWriteUlong(
02849 PrivilegeSetLength
02850 );
02851
02852
ProbeForWrite(
02853 PrivilegeSet,
02854 LocalPrivilegeSetLength,
02855
sizeof(ULONG)
02856 );
02857
02858
ProbeForRead(
02859 GenericMapping,
02860
sizeof(GENERIC_MAPPING),
02861
sizeof(ULONG)
02862 );
02863
02864 LocalGenericMapping = *GenericMapping;
02865
02866 } except (
EXCEPTION_EXECUTE_HANDLER) {
02867
Status = GetExceptionCode();
02868 }
02869
if (!
NT_SUCCESS(
Status ) ) {
02870
return(
Status );
02871 }
02872
02873
if (DesiredAccess &
02874 ( GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL )) {
02875
02876
02877
Status = STATUS_GENERIC_NOT_MAPPED;
02878
goto Cleanup;
02879 }
02880
02881
02882
02883
02884
02885
Status =
ObReferenceObjectByHandle(
02886
ClientToken,
02887 (ACCESS_MASK)TOKEN_QUERY,
02888
SepTokenObjectType,
02889 PreviousMode,
02890 (PVOID *)&
Token,
02891 0
02892 );
02893
02894
if (!
NT_SUCCESS(
Status)) {
02895
Token =
NULL;
02896
goto Cleanup;
02897 }
02898
02899
02900
02901
02902
02903
02904
if (
Token->TokenType != TokenImpersonation) {
02905
Status = STATUS_NO_IMPERSONATION_TOKEN;
02906
goto Cleanup;
02907 }
02908
02909
if (
Token->ImpersonationLevel < SecurityIdentification ) {
02910
Status = STATUS_BAD_IMPERSONATION_LEVEL;
02911
goto Cleanup;
02912 }
02913
02914
02915
02916
02917
02918
Status =
SeCaptureObjectTypeList( ObjectTypeList,
02919 ObjectTypeListLength,
02920 PreviousMode,
02921 &LocalObjectTypeList );
02922
02923
if (!
NT_SUCCESS(
Status)) {
02924
goto Cleanup;
02925 }
02926
02927
02928
02929
02930
02931
02932
02933
02934
Status =
SePrivilegePolicyCheck(
02935 &DesiredAccess,
02936 &PreviouslyGrantedAccess,
02937
NULL,
02938 (PACCESS_TOKEN)
Token,
02939 &Privileges,
02940 PreviousMode
02941 );
02942
02943
if (!
NT_SUCCESS(
Status )) {
02944
02945
try {
02946
02947
if ( ReturnResultList ) {
02948
for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) {
02949 AccessStatus[ResultListIndex] =
Status;
02950 GrantedAccess[ResultListIndex] = 0;
02951 }
02952
02953 }
else {
02954 *AccessStatus =
Status;
02955 *GrantedAccess = 0;
02956 }
02957
02958
Status = STATUS_SUCCESS;
02959
02960 } except(
EXCEPTION_EXECUTE_HANDLER) {
02961
02962
Status = GetExceptionCode();
02963 }
02964
02965
goto Cleanup;
02966 }
02967
02968
02969
02970
02971
02972
02973
if (Privileges !=
NULL) {
02974
02975
if ( ((ULONG)
SepPrivilegeSetSize( Privileges )) > LocalPrivilegeSetLength ) {
02976
02977
try {
02978
02979 *PrivilegeSetLength =
SepPrivilegeSetSize( Privileges );
02980
Status = STATUS_BUFFER_TOO_SMALL;
02981
02982 } except (
EXCEPTION_EXECUTE_HANDLER ) {
02983
02984
Status = GetExceptionCode();
02985 }
02986
02987
SeFreePrivileges( Privileges );
02988
02989
goto Cleanup;
02990
02991 }
else {
02992
02993
try {
02994
02995 RtlCopyMemory(
02996 PrivilegeSet,
02997 Privileges,
02998
SepPrivilegeSetSize( Privileges )
02999 );
03000
03001 } except (
EXCEPTION_EXECUTE_HANDLER ) {
03002
03003
SeFreePrivileges( Privileges );
03004
Status = GetExceptionCode();
03005
goto Cleanup;
03006 }
03007
03008 }
03009
SeFreePrivileges( Privileges );
03010
03011 }
else {
03012
03013
03014
03015
03016
03017
if ( LocalPrivilegeSetLength <
sizeof(PRIVILEGE_SET) ) {
03018
03019
try {
03020
03021 *PrivilegeSetLength =
sizeof(PRIVILEGE_SET);
03022
Status = STATUS_BUFFER_TOO_SMALL;
03023
03024 } except (
EXCEPTION_EXECUTE_HANDLER ) {
03025
03026
Status = GetExceptionCode();
03027 }
03028
03029
goto Cleanup;
03030 }
03031
03032
try {
03033
03034 PrivilegeSet->PrivilegeCount = 0;
03035 PrivilegeSet->Control = 0;
03036
03037 } except (
EXCEPTION_EXECUTE_HANDLER ) {
03038
03039
Status = GetExceptionCode();
03040
goto Cleanup;
03041
03042 }
03043
03044 }
03045
03046
03047
03048
03049
03050
if ( PrincipalSelfSid !=
NULL ) {
03051
Status =
SeCaptureSid(
03052 PrincipalSelfSid,
03053 PreviousMode,
03054
NULL, 0,
03055
PagedPool,
03056
TRUE,
03057 &CapturedPrincipalSelfSid );
03058
03059
if (!
NT_SUCCESS(
Status)) {
03060 CapturedPrincipalSelfSid =
NULL;
03061
goto Cleanup;
03062 }
03063 }
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
Status =
SeCaptureSecurityDescriptor (
03074 SecurityDescriptor,
03075 PreviousMode,
03076
PagedPool,
03077
FALSE,
03078 &CapturedSecurityDescriptor
03079 );
03080
03081
if (!
NT_SUCCESS(
Status)) {
03082
goto Cleanup;
03083 }
03084
03085
03086
03087
03088
03089
03090
03091
03092
if ( CapturedSecurityDescriptor ==
NULL ) {
03093
Status = STATUS_INVALID_SECURITY_DESCR;
03094
goto Cleanup;
03095 }
03096
03097
03098
03099
03100
03101
if ( RtlpOwnerAddrSecurityDescriptor(
03102 (PISECURITY_DESCRIPTOR)CapturedSecurityDescriptor
03103 ) ==
NULL ||
03104 RtlpGroupAddrSecurityDescriptor(
03105 (PISECURITY_DESCRIPTOR)CapturedSecurityDescriptor
03106 ) ==
NULL ) {
03107
03108
SeReleaseSecurityDescriptor (
03109 CapturedSecurityDescriptor,
03110 PreviousMode,
03111
FALSE
03112 );
03113
03114
Status = STATUS_INVALID_SECURITY_DESCR;
03115
goto Cleanup;
03116 }
03117
03118
03119
SeCaptureSubjectContext( &SubjectContext );
03120
03121
SepAcquireTokenReadLock(
Token );
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
if ( DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED) ) {
03133
03134
if (
SepTokenIsOwner(
Token, CapturedSecurityDescriptor,
TRUE )) {
03135
03136
if ( DesiredAccess & MAXIMUM_ALLOWED ) {
03137
03138 PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL);
03139
03140 }
else {
03141
03142 PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL));
03143 }
03144
03145 DesiredAccess &= ~(WRITE_DAC | READ_CONTROL);
03146 }
03147
03148 }
03149
03150
if (DesiredAccess == 0) {
03151
03152
try {
03153
03154
03155
if ( ReturnResultList ) {
03156
for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) {
03157 AccessStatus[ResultListIndex] = STATUS_SUCCESS;
03158 GrantedAccess[ResultListIndex] = PreviouslyGrantedAccess;
03159 }
03160
03161 }
else {
03162 *AccessStatus = STATUS_SUCCESS;
03163 *GrantedAccess = PreviouslyGrantedAccess;
03164 }
03165
Status = STATUS_SUCCESS;
03166
03167 } except (
EXCEPTION_EXECUTE_HANDLER) {
03168
03169
Status = GetExceptionCode();
03170
03171 }
03172
03173
SepReleaseTokenReadLock(
Token );
03174
03175
SeReleaseSubjectContext( &SubjectContext );
03176
03177
SeReleaseSecurityDescriptor (
03178 CapturedSecurityDescriptor,
03179 PreviousMode,
03180
FALSE
03181 );
03182
03183
goto Cleanup;
03184
03185 }
03186
03187
03188
03189
03190
03191
03192
if ( ReturnResultList ) {
03193 LocalGrantedAccessPointer =
03194
ExAllocatePoolWithTag(
PagedPool, (
sizeof(ACCESS_MASK)+
sizeof(
NTSTATUS)) * ObjectTypeListLength, 'aGeS' );
03195
03196
if (LocalGrantedAccessPointer ==
NULL) {
03197
03198
SepReleaseTokenReadLock(
Token );
03199
03200
SeReleaseSubjectContext( &SubjectContext );
03201
03202
SeReleaseSecurityDescriptor (
03203 CapturedSecurityDescriptor,
03204 PreviousMode,
03205
FALSE
03206 );
03207
03208
Status = STATUS_INSUFFICIENT_RESOURCES;
03209
goto Cleanup;
03210 }
03211 LocalAccessStatusPointer = (PNTSTATUS)(LocalGrantedAccessPointer + ObjectTypeListLength);
03212 }
else {
03213 LocalGrantedAccessPointer = &LocalGrantedAccess;
03214 LocalAccessStatusPointer = &LocalAccessStatus;
03215 }
03216
03217
SepAccessCheck (
03218 CapturedSecurityDescriptor,
03219 CapturedPrincipalSelfSid,
03220 SubjectContext.
PrimaryToken,
03221
Token,
03222 DesiredAccess,
03223 LocalObjectTypeList,
03224 ObjectTypeListLength,
03225 &LocalGenericMapping,
03226 PreviouslyGrantedAccess,
03227 PreviousMode,
03228 LocalGrantedAccessPointer,
03229
NULL,
03230 LocalAccessStatusPointer,
03231 ReturnResultList,
03232
NULL,
03233
NULL );
03234
03235
SepReleaseTokenReadLock(
Token );
03236
03237
SeReleaseSubjectContext( &SubjectContext );
03238
03239
SeReleaseSecurityDescriptor (
03240 CapturedSecurityDescriptor,
03241 PreviousMode,
03242
FALSE
03243 );
03244
03245
try {
03246
03247
if ( ReturnResultList ) {
03248
for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) {
03249 AccessStatus[ResultListIndex] = LocalAccessStatusPointer[ResultListIndex];
03250 GrantedAccess[ResultListIndex] = LocalGrantedAccessPointer[ResultListIndex];
03251 }
03252
03253 }
else {
03254 *AccessStatus = *LocalAccessStatusPointer;
03255 *GrantedAccess = *LocalGrantedAccessPointer;
03256 }
03257
03258
Status = STATUS_SUCCESS;
03259
03260 } except (
EXCEPTION_EXECUTE_HANDLER) {
03261
Status = GetExceptionCode();
03262 }
03263
03264
if ( ReturnResultList ) {
03265
if ( LocalGrantedAccessPointer !=
NULL ) {
03266
ExFreePool( LocalGrantedAccessPointer );
03267 }
03268 }
03269
03270
03271
03272
03273
03274 Cleanup:
03275
03276
if (
Token !=
NULL ) {
03277
ObDereferenceObject(
Token );
03278 }
03279
03280
if ( LocalObjectTypeList !=
NULL ) {
03281
SeFreeCapturedObjectTypeList( LocalObjectTypeList );
03282 }
03283
03284
if (CapturedPrincipalSelfSid !=
NULL) {
03285
SeReleaseSid( CapturedPrincipalSelfSid, PreviousMode,
TRUE);
03286 }
03287
03288
return Status;
03289 }
03290
03291
03292
03293
VOID
03294 SeFreePrivileges(
03295 IN PPRIVILEGE_SET Privileges
03296 )
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314 {
03315
PAGED_CODE();
03316
03317
ExFreePool( Privileges );
03318 }
03319
03320
03321
03322 BOOLEAN
03323 SeAccessCheck (
03324 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
03325 IN
PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
03326 IN BOOLEAN SubjectContextLocked,
03327 IN ACCESS_MASK DesiredAccess,
03328 IN ACCESS_MASK PreviouslyGrantedAccess,
03329 OUT PPRIVILEGE_SET *Privileges OPTIONAL,
03330 IN PGENERIC_MAPPING GenericMapping,
03331 IN KPROCESSOR_MODE AccessMode,
03332 OUT PACCESS_MASK GrantedAccess,
03333 OUT PNTSTATUS AccessStatus
03334 )
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396 {
03397 BOOLEAN Success;
03398
03399
PAGED_CODE();
03400
03401
if (AccessMode ==
KernelMode) {
03402
03403
if (DesiredAccess & MAXIMUM_ALLOWED) {
03404
03405
03406
03407
03408
03409
03410
03411 *GrantedAccess = GenericMapping->GenericAll;
03412 *GrantedAccess |= (DesiredAccess & ~MAXIMUM_ALLOWED);
03413 *GrantedAccess |= PreviouslyGrantedAccess;
03414
03415 }
else {
03416
03417 *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
03418 }
03419 *AccessStatus = STATUS_SUCCESS;
03420
return(
TRUE);
03421 }
03422
03423
03424
03425
03426
03427
03428
if ( SecurityDescriptor ==
NULL) {
03429
03430 *AccessStatus = STATUS_ACCESS_DENIED;
03431
return(
FALSE );
03432
03433 }
03434
03435
03436
03437
03438
03439
03440
if ( (SubjectSecurityContext->ClientToken !=
NULL) &&
03441 (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation)
03442 ) {
03443 *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL;
03444
return(
FALSE );
03445 }
03446
03447
if ( DesiredAccess == 0 ) {
03448
03449
if ( PreviouslyGrantedAccess == 0 ) {
03450 *AccessStatus = STATUS_ACCESS_DENIED;
03451
return(
FALSE );
03452 }
03453
03454 *GrantedAccess = PreviouslyGrantedAccess;
03455 *AccessStatus = STATUS_SUCCESS;
03456 *Privileges =
NULL;
03457
return(
TRUE );
03458
03459 }
03460
03461
SeAssertMappedCanonicalAccess( DesiredAccess );
03462
03463
03464
03465
03466
03467
03468
03469
03470
if ( !SubjectContextLocked ) {
03471
SeLockSubjectContext( SubjectSecurityContext );
03472 }
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
if ( DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED) ) {
03483
03484
if (
SepTokenIsOwner(
03485
EffectiveToken( SubjectSecurityContext ),
03486 SecurityDescriptor,
03487
TRUE
03488 ) ) {
03489
03490
if ( DesiredAccess & MAXIMUM_ALLOWED ) {
03491
03492 PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL);
03493
03494 }
else {
03495
03496 PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL));
03497 }
03498
03499 DesiredAccess &= ~(WRITE_DAC | READ_CONTROL);
03500 }
03501 }
03502
03503
if (DesiredAccess == 0) {
03504
03505
if ( !SubjectContextLocked ) {
03506
SeUnlockSubjectContext( SubjectSecurityContext );
03507 }
03508
03509 *GrantedAccess = PreviouslyGrantedAccess;
03510 *AccessStatus = STATUS_SUCCESS;
03511
return(
TRUE );
03512
03513 }
else {
03514
03515
SepAccessCheck(
03516 SecurityDescriptor,
03517
NULL,
03518 SubjectSecurityContext->PrimaryToken,
03519 SubjectSecurityContext->ClientToken,
03520 DesiredAccess,
03521
NULL,
03522 0,
03523 GenericMapping,
03524 PreviouslyGrantedAccess,
03525 AccessMode,
03526 GrantedAccess,
03527 Privileges,
03528 AccessStatus,
03529
FALSE,
03530 &Success,
03531
NULL
03532 );
03533
#if DBG
03534
if (!Success && SepShowAccessFail) {
03535
DbgPrint(
"SE: Access check failed, DesiredAccess = 0x%x\n",
03536 DesiredAccess);
03537 SepDumpSD =
TRUE;
03538
SepDumpSecurityDescriptor(
03539 SecurityDescriptor,
03540
"Input to SeAccessCheck\n"
03541 );
03542 SepDumpSD =
FALSE;
03543 SepDumpToken =
TRUE;
03544
SepDumpTokenInfo(
EffectiveToken( SubjectSecurityContext ) );
03545 SepDumpToken =
FALSE;
03546 }
03547
#endif
03548
03549
03550
03551
03552
03553
03554
if ( !SubjectContextLocked ) {
03555
SeUnlockSubjectContext( SubjectSecurityContext );
03556 }
03557
03558
return( Success );
03559 }
03560 }
03561
03562
03563 BOOLEAN
03564 SeProxyAccessCheck (
03565 IN PUNICODE_STRING Volume,
03566 IN PUNICODE_STRING RelativePath,
03567 IN BOOLEAN ContainerObject,
03568 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
03569 IN
PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
03570 IN BOOLEAN SubjectContextLocked,
03571 IN ACCESS_MASK DesiredAccess,
03572 IN ACCESS_MASK PreviouslyGrantedAccess,
03573 OUT PPRIVILEGE_SET *Privileges OPTIONAL,
03574 IN PGENERIC_MAPPING GenericMapping,
03575 IN KPROCESSOR_MODE AccessMode,
03576 OUT PACCESS_MASK GrantedAccess,
03577 OUT PNTSTATUS AccessStatus
03578 )
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635 {
03636
return SeAccessCheck (
03637 SecurityDescriptor,
03638 SubjectSecurityContext,
03639 SubjectContextLocked,
03640 DesiredAccess,
03641 PreviouslyGrantedAccess,
03642 Privileges,
03643 GenericMapping,
03644 AccessMode,
03645 GrantedAccess,
03646 AccessStatus
03647 );
03648 }
03649
03650
03651
NTSTATUS
03652 SePrivilegePolicyCheck(
03653 IN OUT PACCESS_MASK RemainingDesiredAccess,
03654 IN OUT PACCESS_MASK PreviouslyGrantedAccess,
03655 IN
PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL,
03656 IN PACCESS_TOKEN ExplicitToken OPTIONAL,
03657 OUT PPRIVILEGE_SET *PrivilegeSet,
03658 IN KPROCESSOR_MODE PreviousMode
03659 )
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704 {
03705 BOOLEAN Success;
03706
PTOKEN Token;
03707 BOOLEAN WriteOwner =
FALSE;
03708 BOOLEAN SystemSecurity =
FALSE;
03709 ULONG PrivilegeNumber = 0;
03710 ULONG PrivilegeCount = 0;
03711 ULONG SizeRequired;
03712
03713
PAGED_CODE();
03714
03715
if (ARGUMENT_PRESENT( SubjectSecurityContext )) {
03716
03717
Token = (
PTOKEN)
EffectiveToken( SubjectSecurityContext );
03718
03719 }
else {
03720
03721
Token = (
PTOKEN)ExplicitToken;
03722 }
03723
03724
03725
if (*RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY) {
03726
03727 Success =
SepSinglePrivilegeCheck (
03728
SeSecurityPrivilege,
03729
Token,
03730 PreviousMode
03731 );
03732
03733
if (!Success) {
03734
03735
return( STATUS_PRIVILEGE_NOT_HELD );
03736 }
03737
03738 PrivilegeCount++;
03739 SystemSecurity =
TRUE;
03740
03741 *RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
03742 *PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
03743 }
03744
03745
if (*RemainingDesiredAccess & WRITE_OWNER) {
03746
03747 Success =
SepSinglePrivilegeCheck (
03748
SeTakeOwnershipPrivilege,
03749
Token,
03750 PreviousMode
03751 );
03752
03753
if (Success) {
03754
03755 PrivilegeCount++;
03756 WriteOwner =
TRUE;
03757
03758 *RemainingDesiredAccess &= ~WRITE_OWNER;
03759 *PreviouslyGrantedAccess |= WRITE_OWNER;
03760
03761 }
03762 }
03763
03764
if (PrivilegeCount > 0) {
03765 SizeRequired =
sizeof(PRIVILEGE_SET) +
03766 (PrivilegeCount -
ANYSIZE_ARRAY) *
03767 (ULONG)
sizeof(LUID_AND_ATTRIBUTES);
03768
03769 *PrivilegeSet =
ExAllocatePoolWithTag(
PagedPool, SizeRequired, 'rPeS' );
03770
03771
if ( *PrivilegeSet ==
NULL ) {
03772
return( STATUS_INSUFFICIENT_RESOURCES );
03773 }
03774
03775 (*PrivilegeSet)->PrivilegeCount = PrivilegeCount;
03776 (*PrivilegeSet)->Control = 0;
03777
03778
if (WriteOwner) {
03779 (*PrivilegeSet)->Privilege[PrivilegeNumber].Luid =
SeTakeOwnershipPrivilege;
03780 (*PrivilegeSet)->Privilege[PrivilegeNumber].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
03781 PrivilegeNumber++;
03782 }
03783
03784
if (SystemSecurity) {
03785 (*PrivilegeSet)->Privilege[PrivilegeNumber].Luid =
SeSecurityPrivilege;
03786 (*PrivilegeSet)->Privilege[PrivilegeNumber].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
03787 }
03788 }
03789
03790
return( STATUS_SUCCESS );
03791 }
03792
03793
03794
03795 BOOLEAN
03796 SepTokenIsOwner(
03797 IN PACCESS_TOKEN EffectiveToken,
03798 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
03799 IN BOOLEAN TokenLocked
03800 )
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830 {
03831 PSID
Owner;
03832 BOOLEAN rc;
03833
03834 PISECURITY_DESCRIPTOR ISecurityDescriptor;
03835
PTOKEN Token;
03836
03837
PAGED_CODE();
03838
03839 ISecurityDescriptor = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
03840
Token = (
PTOKEN)
EffectiveToken;
03841
03842
if (!TokenLocked) {
03843
SepAcquireTokenReadLock(
Token );
03844 }
03845
03846
Owner = RtlpOwnerAddrSecurityDescriptor( ISecurityDescriptor );
03847
ASSERT(
Owner !=
NULL );
03848
03849 rc =
SepSidInToken(
Token,
NULL,
Owner,
FALSE );
03850
03851
03852
03853
03854
03855
if (rc && (
Token->TokenFlags &
TOKEN_IS_RESTRICTED) != 0) {
03856 rc =
SepSidInTokenEx(
Token,
NULL,
Owner,
FALSE,
TRUE );
03857
03858 }
03859
03860
if (!TokenLocked) {
03861
SepReleaseTokenReadLock(
Token );
03862 }
03863
03864
return( rc );
03865 }
03866
03867
03868
03869
03870 BOOLEAN
03871 SeFastTraverseCheck(
03872 PSECURITY_DESCRIPTOR SecurityDescriptor,
03873 ACCESS_MASK TraverseAccess,
03874 KPROCESSOR_MODE AccessMode
03875 )
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906 {
03907 PACL
Dacl;
03908 ULONG i;
03909 PVOID Ace;
03910 ULONG AceCount;
03911
03912
PAGED_CODE();
03913
03914
if ( AccessMode ==
KernelMode ) {
03915
return(
TRUE );
03916 }
03917
03918
if (SecurityDescriptor ==
NULL) {
03919
return(
FALSE );
03920 }
03921
03922
03923
03924
03925
03926
03927
Dacl = RtlpDaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)SecurityDescriptor );
03928
03929
03930
03931
03932
03933
03934
03935
03936
if ( !RtlpAreControlBitsSet(
03937 (PISECURITY_DESCRIPTOR)SecurityDescriptor, SE_DACL_PRESENT
03938 )
03939 || (
Dacl ==
NULL)) {
03940
03941
return(
TRUE);
03942 }
03943
03944
03945
03946
03947
03948
03949
if ((AceCount =
Dacl->AceCount) == 0) {
03950
03951
return(
FALSE );
03952 }
03953
03954
03955
03956
03957
03958
03959
for ( i = 0, Ace =
FirstAce(
Dacl ) ;
03960 i < AceCount ;
03961 i++, Ace =
NextAce( Ace )
03962 ) {
03963
03964
if ( !(((PACE_HEADER)Ace)->AceFlags & INHERIT_ONLY_ACE)) {
03965
03966
if ( (((PACE_HEADER)Ace)->AceType == ACCESS_ALLOWED_ACE_TYPE) ) {
03967
03968
if ( (TraverseAccess & ((PACCESS_ALLOWED_ACE)Ace)->Mask) ) {
03969
03970
if (
RtlEqualSid(
SeWorldSid, &((PACCESS_ALLOWED_ACE)Ace)->SidStart ) ) {
03971
03972
return(
TRUE );
03973 }
03974 }
03975
03976 }
else {
03977
03978
if ( (((PACE_HEADER)Ace)->AceType == ACCESS_DENIED_ACE_TYPE) ) {
03979
03980
if ( (TraverseAccess & ((PACCESS_DENIED_ACE)Ace)->Mask) ) {
03981
03982
if (
RtlEqualSid(
SeWorldSid, &((PACCESS_DENIED_ACE)Ace)->SidStart ) ) {
03983
03984
return(
FALSE );
03985 }
03986 }
03987 }
03988 }
03989 }
03990 }
03991
03992
return(
FALSE );
03993 }