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
#include "ntrtlp.h"
00029
#include <stdio.h>
00030
#include "seopaque.h"
00031
#include "sertlp.h"
00032
#ifdef NTOS_KERNEL_RUNTIME
00033
#include <..\se\sep.h>
00034
#else // NTOS_KERNEL_RUNTIME
00035
#include <..\dll\ldrp.h>
00036
#endif // NTOS_KERNEL_RUNTIME
00037
00038
00039
00040
00041
00042 ULONG
00043
RtlLengthUsedSecurityDescriptor (
00044 IN PSECURITY_DESCRIPTOR SecurityDescriptor
00045 );
00046
00047
#undef RtlEqualLuid
00048
00049 NTSYSAPI
00050 BOOLEAN
00051 NTAPI
00052
RtlEqualLuid (
00053 PLUID Luid1,
00054 PLUID Luid2
00055 );
00056
00057
NTSTATUS
00058
RtlpConvertAclToAutoInherit (
00059 IN PACL ParentAcl OPTIONAL,
00060 IN PACL ChildAcl,
00061 IN GUID *ObjectType OPTIONAL,
00062 IN BOOLEAN IsDirectoryObject,
00063 IN PSID OwnerSid,
00064 IN PSID GroupSid,
00065 IN PGENERIC_MAPPING GenericMapping,
00066 OUT PACL *NewAcl,
00067 OUT PULONG NewGenericControl
00068 );
00069
00070 BOOLEAN
00071
RtlpCopyEffectiveAce (
00072 IN PACE_HEADER OldAce,
00073 IN BOOLEAN AutoInherit,
00074 IN BOOLEAN WillGenerateInheritAce,
00075 IN PSID ClientOwnerSid,
00076 IN PSID ClientGroupSid,
00077 IN PSID ServerOwnerSid OPTIONAL,
00078 IN PSID ServerGroupSid OPTIONAL,
00079 IN PGENERIC_MAPPING GenericMapping,
00080 IN GUID *NewObjectType OPTIONAL,
00081 IN OUT PVOID *AcePosition,
00082 OUT PULONG NewAceLength,
00083 OUT PACL NewAcl,
00084 OUT PBOOLEAN ObjectAceInherited OPTIONAL,
00085 OUT PBOOLEAN EffectiveAceMapped,
00086 OUT PBOOLEAN AclOverflowed
00087 );
00088
00089 typedef enum {
00090
CopyInheritedAces,
00091
CopyNonInheritedAces,
00092
CopyAllAces }
ACE_TYPE_TO_COPY;
00093
00094
NTSTATUS
00095
RtlpCopyAces(
00096 IN PACL Acl,
00097 IN PGENERIC_MAPPING GenericMapping,
00098 IN ACE_TYPE_TO_COPY AceTypeToCopy,
00099 IN UCHAR AceFlagsToReset,
00100 IN BOOLEAN MapSids,
00101 IN PSID ClientOwnerSid,
00102 IN PSID ClientGroupSid,
00103 IN PSID ServerOwnerSid OPTIONAL,
00104 IN PSID ServerGroupSid OPTIONAL,
00105 OUT PULONG NewAclSizeParam,
00106 OUT PACL NewAcl
00107 );
00108
00109
NTSTATUS
00110
RtlpGenerateInheritedAce (
00111 IN PACE_HEADER OldAce,
00112 IN BOOLEAN IsDirectoryObject,
00113 IN BOOLEAN AutoInherit,
00114 IN PSID ClientOwnerSid,
00115 IN PSID ClientGroupSid,
00116 IN PSID ServerOwnerSid OPTIONAL,
00117 IN PSID ServerGroupSid OPTIONAL,
00118 IN PGENERIC_MAPPING GenericMapping,
00119 IN GUID *NewObjectType OPTIONAL,
00120 OUT PULONG NewAceLength,
00121 OUT PACL NewAcl,
00122 OUT PULONG NewAceExtraLength,
00123 OUT PBOOLEAN ObjectAceInherited
00124 );
00125
00126
NTSTATUS
00127
RtlpGenerateInheritAcl(
00128 IN PACL Acl,
00129 IN BOOLEAN IsDirectoryObject,
00130 IN BOOLEAN AutoInherit,
00131 IN PSID ClientOwnerSid,
00132 IN PSID ClientGroupSid,
00133 IN PSID ServerOwnerSid OPTIONAL,
00134 IN PSID ServerGroupSid OPTIONAL,
00135 IN PGENERIC_MAPPING GenericMapping,
00136 IN GUID *NewObjectType OPTIONAL,
00137 OUT PULONG NewAclSizeParam,
00138 OUT PACL NewAcl,
00139 OUT PBOOLEAN ObjectAceInherited
00140 );
00141
00142
NTSTATUS
00143
RtlpInheritAcl2 (
00144 IN PACL DirectoryAcl,
00145 IN PACL ChildAcl,
00146 IN ULONG ChildGenericControl,
00147 IN BOOLEAN IsDirectoryObject,
00148 IN BOOLEAN AutoInherit,
00149 IN BOOLEAN DefaultDescriptorForObject,
00150 IN PSID OwnerSid,
00151 IN PSID GroupSid,
00152 IN PSID ServerOwnerSid OPTIONAL,
00153 IN PSID ServerGroupSid OPTIONAL,
00154 IN PGENERIC_MAPPING GenericMapping,
00155 IN BOOLEAN IsSacl,
00156 IN GUID *NewObjectType OPTIONAL,
00157 IN PULONG AclBufferSize,
00158 IN OUT PUCHAR AclBuffer,
00159 OUT PBOOLEAN NewAclExplicitlyAssigned,
00160 OUT PULONG NewGenericControl
00161 );
00162
00163
NTSTATUS
00164
RtlpComputeMergedAcl (
00165 IN PACL CurrentAcl,
00166 IN ULONG CurrentGenericControl,
00167 IN PACL ModificationAcl,
00168 IN ULONG ModificationGenericControl,
00169 IN PSID ClientOwnerSid,
00170 IN PSID ClientGroupSid,
00171 IN PGENERIC_MAPPING GenericMapping,
00172 IN BOOLEAN IsSacl,
00173 OUT PACL *NewAcl,
00174 OUT PULONG NewGenericControl
00175 );
00176
00177
NTSTATUS
00178
RtlpComputeMergedAcl2 (
00179 IN PACL CurrentAcl,
00180 IN ULONG CurrentGenericControl,
00181 IN PACL ModificationAcl,
00182 IN ULONG ModificationGenericControl,
00183 IN PSID ClientOwnerSid,
00184 IN PSID ClientGroupSid,
00185 IN PGENERIC_MAPPING GenericMapping,
00186 IN BOOLEAN IsSacl,
00187 IN PULONG AclBufferSize,
00188 IN OUT PUCHAR AclBuffer,
00189 OUT PULONG NewGenericControl
00190 );
00191
00192 BOOLEAN
00193
RtlpCompareAces(
00194 IN
PKNOWN_ACE InheritedAce,
00195 IN
PKNOWN_ACE ChildAce,
00196 IN PSID OwnerSid,
00197 IN PSID GroupSid
00198 );
00199
00200 BOOLEAN
00201
RtlpCompareKnownObjectAces(
00202 IN PKNOWN_OBJECT_ACE InheritedAce,
00203 IN PKNOWN_OBJECT_ACE ChildAce,
00204 IN PSID OwnerSid OPTIONAL,
00205 IN PSID GroupSid OPTIONAL
00206 );
00207
00208 BOOLEAN
00209
RtlpCompareKnownAces(
00210 IN
PKNOWN_ACE InheritedAce,
00211 IN
PKNOWN_ACE ChildAce,
00212 IN PSID OwnerSid OPTIONAL,
00213 IN PSID GroupSid OPTIONAL
00214 );
00215
00216 BOOLEAN
00217
RtlpIsDuplicateAce(
00218 IN PACL Acl,
00219 IN
PKNOWN_ACE NewAce,
00220 IN GUID *ObjectType OPTIONAL
00221 );
00222
00223
NTSTATUS
00224
RtlpCreateServerAcl(
00225 IN PACL Acl,
00226 IN BOOLEAN AclUntrusted,
00227 IN PSID ServerSid,
00228 OUT PACL *ServerAcl,
00229 OUT BOOLEAN *ServerAclAllocated
00230 );
00231
00232
NTSTATUS
00233
RtlpGetDefaultsSubjectContext(
00234 HANDLE ClientToken,
00235 OUT PTOKEN_OWNER *OwnerInfo,
00236 OUT PTOKEN_PRIMARY_GROUP *GroupInfo,
00237 OUT PTOKEN_DEFAULT_DACL *DefaultDaclInfo,
00238 OUT PTOKEN_OWNER *ServerOwner,
00239 OUT PTOKEN_PRIMARY_GROUP *ServerGroup
00240 );
00241
00242 BOOLEAN
RtlpValidateSDOffsetAndSize (
00243 IN ULONG Offset,
00244 IN ULONG Length,
00245 IN ULONG MinLength,
00246 OUT PULONG MaxLength
00247 );
00248
00249 BOOLEAN
00250
RtlValidRelativeSecurityDescriptor (
00251 IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
00252 IN ULONG SecurityDescriptorLength,
00253 IN SECURITY_INFORMATION RequiredInformation
00254 );
00255
00256
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
00257
#pragma alloc_text(PAGE,RtlRunEncodeUnicodeString)
00258
#pragma alloc_text(PAGE,RtlRunDecodeUnicodeString)
00259
#pragma alloc_text(PAGE,RtlEraseUnicodeString)
00260
#pragma alloc_text(PAGE,RtlAdjustPrivilege)
00261
#pragma alloc_text(PAGE,RtlValidSid)
00262
#pragma alloc_text(PAGE,RtlEqualSid)
00263
#pragma alloc_text(PAGE,RtlEqualPrefixSid)
00264
#pragma alloc_text(PAGE,RtlLengthRequiredSid)
00265
#pragma alloc_text(PAGE,RtlInitializeSid)
00266
#pragma alloc_text(PAGE,RtlFreeSid)
00267
#pragma alloc_text(PAGE,RtlIdentifierAuthoritySid)
00268
#pragma alloc_text(PAGE,RtlSubAuthoritySid)
00269
#pragma alloc_text(PAGE,RtlSubAuthorityCountSid)
00270
#pragma alloc_text(PAGE,RtlLengthSid)
00271
#pragma alloc_text(PAGE,RtlCopySid)
00272
#pragma alloc_text(PAGE,RtlCopySidAndAttributesArray)
00273
#pragma alloc_text(PAGE,RtlConvertSidToUnicodeString)
00274
#pragma alloc_text(PAGE,RtlEqualLuid)
00275
#pragma alloc_text(PAGE,RtlCopyLuid)
00276
#pragma alloc_text(PAGE,RtlCopyLuidAndAttributesArray)
00277
#pragma alloc_text(PAGE,RtlCreateSecurityDescriptor)
00278
#pragma alloc_text(PAGE,RtlCreateSecurityDescriptorRelative)
00279
#pragma alloc_text(PAGE,RtlValidSecurityDescriptor)
00280
#pragma alloc_text(PAGE,RtlLengthSecurityDescriptor)
00281
#pragma alloc_text(PAGE,RtlLengthUsedSecurityDescriptor)
00282
#pragma alloc_text(PAGE,RtlGetControlSecurityDescriptor)
00283
#pragma alloc_text(PAGE,RtlSetControlSecurityDescriptor)
00284
#pragma alloc_text(PAGE,RtlSetDaclSecurityDescriptor)
00285
#pragma alloc_text(PAGE,RtlGetDaclSecurityDescriptor)
00286
#pragma alloc_text(PAGE,RtlSetSaclSecurityDescriptor)
00287
#pragma alloc_text(PAGE,RtlGetSaclSecurityDescriptor)
00288
#pragma alloc_text(PAGE,RtlSetOwnerSecurityDescriptor)
00289
#pragma alloc_text(PAGE,RtlGetOwnerSecurityDescriptor)
00290
#pragma alloc_text(PAGE,RtlSetGroupSecurityDescriptor)
00291
#pragma alloc_text(PAGE,RtlGetGroupSecurityDescriptor)
00292
#pragma alloc_text(PAGE,RtlGetSecurityDescriptorRMControl)
00293
#pragma alloc_text(PAGE,RtlSetSecurityDescriptorRMControl)
00294
#pragma alloc_text(PAGE,RtlAreAllAccessesGranted)
00295
#pragma alloc_text(PAGE,RtlAreAnyAccessesGranted)
00296
#pragma alloc_text(PAGE,RtlMapGenericMask)
00297
#pragma alloc_text(PAGE,RtlpApplyAclToObject)
00298
#pragma alloc_text(PAGE,RtlpContainsCreatorGroupSid)
00299
#pragma alloc_text(PAGE,RtlpContainsCreatorOwnerSid)
00300
#pragma alloc_text(PAGE,RtlpCopyEffectiveAce)
00301
#pragma alloc_text(PAGE,RtlpCopyAces)
00302
#pragma alloc_text(PAGE,RtlpGenerateInheritAcl)
00303
#pragma alloc_text(PAGE,RtlpGenerateInheritedAce)
00304
#pragma alloc_text(PAGE,RtlpInheritAcl)
00305
#pragma alloc_text(PAGE,RtlpInheritAcl2)
00306
#pragma alloc_text(PAGE,RtlpComputeMergedAcl)
00307
#pragma alloc_text(PAGE,RtlpComputeMergedAcl2)
00308
#pragma alloc_text(PAGE,RtlpValidOwnerSubjectContext)
00309
#pragma alloc_text(PAGE,RtlpConvertToAutoInheritSecurityObject)
00310
#pragma alloc_text(PAGE,RtlpCompareAces)
00311
#pragma alloc_text(PAGE,RtlpCompareKnownAces)
00312
#pragma alloc_text(PAGE,RtlpCompareKnownObjectAces)
00313
#pragma alloc_text(PAGE,RtlpIsDuplicateAce)
00314
#pragma alloc_text(PAGE,RtlpConvertAclToAutoInherit)
00315
#pragma alloc_text(PAGE,RtlSetSecurityObjectEx)
00316
#pragma alloc_text(PAGE,RtlpCreateServerAcl)
00317
#pragma alloc_text(PAGE,RtlValidRelativeSecurityDescriptor)
00318
#pragma alloc_text(PAGE,RtlpValidateSDOffsetAndSize)
00319
#endif
00320
00321
00322
00324
00325
00326
00328
00329
00330 #define CREATOR_SID_SIZE 12
00331
00332 #define max(a,b) (((a) > (b)) ? (a) : (b))
00333
00334
00335
00336
00337
00338
00339
00340 UCHAR
RtlBaseAceType[] = {
00341 ACCESS_ALLOWED_ACE_TYPE,
00342 ACCESS_DENIED_ACE_TYPE,
00343 SYSTEM_AUDIT_ACE_TYPE,
00344 SYSTEM_ALARM_ACE_TYPE,
00345 ACCESS_ALLOWED_ACE_TYPE,
00346 ACCESS_ALLOWED_ACE_TYPE,
00347 ACCESS_DENIED_ACE_TYPE,
00348 SYSTEM_AUDIT_ACE_TYPE,
00349 SYSTEM_ALARM_ACE_TYPE
00350 };
00351
00352
00353
00354
00355
00356 UCHAR
RtlIsSystemAceType[] = {
00357
FALSE,
00358
FALSE,
00359
TRUE,
00360
TRUE,
00361
FALSE,
00362
FALSE,
00363
FALSE,
00364
TRUE,
00365
TRUE
00366 };
00367
00368 BOOLEAN
RtlpVerboseConvert =
FALSE;
00369
00370 #define SE_VALID_CONTROL_BITS ( SE_DACL_UNTRUSTED | \
00371
SE_SERVER_SECURITY | \
00372
SE_DACL_AUTO_INHERIT_REQ | \
00373
SE_SACL_AUTO_INHERIT_REQ | \
00374
SE_DACL_AUTO_INHERITED | \
00375
SE_SACL_AUTO_INHERITED | \
00376
SE_DACL_PROTECTED | \
00377
SE_SACL_PROTECTED )
00378
00379
00381
00382
00383
00385
00386
00387
VOID
00388 RtlRunEncodeUnicodeString(
00389 PUCHAR Seed OPTIONAL,
00390 PUNICODE_STRING String
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 LARGE_INTEGER
Time;
00425 PUCHAR LocalSeed;
00426
NTSTATUS Status;
00427 ULONG i;
00428 PSTRING S;
00429
00430
00431
RTL_PAGED_CODE();
00432
00433
00434
00435
00436
00437 S = (PSTRING)((PVOID)
String);
00438
00439
00440
00441
00442
00443
00444
if ((*Seed) == 0) {
00445
Status = NtQuerySystemTime ( &
Time );
00446
ASSERT(
NT_SUCCESS(
Status));
00447
00448 LocalSeed = (PUCHAR)((PVOID)&
Time);
00449
00450 i = 1;
00451
00452 (*Seed) = LocalSeed[ i ];
00453
00454
00455
00456
00457
00458
00459
00460
00461
while ( ((*Seed) == 0) && ( i <
sizeof(
Time ) ) )
00462 {
00463 (*Seed) |= LocalSeed[ i++ ] ;
00464 }
00465
00466
if ( (*Seed) == 0 )
00467 {
00468 (*Seed) = 1;
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
if (S->Length >= 1) {
00482 S->Buffer[0] ^= ((*Seed) | 0X43);
00483 }
00484
00485
00486
00487
00488
00489
00490
for (i=1; i<S->Length; i++) {
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 S->Buffer[i] ^= (S->Buffer[i-1]^(*Seed));
00510
00511 }
00512
00513
00514
return;
00515
00516 }
00517
00518
00519
VOID
00520 RtlRunDecodeUnicodeString(
00521 UCHAR Seed,
00522 PUNICODE_STRING String
00523 )
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 {
00550
00551 ULONG
00552 i;
00553
00554 PSTRING
00555 S;
00556
00557
RTL_PAGED_CODE();
00558
00559
00560
00561
00562
00563 S = (PSTRING)((PVOID)
String);
00564
00565
00566
00567
00568
00569
00570
for (i=S->Length; i>1; i--) {
00571
00572
00573
00574
00575
00576
00577 S->Buffer[i-1] ^= (S->Buffer[i-2]^
Seed);
00578
00579 }
00580
00581
00582
00583
00584
00585
if (S->Length >= 1) {
00586 S->Buffer[0] ^= (
Seed | 0X43);
00587 }
00588
00589
00590
return;
00591 }
00592
00593
00594
00595
VOID
00596 RtlEraseUnicodeString(
00597 PUNICODE_STRING String
00598 )
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 {
00623
RTL_PAGED_CODE();
00624
00625
if ((
String->Buffer ==
NULL) || (
String->MaximumLength == 0)) {
00626
return;
00627 }
00628
00629 RtlZeroMemory( (PVOID)
String->Buffer, (ULONG)
String->MaximumLength );
00630
00631
String->Length = 0;
00632
00633
return;
00634 }
00635
00636
00637
00638
NTSTATUS
00639 RtlAdjustPrivilege(
00640 ULONG Privilege,
00641 BOOLEAN Enable,
00642 BOOLEAN Client,
00643 PBOOLEAN WasEnabled
00644 )
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 {
00689
NTSTATUS
00690
Status,
00691 TmpStatus;
00692
00693 HANDLE
00694
Token;
00695
00696 LUID
00697 LuidPrivilege;
00698
00699 PTOKEN_PRIVILEGES
00700 NewPrivileges,
00701 OldPrivileges;
00702
00703 ULONG
00704 Length;
00705
00706 UCHAR
00707
Buffer1[
sizeof(TOKEN_PRIVILEGES)+
00708 ((1-
ANYSIZE_ARRAY)*
sizeof(LUID_AND_ATTRIBUTES))],
00709
Buffer2[
sizeof(TOKEN_PRIVILEGES)+
00710 ((1-
ANYSIZE_ARRAY)*
sizeof(LUID_AND_ATTRIBUTES))];
00711
00712
00713
RTL_PAGED_CODE();
00714
00715 NewPrivileges = (PTOKEN_PRIVILEGES)
Buffer1;
00716 OldPrivileges = (PTOKEN_PRIVILEGES)
Buffer2;
00717
00718
00719
00720
00721
00722
if (Client ==
TRUE) {
00723
Status =
NtOpenThreadToken(
00724 NtCurrentThread(),
00725 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
00726
FALSE,
00727 &
Token
00728 );
00729 }
else {
00730
00731
Status =
NtOpenProcessToken(
00732 NtCurrentProcess(),
00733 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
00734 &
Token
00735 );
00736 }
00737
00738
if (!
NT_SUCCESS(
Status)) {
00739
return(
Status);
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 LuidPrivilege = RtlConvertUlongToLuid(Privilege);
00749
00750
00751 NewPrivileges->PrivilegeCount = 1;
00752 NewPrivileges->Privileges[0].Luid = LuidPrivilege;
00753 NewPrivileges->Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0;
00754
00755
00756
00757
00758
00759
00760
00761
Status =
NtAdjustPrivilegesToken(
00762
Token,
00763
FALSE,
00764 NewPrivileges,
00765
sizeof(
Buffer1),
00766 OldPrivileges,
00767 &Length
00768 );
00769
00770
00771 TmpStatus =
NtClose(
Token);
00772
ASSERT(
NT_SUCCESS(TmpStatus));
00773
00774
00775
00776
00777
00778
00779
00780
if (
Status == STATUS_NOT_ALL_ASSIGNED) {
00781
Status = STATUS_PRIVILEGE_NOT_HELD;
00782 }
00783
00784
00785
if (
NT_SUCCESS(
Status)) {
00786
00787
00788
00789
00790
00791
00792
00793
if (OldPrivileges->PrivilegeCount == 0) {
00794
00795 (*WasEnabled) = Enable;
00796
00797 }
else {
00798
00799 (*WasEnabled) =
00800 (OldPrivileges->Privileges[0].Attributes & SE_PRIVILEGE_ENABLED)
00801 ?
TRUE :
FALSE;
00802 }
00803 }
00804
00805
return(
Status);
00806 }
00807
00808
00809 BOOLEAN
00810 RtlValidSid (
00811 IN PSID Sid
00812 )
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 {
00831 PISID Isid = (PISID) Sid;
00832
RTL_PAGED_CODE();
00833
00834
00835
00836
00837
00838
try {
00839
00840
if ( Isid !=
NULL && (Isid->Revision & 0x0f) == SID_REVISION) {
00841
if (Isid->SubAuthorityCount <= SID_MAX_SUB_AUTHORITIES) {
00842
00843
00844
00845
00846
#ifndef NTOS_KERNEL_RUNTIME
00847
#define ProbeAndReadUlongUM(Address) \
00848
(*(volatile ULONG *)(Address))
00849
00850
if (Isid->SubAuthorityCount > 0) {
00851
ProbeAndReadUlongUM(
00852 &Isid->SubAuthority[Isid->SubAuthorityCount-1]
00853 );
00854 }
00855
#endif // !NTOS_KERNEL_RUNTIME
00856
return TRUE;
00857 }
00858 }
00859
00860 } except(
EXCEPTION_EXECUTE_HANDLER) {
00861
return FALSE;
00862 }
00863
00864
return FALSE;
00865
00866 }
00867
00868
00869
00870 BOOLEAN
00871 RtlEqualSid (
00872 IN PSID Sid1,
00873 IN PSID Sid2
00874 )
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 {
00895 ULONG SidLength;
00896
00897
RTL_PAGED_CODE();
00898
00899
00900
00901
00902
00903
if ( ((SID *)Sid1)->Revision == ((SID *)Sid2)->Revision ) {
00904
00905
00906
00907
00908
00909
00910
if ( *
RtlSubAuthorityCountSid( Sid1 ) == *
RtlSubAuthorityCountSid( Sid2 )) {
00911
00912 SidLength =
SeLengthSid( Sid1 );
00913
return( (BOOLEAN)RtlEqualMemory( Sid1, Sid2, SidLength) );
00914 }
00915 }
00916
00917
return(
FALSE );
00918
00919 }
00920
00921
00922
00923 BOOLEAN
00924 RtlEqualPrefixSid (
00925 IN PSID Sid1,
00926 IN PSID Sid2
00927 )
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 {
00952 LONG
Index;
00953
00954
00955
00956
00957
00958 SID *ISid1 = Sid1;
00959 SID *ISid2 = Sid2;
00960
00961
RTL_PAGED_CODE();
00962
00963
00964
00965
00966
00967
if (ISid1->Revision == ISid2->Revision ) {
00968
00969
00970
00971
00972
00973
if ( (ISid1->IdentifierAuthority.Value[0] ==
00974 ISid2->IdentifierAuthority.Value[0]) &&
00975 (ISid1->IdentifierAuthority.Value[1]==
00976 ISid2->IdentifierAuthority.Value[1]) &&
00977 (ISid1->IdentifierAuthority.Value[2] ==
00978 ISid2->IdentifierAuthority.Value[2]) &&
00979 (ISid1->IdentifierAuthority.Value[3] ==
00980 ISid2->IdentifierAuthority.Value[3]) &&
00981 (ISid1->IdentifierAuthority.Value[4] ==
00982 ISid2->IdentifierAuthority.Value[4]) &&
00983 (ISid1->IdentifierAuthority.Value[5] ==
00984 ISid2->IdentifierAuthority.Value[5])
00985 ) {
00986
00987
00988
00989
00990
00991
if (ISid1->SubAuthorityCount == ISid2->SubAuthorityCount) {
00992
00993
if (ISid1->SubAuthorityCount == 0) {
00994
return TRUE;
00995 }
00996
00997
Index = 0;
00998
while (
Index < (ISid1->SubAuthorityCount - 1)) {
00999
if ((ISid1->SubAuthority[
Index]) != (ISid2->SubAuthority[
Index])) {
01000
01001
01002
01003
01004
01005
return FALSE;
01006 }
01007
Index += 1;
01008 }
01009
01010
01011
01012
01013
01014
return TRUE;
01015 }
01016 }
01017 }
01018
01019
01020
01021
01022
01023
01024
return FALSE;
01025 }
01026
01027
01028
01029 ULONG
01030 RtlLengthRequiredSid (
01031 IN ULONG SubAuthorityCount
01032 )
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 {
01053
RTL_PAGED_CODE();
01054
01055
return (8
L + (4 * SubAuthorityCount));
01056
01057 }
01058
01059
#ifndef NTOS_KERNEL_RUNTIME
01060
01061
NTSTATUS
01062 RtlAllocateAndInitializeSid(
01063 IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
01064 IN UCHAR SubAuthorityCount,
01065 IN ULONG SubAuthority0,
01066 IN ULONG SubAuthority1,
01067 IN ULONG SubAuthority2,
01068 IN ULONG SubAuthority3,
01069 IN ULONG SubAuthority4,
01070 IN ULONG SubAuthority5,
01071 IN ULONG SubAuthority6,
01072 IN ULONG SubAuthority7,
01073 OUT PSID *Sid
01074 )
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115 {
01116 PISID ISid;
01117
01118
RTL_PAGED_CODE();
01119
01120
if ( SubAuthorityCount > 8 ) {
01121
return( STATUS_INVALID_SID );
01122 }
01123
01124 ISid =
RtlAllocateHeap( RtlProcessHeap(), 0,
01125
RtlLengthRequiredSid(SubAuthorityCount)
01126 );
01127
if (ISid ==
NULL) {
01128
return(STATUS_NO_MEMORY);
01129 }
01130
01131 ISid->SubAuthorityCount = (UCHAR)SubAuthorityCount;
01132 ISid->Revision = 1;
01133 ISid->IdentifierAuthority = *IdentifierAuthority;
01134
01135
switch (SubAuthorityCount) {
01136
01137
case 8:
01138 ISid->SubAuthority[7] = SubAuthority7;
01139
case 7:
01140 ISid->SubAuthority[6] = SubAuthority6;
01141
case 6:
01142 ISid->SubAuthority[5] = SubAuthority5;
01143
case 5:
01144 ISid->SubAuthority[4] = SubAuthority4;
01145
case 4:
01146 ISid->SubAuthority[3] = SubAuthority3;
01147
case 3:
01148 ISid->SubAuthority[2] = SubAuthority2;
01149
case 2:
01150 ISid->SubAuthority[1] = SubAuthority1;
01151
case 1:
01152 ISid->SubAuthority[0] = SubAuthority0;
01153
case 0:
01154 ;
01155 }
01156
01157 (*Sid) = ISid;
01158
return( STATUS_SUCCESS );
01159
01160 }
01161
#endif // NTOS_KERNEL_RUNTIME
01162
01163
01164
01165
NTSTATUS
01166 RtlInitializeSid(
01167 IN PSID Sid,
01168 IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
01169 IN UCHAR SubAuthorityCount
01170 )
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 {
01193 PISID ISid;
01194
01195
RTL_PAGED_CODE();
01196
01197
01198
01199
01200
01201 ISid = (PISID)Sid;
01202
01203
if ( SubAuthorityCount > SID_MAX_SUB_AUTHORITIES ) {
01204
return( STATUS_INVALID_PARAMETER );
01205 }
01206
01207 ISid->SubAuthorityCount = (UCHAR)SubAuthorityCount;
01208 ISid->Revision = 1;
01209 ISid->IdentifierAuthority = *IdentifierAuthority;
01210
01211
return( STATUS_SUCCESS );
01212
01213 }
01214
01215
#ifndef NTOS_KERNEL_RUNTIME
01216
01217 PVOID
01218 RtlFreeSid(
01219 IN PSID Sid
01220 )
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 {
01242
RTL_PAGED_CODE();
01243
01244
if (
RtlFreeHeap( RtlProcessHeap(), 0, Sid ))
01245
return NULL;
01246
else
01247
return Sid;
01248 }
01249
#endif // NTOS_KERNEL_RUNTIME
01250
01251
01252 PSID_IDENTIFIER_AUTHORITY
01253 RtlIdentifierAuthoritySid(
01254 IN PSID Sid
01255 )
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270 {
01271 PISID ISid;
01272
01273
RTL_PAGED_CODE();
01274
01275
01276
01277
01278
01279 ISid = (PISID)Sid;
01280
01281
return &(ISid->IdentifierAuthority);
01282
01283 }
01284
01285 PULONG
01286 RtlSubAuthoritySid(
01287 IN PSID Sid,
01288 IN ULONG SubAuthority
01289 )
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309 {
01310
RTL_PAGED_CODE();
01311
01312
return RtlpSubAuthoritySid( Sid, SubAuthority );
01313 }
01314
01315 PUCHAR
01316 RtlSubAuthorityCountSid(
01317 IN PSID Sid
01318 )
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334 {
01335 PISID ISid;
01336
01337
RTL_PAGED_CODE();
01338
01339
01340
01341
01342
01343 ISid = (PISID)Sid;
01344
01345
return &(ISid->SubAuthorityCount);
01346
01347 }
01348
01349 ULONG
01350 RtlLengthSid (
01351 IN PSID Sid
01352 )
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372 {
01373
RTL_PAGED_CODE();
01374
01375
return SeLengthSid(Sid);
01376 }
01377
01378
01379
NTSTATUS
01380 RtlCopySid (
01381 IN ULONG DestinationSidLength,
01382 OUT PSID DestinationSid,
01383 IN PSID SourceSid
01384 )
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413 {
01414 ULONG SidLength =
SeLengthSid(SourceSid);
01415
01416
RTL_PAGED_CODE();
01417
01418
if (SidLength > DestinationSidLength) {
01419
01420
return STATUS_BUFFER_TOO_SMALL;
01421
01422 }
01423
01424
01425
01426
01427
01428 RtlMoveMemory( DestinationSid, SourceSid, SidLength );
01429
01430
return STATUS_SUCCESS;
01431
01432 }
01433
01434
01435
NTSTATUS
01436 RtlCopySidAndAttributesArray (
01437 IN ULONG ArrayLength,
01438 IN PSID_AND_ATTRIBUTES Source,
01439 IN ULONG TargetSidBufferSize,
01440 OUT PSID_AND_ATTRIBUTES TargetArrayElement,
01441 OUT PSID TargetSid,
01442 OUT PSID *NextTargetSid,
01443 OUT PULONG RemainingTargetSidBufferSize
01444 )
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490 {
01491
01492 ULONG
Index = 0;
01493 PSID NextSid = TargetSid;
01494 ULONG NextSidLength;
01495 ULONG AlignedSidLength;
01496 ULONG RemainingLength = TargetSidBufferSize;
01497
01498
RTL_PAGED_CODE();
01499
01500
while (
Index < ArrayLength) {
01501
01502 NextSidLength =
SeLengthSid( Source[
Index].Sid );
01503 AlignedSidLength = PtrToUlong(
LongAlign(NextSidLength));
01504
01505
if (NextSidLength > RemainingLength) {
01506
return STATUS_BUFFER_TOO_SMALL;
01507 }
01508
01509 RemainingLength -= AlignedSidLength;
01510
01511 TargetArrayElement[
Index].Sid = NextSid;
01512 TargetArrayElement[
Index].Attributes = Source[
Index].Attributes;
01513
01514
RtlCopySid( NextSidLength, NextSid, Source[
Index].Sid );
01515
01516 NextSid = (PSID)((PCHAR)NextSid + AlignedSidLength);
01517
01518
Index += 1;
01519
01520 }
01521
01522 (*NextTargetSid) = NextSid;
01523 (*RemainingTargetSidBufferSize) = RemainingLength;
01524
01525
return STATUS_SUCCESS;
01526
01527 }
01528
01529
01530
01531
NTSTATUS
01532 RtlLengthSidAsUnicodeString(
01533 PSID Sid,
01534 PULONG StringLength
01535 )
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562 {
01563 ULONG i ;
01564
01565 PISID iSid = (PISID)Sid;
01566
01567
01568
RTL_PAGED_CODE();
01569
01570
if (
RtlValidSid( Sid ) !=
TRUE)
01571 {
01572
return(STATUS_INVALID_SID);
01573 }
01574
01575
01576
01577
01578
01579
01580
01581
if ( (iSid->IdentifierAuthority.Value[0] != 0) ||
01582 (iSid->IdentifierAuthority.Value[1] != 0) )
01583 {
01584 i = 14 ;
01585
01586 }
01587
else
01588 {
01589 i = 10 ;
01590 }
01591
01592 i += 4 ;
01593
01594
01595
01596
01597
01598
01599 i += 11 * iSid->SubAuthorityCount ;
01600
01601 *
StringLength = i *
sizeof( WCHAR );
01602
01603
return STATUS_SUCCESS ;
01604
01605 }
01606
01607
01608
01609
01610
NTSTATUS
01611 RtlConvertSidToUnicodeString(
01612 PUNICODE_STRING UnicodeString,
01613 PSID Sid,
01614 BOOLEAN AllocateDestinationString
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
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 {
01684
NTSTATUS Status;
01685 WCHAR UniBuffer[ 256 ];
01686 PWSTR
Offset ;
01687 UNICODE_STRING LocalString ;
01688
01689 UCHAR i;
01690 ULONG Tmp;
01691 LARGE_INTEGER Auth ;
01692
01693 PISID iSid = (PISID)Sid;
01694
01695
01696
RTL_PAGED_CODE();
01697
01698
if (
RtlValidSid( Sid ) !=
TRUE) {
01699
return(STATUS_INVALID_SID);
01700 }
01701
01702
if ( iSid->Revision != SID_REVISION )
01703 {
01704
return STATUS_INVALID_SID ;
01705 }
01706
01707 wcscpy( UniBuffer,
L"S-1-" );
01708
01709
Offset = &UniBuffer[ 4 ];
01710
01711
if ( (iSid->IdentifierAuthority.Value[0] != 0) ||
01712 (iSid->IdentifierAuthority.Value[1] != 0) ){
01713
01714
01715
01716
01717
01718 Auth.HighPart = (LONG) (iSid->IdentifierAuthority.Value[ 0 ] << 8) +
01719 (LONG) iSid->IdentifierAuthority.Value[ 1 ] ;
01720
01721 Auth.LowPart = (ULONG)iSid->IdentifierAuthority.Value[5] +
01722 (ULONG)(iSid->IdentifierAuthority.Value[4] << 8) +
01723 (ULONG)(iSid->IdentifierAuthority.Value[3] << 16) +
01724 (ULONG)(iSid->IdentifierAuthority.Value[2] << 24);
01725
01726
Status =
RtlLargeIntegerToUnicode(
01727 &Auth,
01728 16,
01729 256 - (LONG) (
Offset - UniBuffer),
01730
Offset );
01731
01732
01733 }
else {
01734
01735 Tmp = (ULONG)iSid->IdentifierAuthority.Value[5] +
01736 (ULONG)(iSid->IdentifierAuthority.Value[4] << 8) +
01737 (ULONG)(iSid->IdentifierAuthority.Value[3] << 16) +
01738 (ULONG)(iSid->IdentifierAuthority.Value[2] << 24);
01739
01740
Status =
RtlIntegerToUnicode(
01741 Tmp,
01742 10,
01743 256 - (LONG) (
Offset - UniBuffer),
01744
Offset );
01745
01746 }
01747
01748
if ( !
NT_SUCCESS(
Status ) )
01749 {
01750
return Status ;
01751 }
01752
01753
01754
for (i=0;i<iSid->SubAuthorityCount ;i++ ) {
01755
01756
while ( *
Offset && (
Offset < &UniBuffer[ 255 ] ) )
01757 {
01758
Offset++ ;
01759 }
01760
01761 *
Offset++ =
L'-' ;
01762
01763
Status =
RtlIntegerToUnicode(
01764 iSid->SubAuthority[ i ],
01765 10,
01766 256 - (LONG) (
Offset - UniBuffer),
01767
Offset );
01768
01769
if ( !
NT_SUCCESS(
Status ) )
01770 {
01771
return Status ;
01772 }
01773 }
01774
01775
if ( AllocateDestinationString )
01776 {
01777
if (
RtlCreateUnicodeString( UnicodeString,
01778 UniBuffer ) )
01779 {
01780
Status = STATUS_SUCCESS ;
01781 }
01782
else
01783 {
01784
Status = STATUS_NO_MEMORY ;
01785 }
01786
01787 }
01788
else
01789 {
01790
01791
while ( *
Offset && (
Offset < &UniBuffer[ 255 ] ) )
01792 {
01793
Offset++ ;
01794 }
01795
01796 Tmp = (ULONG) (
Offset - UniBuffer) *
sizeof( WCHAR );
01797
01798
if ( Tmp < UnicodeString->MaximumLength )
01799 {
01800 LocalString.Length = (
USHORT) Tmp ;
01801 LocalString.MaximumLength = LocalString.Length +
sizeof( WCHAR );
01802 LocalString.Buffer = UniBuffer ;
01803
01804
RtlCopyUnicodeString(
01805 UnicodeString,
01806 &LocalString );
01807
01808
Status = STATUS_SUCCESS ;
01809 }
01810
else
01811 {
01812
Status = STATUS_BUFFER_OVERFLOW ;
01813 }
01814
01815 }
01816
01817
return(
Status);
01818 }
01819
01820
01821
01822
01823 BOOLEAN
01824 RtlEqualLuid (
01825 IN PLUID Luid1,
01826 IN PLUID Luid2
01827 )
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850 {
01851 LUID UNALIGNED * TempLuid1;
01852 LUID UNALIGNED * TempLuid2;
01853
01854
RTL_PAGED_CODE();
01855
01856
return((Luid1->HighPart == Luid2->HighPart) &&
01857 (Luid1->LowPart == Luid2->LowPart));
01858
01859 }
01860
01861
01862
VOID
01863 RtlCopyLuid (
01864 OUT PLUID DestinationLuid,
01865 IN PLUID SourceLuid
01866 )
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888 {
01889
RTL_PAGED_CODE();
01890
01891 (*DestinationLuid) = (*SourceLuid);
01892
return;
01893 }
01894
01895
VOID
01896 RtlCopyLuidAndAttributesArray (
01897 IN ULONG ArrayLength,
01898 IN PLUID_AND_ATTRIBUTES Source,
01899 OUT PLUID_AND_ATTRIBUTES Target
01900 )
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925 {
01926
01927 ULONG
Index = 0;
01928
01929
RTL_PAGED_CODE();
01930
01931
while (
Index < ArrayLength) {
01932
01933 Target[
Index] = Source[
Index];
01934
01935
Index += 1;
01936
01937 }
01938
01939
01940
return;
01941
01942 }
01943
01944
NTSTATUS
01945 RtlCreateSecurityDescriptor (
01946 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
01947 IN ULONG Revision
01948 )
01949
01950
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
RTL_PAGED_CODE();
01979
01980
01981
01982
01983
01984
if (Revision == SECURITY_DESCRIPTOR_REVISION) {
01985
01986
01987
01988
01989
01990 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
01991
01992 RtlZeroMemory( ISecurityDescriptor,
sizeof(SECURITY_DESCRIPTOR));
01993
01994 ISecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
01995
01996
return STATUS_SUCCESS;
01997 }
01998
01999
return STATUS_UNKNOWN_REVISION;
02000 }
02001
02002
02003
NTSTATUS
02004 RtlCreateSecurityDescriptorRelative (
02005 IN PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
02006 IN ULONG Revision
02007 )
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041 {
02042
RTL_PAGED_CODE();
02043
02044
02045
02046
02047
02048
if (Revision == SECURITY_DESCRIPTOR_REVISION) {
02049
02050
02051
02052
02053
02054 RtlZeroMemory( SecurityDescriptor,
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
02055
02056 SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
02057
02058
return STATUS_SUCCESS;
02059 }
02060
02061
return STATUS_UNKNOWN_REVISION;
02062 }
02063
02064
02065 BOOLEAN
02066 RtlValidSecurityDescriptor (
02067 IN PSECURITY_DESCRIPTOR SecurityDescriptor
02068 )
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090 {
02091 PSID
Owner;
02092 PSID
Group;
02093 PACL
Dacl;
02094 PACL Sacl;
02095
02096
02097
02098
02099
02100 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
02101
02102
RTL_PAGED_CODE();
02103
02104
try {
02105
02106
02107
02108
02109
02110
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
02111
return FALSE;
02112 }
02113
02114
02115
02116
02117
02118
02119
Owner = RtlpOwnerAddrSecurityDescriptor( ISecurityDescriptor );
02120
02121
if (
Owner !=
NULL) {
02122
if (!
RtlValidSid(
Owner )) {
02123
return FALSE;
02124 }
02125 }
02126
02127
Group = RtlpGroupAddrSecurityDescriptor( ISecurityDescriptor );
02128
02129
if (
Group !=
NULL) {
02130
if (!
RtlValidSid(
Group )) {
02131
return FALSE;
02132 }
02133 }
02134
02135
Dacl = RtlpDaclAddrSecurityDescriptor( ISecurityDescriptor );
02136
if (
Dacl !=
NULL ) {
02137
02138
if (!
RtlValidAcl(
Dacl )) {
02139
return FALSE;
02140 }
02141 }
02142
02143 Sacl = RtlpSaclAddrSecurityDescriptor( ISecurityDescriptor );
02144
if ( Sacl !=
NULL ) {
02145
if (!
RtlValidAcl( Sacl )) {
02146
return FALSE;
02147 }
02148 }
02149
02150 } except(
EXCEPTION_EXECUTE_HANDLER) {
02151
return FALSE;
02152 }
02153
02154
02155
02156
02157
02158
return TRUE;
02159
02160
02161 }
02162
02163
02164 ULONG
02165 RtlLengthSecurityDescriptor (
02166 IN PSECURITY_DESCRIPTOR SecurityDescriptor
02167 )
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195 {
02196 ULONG sum;
02197 PVOID Temp;
02198
02199
02200
02201
02202
02203
02204 SECURITY_DESCRIPTOR *ISecurityDescriptor = (SECURITY_DESCRIPTOR *)SecurityDescriptor;
02205
02206
RTL_PAGED_CODE();
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218 sum = ISecurityDescriptor->Control & SE_SELF_RELATIVE ?
02219
sizeof(SECURITY_DESCRIPTOR_RELATIVE) :
02220
sizeof(SECURITY_DESCRIPTOR);
02221
02222
02223
02224
02225
02226 Temp = RtlpOwnerAddrSecurityDescriptor(ISecurityDescriptor);
02227
if (Temp !=
NULL) {
02228 sum += LongAlignSize(
SeLengthSid(Temp));
02229 }
02230
02231
02232
02233
02234
02235 Temp = RtlpGroupAddrSecurityDescriptor(ISecurityDescriptor);
02236
if (Temp !=
NULL) {
02237 sum += LongAlignSize(
SeLengthSid(Temp));
02238 }
02239
02240
02241
02242
02243
02244 Temp = RtlpDaclAddrSecurityDescriptor(ISecurityDescriptor);
02245
if ( Temp !=
NULL ) {
02246
02247 sum += LongAlignSize(((PACL) Temp)->AclSize );
02248 }
02249
02250
02251
02252
02253
02254 Temp = RtlpSaclAddrSecurityDescriptor(ISecurityDescriptor);
02255
if ( Temp !=
NULL ) {
02256
02257 sum += LongAlignSize(((PACL) Temp)->AclSize );
02258 }
02259
02260
return sum;
02261 }
02262
02263
02264 ULONG
02265 RtlLengthUsedSecurityDescriptor (
02266 IN PSECURITY_DESCRIPTOR SecurityDescriptor
02267 )
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304 {
02305 ULONG sum;
02306
02307 ACL_SIZE_INFORMATION AclSize;
02308 PVOID Temp;
02309
02310
02311
02312
02313
02314 SECURITY_DESCRIPTOR *ISecurityDescriptor = (SECURITY_DESCRIPTOR *)SecurityDescriptor;
02315
02316
RTL_PAGED_CODE();
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328 sum = ISecurityDescriptor->Control & SE_SELF_RELATIVE ?
02329
sizeof(SECURITY_DESCRIPTOR_RELATIVE) :
02330
sizeof(SECURITY_DESCRIPTOR);
02331
02332
02333
02334
02335
02336 Temp = RtlpOwnerAddrSecurityDescriptor(ISecurityDescriptor);
02337
if (Temp !=
NULL) {
02338 sum += LongAlignSize(
SeLengthSid(Temp));
02339 }
02340
02341
02342
02343
02344
02345 Temp = RtlpGroupAddrSecurityDescriptor(ISecurityDescriptor);
02346
if (Temp !=
NULL) {
02347 sum += LongAlignSize(
SeLengthSid(Temp));
02348 }
02349
02350
02351
02352
02353
02354 Temp = RtlpDaclAddrSecurityDescriptor(ISecurityDescriptor);
02355
if ( Temp !=
NULL ) {
02356
02357
RtlQueryInformationAcl( Temp,
02358 (PVOID)&AclSize,
02359
sizeof(AclSize),
02360 AclSizeInformation );
02361
02362 sum += LongAlignSize(AclSize.AclBytesInUse);
02363 }
02364
02365
02366
02367
02368
02369 Temp = RtlpSaclAddrSecurityDescriptor(ISecurityDescriptor);
02370
if ( Temp !=
NULL ) {
02371
02372
RtlQueryInformationAcl( Temp,
02373 (PVOID)&AclSize,
02374
sizeof(AclSize),
02375 AclSizeInformation );
02376
02377 sum += LongAlignSize(AclSize.AclBytesInUse);
02378 }
02379
02380
return sum;
02381 }
02382
02383
02384
02385
NTSTATUS
02386 RtlSetAttributesSecurityDescriptor(
02387 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02388 IN SECURITY_DESCRIPTOR_CONTROL Control,
02389 OUT PULONG Revision
02390 )
02391 {
02392
RTL_PAGED_CODE();
02393
02394
02395
02396
02397
02398
02399 *Revision = ((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Revision;
02400
02401
if ( ((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Revision
02402 != SECURITY_DESCRIPTOR_REVISION ) {
02403
return STATUS_UNKNOWN_REVISION;
02404 }
02405
02406
02407
02408 Control &=
SE_VALID_CONTROL_BITS;
02409
return RtlSetControlSecurityDescriptor ( SecurityDescriptor, Control, Control );
02410 }
02411
02412
02413
02414
NTSTATUS
02415 RtlGetControlSecurityDescriptor (
02416 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02417 OUT PSECURITY_DESCRIPTOR_CONTROL Control,
02418 OUT PULONG Revision
02419 )
02420
02421
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
RTL_PAGED_CODE();
02450
02451
02452
02453
02454
02455
02456 *Revision = ((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Revision;
02457
02458
02459
if ( ((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Revision
02460 != SECURITY_DESCRIPTOR_REVISION ) {
02461
return STATUS_UNKNOWN_REVISION;
02462 }
02463
02464
02465 *Control = ((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Control;
02466
02467
return STATUS_SUCCESS;
02468
02469 }
02470
02471
NTSTATUS
02472 RtlSetControlSecurityDescriptor (
02473 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
02474 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
02475 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
02476 )
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525 {
02526
02527
02528
02529
02530
if ( (ControlBitsOfInterest & ~
SE_VALID_CONTROL_BITS) != 0 ||
02531 (ControlBitsToSet & ~ControlBitsOfInterest) != 0 ) {
02532
return STATUS_INVALID_PARAMETER;
02533 }
02534
02535 ((SECURITY_DESCRIPTOR *)pSecurityDescriptor)->Control &= ~ControlBitsOfInterest;
02536 ((SECURITY_DESCRIPTOR *)pSecurityDescriptor)->Control |= ControlBitsToSet;
02537
02538
return STATUS_SUCCESS;
02539 }
02540
02541
02542
NTSTATUS
02543 RtlSetDaclSecurityDescriptor (
02544 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02545 IN BOOLEAN DaclPresent,
02546 IN PACL Dacl OPTIONAL,
02547 IN BOOLEAN DaclDefaulted OPTIONAL
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
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597 {
02598
02599
02600
02601
02602
02603 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
02604
02605
RTL_PAGED_CODE();
02606
02607
02608
02609
02610
02611
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
02612
return STATUS_UNKNOWN_REVISION;
02613 }
02614
02615
02616
02617
02618
02619
if (ISecurityDescriptor->Control & SE_SELF_RELATIVE) {
02620
return STATUS_INVALID_SECURITY_DESCR;
02621 }
02622
02623
02624
02625
02626
02627
02628
if (DaclPresent) {
02629
02630 ISecurityDescriptor->Control |= SE_DACL_PRESENT;
02631
02632
02633
02634
02635
02636 ISecurityDescriptor->Dacl =
NULL;
02637
if (ARGUMENT_PRESENT(
Dacl)) {
02638 ISecurityDescriptor->Dacl =
Dacl;
02639 }
02640
02641
02642
02643
02644
02645
02646
02647
02648 ISecurityDescriptor->Control &= ~SE_DACL_DEFAULTED;
02649
if (DaclDefaulted ==
TRUE) {
02650 ISecurityDescriptor->Control |= SE_DACL_DEFAULTED;
02651 }
02652 }
else {
02653
02654 ISecurityDescriptor->Control &= ~SE_DACL_PRESENT;
02655
02656 }
02657
02658
02659
return STATUS_SUCCESS;
02660
02661 }
02662
02663
02664
NTSTATUS
02665 RtlGetDaclSecurityDescriptor (
02666 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02667 OUT PBOOLEAN DaclPresent,
02668 OUT PACL *Dacl,
02669 OUT PBOOLEAN DaclDefaulted
02670 )
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712 {
02713
02714
02715
02716
02717 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
02718
02719
RTL_PAGED_CODE();
02720
02721
02722
02723
02724
02725
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
02726
return STATUS_UNKNOWN_REVISION;
02727 }
02728
02729
02730
02731
02732
02733 *DaclPresent = RtlpAreControlBitsSet( ISecurityDescriptor, SE_DACL_PRESENT );
02734
02735
if (*DaclPresent) {
02736
02737
02738
02739
02740
02741 *
Dacl = RtlpDaclAddrSecurityDescriptor(ISecurityDescriptor);
02742
02743
02744
02745
02746
02747 *DaclDefaulted = RtlpAreControlBitsSet( ISecurityDescriptor, SE_DACL_DEFAULTED );
02748 }
02749
02750
return STATUS_SUCCESS;
02751
02752 }
02753
02754
02755
NTSTATUS
02756 RtlSetSaclSecurityDescriptor (
02757 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02758 IN BOOLEAN SaclPresent,
02759 IN PACL Sacl OPTIONAL,
02760 IN BOOLEAN SaclDefaulted OPTIONAL
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
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808 {
02809
02810
02811
02812
02813
02814 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
02815
02816
RTL_PAGED_CODE();
02817
02818
02819
02820
02821
02822
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
02823
return STATUS_UNKNOWN_REVISION;
02824 }
02825
02826
02827
02828
02829
02830
if (ISecurityDescriptor->Control & SE_SELF_RELATIVE) {
02831
return STATUS_INVALID_SECURITY_DESCR;
02832 }
02833
02834
02835
02836
02837
02838
02839
if (SaclPresent) {
02840
02841 ISecurityDescriptor->Control |= SE_SACL_PRESENT;
02842
02843
02844
02845
02846
02847 ISecurityDescriptor->Sacl =
NULL;
02848
if (ARGUMENT_PRESENT(Sacl)) {
02849 ISecurityDescriptor->Sacl = Sacl;
02850 }
02851
02852
02853
02854
02855
02856 ISecurityDescriptor->Control &= ~ SE_SACL_DEFAULTED;
02857
if (ARGUMENT_PRESENT(SaclDefaulted)) {
02858 ISecurityDescriptor->Control |= SE_SACL_DEFAULTED;
02859 }
02860 }
else {
02861
02862 ISecurityDescriptor->Control &= ~SE_SACL_PRESENT;
02863 }
02864
02865
return STATUS_SUCCESS;
02866
02867 }
02868
02869
02870
NTSTATUS
02871 RtlGetSaclSecurityDescriptor (
02872 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02873 OUT PBOOLEAN SaclPresent,
02874 OUT PACL *Sacl,
02875 OUT PBOOLEAN SaclDefaulted
02876 )
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917 {
02918
02919
02920
02921
02922
02923 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
02924
02925
RTL_PAGED_CODE();
02926
02927
02928
02929
02930
02931
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
02932
return STATUS_UNKNOWN_REVISION;
02933 }
02934
02935
02936
02937
02938
02939 *SaclPresent = RtlpAreControlBitsSet( ISecurityDescriptor, SE_SACL_PRESENT );
02940
02941
if (*SaclPresent) {
02942
02943
02944
02945
02946
02947 *Sacl = RtlpSaclAddrSecurityDescriptor(ISecurityDescriptor);
02948
02949
02950
02951
02952
02953 *SaclDefaulted = RtlpAreControlBitsSet( ISecurityDescriptor, SE_SACL_DEFAULTED );
02954
02955 }
02956
02957
return STATUS_SUCCESS;
02958
02959 }
02960
02961
02962
NTSTATUS
02963 RtlSetOwnerSecurityDescriptor (
02964 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
02965 IN PSID Owner OPTIONAL,
02966 IN BOOLEAN OwnerDefaulted OPTIONAL
02967 )
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009 {
03010
03011
03012
03013
03014
03015 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
03016
03017
RTL_PAGED_CODE();
03018
03019
03020
03021
03022
03023
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
03024
return STATUS_UNKNOWN_REVISION;
03025 }
03026
03027
03028
03029
03030
03031
if (ISecurityDescriptor->Control & SE_SELF_RELATIVE) {
03032
return STATUS_INVALID_SECURITY_DESCR;
03033 }
03034
03035
03036
03037
03038
03039 ISecurityDescriptor->Owner =
NULL;
03040
if (ARGUMENT_PRESENT(
Owner)) {
03041 ISecurityDescriptor->Owner =
Owner;
03042 }
03043
03044
03045
03046
03047
03048 ISecurityDescriptor->Control &= ~SE_OWNER_DEFAULTED;
03049
if (OwnerDefaulted ==
TRUE) {
03050 ISecurityDescriptor->Control |= SE_OWNER_DEFAULTED;
03051 }
03052
03053
return STATUS_SUCCESS;
03054
03055 }
03056
03057
03058
NTSTATUS
03059 RtlGetOwnerSecurityDescriptor (
03060 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
03061 OUT PSID *Owner,
03062 OUT PBOOLEAN OwnerDefaulted
03063 )
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099 {
03100
03101
03102
03103
03104
03105 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
03106
03107
RTL_PAGED_CODE();
03108
03109
03110
03111
03112
03113
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
03114
return STATUS_UNKNOWN_REVISION;
03115 }
03116
03117
03118
03119
03120
03121 *
Owner = RtlpOwnerAddrSecurityDescriptor(ISecurityDescriptor);
03122
03123
03124
03125
03126
03127 *OwnerDefaulted = RtlpAreControlBitsSet( ISecurityDescriptor, SE_OWNER_DEFAULTED );
03128
03129
return STATUS_SUCCESS;
03130
03131 }
03132
03133
03134
NTSTATUS
03135 RtlSetGroupSecurityDescriptor (
03136 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
03137 IN PSID Group OPTIONAL,
03138 IN BOOLEAN GroupDefaulted OPTIONAL
03139 )
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182 {
03183
03184
03185
03186
03187
03188 SECURITY_DESCRIPTOR *ISecurityDescriptor = SecurityDescriptor;
03189
03190
RTL_PAGED_CODE();
03191
03192
03193
03194
03195
03196
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
03197
return STATUS_UNKNOWN_REVISION;
03198 }
03199
03200
03201
03202
03203
03204
if (ISecurityDescriptor->Control & SE_SELF_RELATIVE) {
03205
return STATUS_INVALID_SECURITY_DESCR;
03206 }
03207
03208
03209
03210
03211
03212 ISecurityDescriptor->Group =
NULL;
03213
if (ARGUMENT_PRESENT(
Group)) {
03214 ISecurityDescriptor->Group =
Group;
03215 }
03216
03217
03218
03219
03220
03221 ISecurityDescriptor->Control &= ~SE_GROUP_DEFAULTED;
03222
if (ARGUMENT_PRESENT(GroupDefaulted)) {
03223 ISecurityDescriptor->Control |= SE_GROUP_DEFAULTED;
03224 }
03225
03226
return STATUS_SUCCESS;
03227
03228 }
03229
03230
03231
NTSTATUS
03232 RtlGetGroupSecurityDescriptor (
03233 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
03234 OUT PSID *Group,
03235 OUT PBOOLEAN GroupDefaulted
03236 )
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272 {
03273
03274
03275
03276
03277
03278 SECURITY_DESCRIPTOR *ISecurityDescriptor =
03279 (SECURITY_DESCRIPTOR *)SecurityDescriptor;
03280
03281
RTL_PAGED_CODE();
03282
03283
03284
03285
03286
03287
if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
03288
return STATUS_UNKNOWN_REVISION;
03289 }
03290
03291
03292
03293
03294
03295 *
Group = RtlpGroupAddrSecurityDescriptor(ISecurityDescriptor);
03296
03297
03298
03299
03300
03301 *GroupDefaulted = RtlpAreControlBitsSet( ISecurityDescriptor, SE_GROUP_DEFAULTED );
03302
03303
return STATUS_SUCCESS;
03304
03305 }
03306
03307
03308 BOOLEAN
03309 RtlAreAllAccessesGranted(
03310 IN ACCESS_MASK GrantedAccess,
03311 IN ACCESS_MASK DesiredAccess
03312 )
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336 {
03337
RTL_PAGED_CODE();
03338
03339
return ((BOOLEAN)((~(GrantedAccess) & (DesiredAccess)) == 0));
03340 }
03341
03342
03343 BOOLEAN
03344 RtlAreAnyAccessesGranted(
03345 IN ACCESS_MASK GrantedAccess,
03346 IN ACCESS_MASK DesiredAccess
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
RTL_PAGED_CODE();
03375
03376
return ((BOOLEAN)(((GrantedAccess) & (DesiredAccess)) != 0));
03377 }
03378
03379
03380
VOID
03381 RtlMapGenericMask(
03382 IN OUT PACCESS_MASK AccessMask,
03383 IN PGENERIC_MAPPING GenericMapping
03384 )
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407 {
03408
RTL_PAGED_CODE();
03409
03410
03411
03412
03413
03414
03415
03416
if (*AccessMask & GENERIC_READ) {
03417
03418 *AccessMask |= GenericMapping->GenericRead;
03419 }
03420
03421
if (*AccessMask & GENERIC_WRITE) {
03422
03423 *AccessMask |= GenericMapping->GenericWrite;
03424 }
03425
03426
if (*AccessMask & GENERIC_EXECUTE) {
03427
03428 *AccessMask |= GenericMapping->GenericExecute;
03429 }
03430
03431
if (*AccessMask & GENERIC_ALL) {
03432
03433 *AccessMask |= GenericMapping->GenericAll;
03434 }
03435
03436
03437
03438
03439
03440 *AccessMask &= ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
03441
03442
return;
03443 }
03444
03445
NTSTATUS
03446 RtlImpersonateSelf(
03447 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
03448 )
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481 {
03482
NTSTATUS
03483
Status,
03484 IgnoreStatus;
03485
03486 HANDLE
03487 Token1,
03488 Token2;
03489
03490 OBJECT_ATTRIBUTES
03491
ObjectAttributes;
03492
03493 SECURITY_QUALITY_OF_SERVICE
03494 Qos;
03495
03496
03497
RTL_PAGED_CODE();
03498
03499 InitializeObjectAttributes(&
ObjectAttributes,
NULL, 0, 0,
NULL);
03500
03501 Qos.Length =
sizeof(SECURITY_QUALITY_OF_SERVICE);
03502 Qos.ImpersonationLevel = ImpersonationLevel;
03503 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
03504 Qos.EffectiveOnly =
FALSE;
03505
ObjectAttributes.SecurityQualityOfService = &Qos;
03506
03507
Status =
NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE, &Token1 );
03508
03509
if (
NT_SUCCESS(
Status)) {
03510
Status =
NtDuplicateToken(
03511 Token1,
03512 TOKEN_IMPERSONATE,
03513 &
ObjectAttributes,
03514
FALSE,
03515 TokenImpersonation,
03516 &Token2
03517 );
03518
if (
NT_SUCCESS(
Status)) {
03519
Status =
NtSetInformationThread(
03520 NtCurrentThread(),
03521 ThreadImpersonationToken,
03522 &Token2,
03523
sizeof(HANDLE)
03524 );
03525
03526 IgnoreStatus =
NtClose( Token2 );
03527 }
03528
03529
03530 IgnoreStatus =
NtClose( Token1 );
03531 }
03532
03533
03534
return(
Status);
03535
03536 }
03537
03538
#ifndef WIN16
03539
03540
03541
#ifndef NTOS_KERNEL_RUNTIME
03542
03543 BOOLEAN
03544 RtlpValidOwnerSubjectContext(
03545 IN HANDLE Token,
03546 IN PSID Owner,
03547 IN BOOLEAN ServerObject,
03548 OUT PNTSTATUS ReturnStatus
03549 )
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574 {
03575
NTSTATUS Status;
03576
03577 ULONG
Index;
03578 BOOLEAN Found;
03579 ULONG ReturnLength;
03580 PTOKEN_GROUPS GroupIds =
NULL;
03581 PTOKEN_USER UserId =
NULL;
03582 PVOID
HeapHandle;
03583 HANDLE TokenToUse;
03584
03585 BOOLEAN HasPrivilege;
03586 PRIVILEGE_SET PrivilegeSet;
03587
03588
RTL_PAGED_CODE();
03589
03590
03591
03592
03593
03594
if (
Owner ==
NULL ) {
03595 *ReturnStatus = STATUS_INVALID_OWNER;
03596
return(
FALSE);
03597 }
03598
03599
03600
03601
03602
03603
03604
03605
if (!ServerObject) {
03606
03607 TokenToUse =
Token;
03608
03609 }
else {
03610
03611 *ReturnStatus =
NtOpenProcessToken(
03612 NtCurrentProcess(),
03613 TOKEN_QUERY,
03614 &TokenToUse
03615 );
03616
03617
if (!
NT_SUCCESS( *ReturnStatus )) {
03618
return(
FALSE );
03619 }
03620 }
03621
03622
HeapHandle = RtlProcessHeap();
03623
03624
03625
03626
03627
03628 *ReturnStatus =
NtQueryInformationToken(
03629 TokenToUse,
03630 TokenUser,
03631 UserId,
03632 0,
03633 &ReturnLength
03634 );
03635
03636
if (!
NT_SUCCESS( *ReturnStatus ) && (STATUS_BUFFER_TOO_SMALL != *ReturnStatus)) {
03637
if (ServerObject) {
03638
NtClose( TokenToUse );
03639 }
03640
return(
FALSE );
03641
03642 }
03643
03644 UserId =
RtlAllocateHeap(
HeapHandle, 0, ReturnLength );
03645
03646
if (UserId ==
NULL) {
03647
03648 *ReturnStatus = STATUS_NO_MEMORY;
03649
if (ServerObject) {
03650
NtClose( TokenToUse );
03651 }
03652
03653
return(
FALSE );
03654 }
03655
03656 *ReturnStatus =
NtQueryInformationToken(
03657 TokenToUse,
03658 TokenUser,
03659 UserId,
03660 ReturnLength,
03661 &ReturnLength
03662 );
03663
03664
if (!
NT_SUCCESS( *ReturnStatus )) {
03665
RtlFreeHeap(
HeapHandle, 0, (PVOID)UserId );
03666
if (ServerObject) {
03667
NtClose( TokenToUse );
03668 }
03669
return(
FALSE );
03670 }
03671
03672
if (
RtlEqualSid(
Owner, UserId->User.Sid ) ) {
03673
03674
RtlFreeHeap(
HeapHandle, 0, (PVOID)UserId );
03675
if (ServerObject) {
03676
NtClose( TokenToUse );
03677 }
03678
return(
TRUE );
03679 }
03680
03681
RtlFreeHeap(
HeapHandle, 0, (PVOID)UserId );
03682
03683
03684
03685
03686
03687 *ReturnStatus =
NtQueryInformationToken(
03688 TokenToUse,
03689 TokenGroups,
03690 GroupIds,
03691 0,
03692 &ReturnLength
03693 );
03694
03695
if (!
NT_SUCCESS( *ReturnStatus ) && (STATUS_BUFFER_TOO_SMALL != *ReturnStatus)) {
03696
03697
if (ServerObject) {
03698
NtClose( TokenToUse );
03699 }
03700
return(
FALSE );
03701 }
03702
03703 GroupIds =
RtlAllocateHeap(
HeapHandle, 0, ReturnLength );
03704
03705
if (GroupIds ==
NULL) {
03706
03707 *ReturnStatus = STATUS_NO_MEMORY;
03708
if (ServerObject) {
03709
NtClose( TokenToUse );
03710 }
03711
return(
FALSE );
03712 }
03713
03714 *ReturnStatus =
NtQueryInformationToken(
03715 TokenToUse,
03716 TokenGroups,
03717 GroupIds,
03718 ReturnLength,
03719 &ReturnLength
03720 );
03721
03722
if (ServerObject) {
03723
NtClose( TokenToUse );
03724 }
03725
03726
if (!
NT_SUCCESS( *ReturnStatus )) {
03727
RtlFreeHeap(
HeapHandle, 0, GroupIds );
03728
return(
FALSE );
03729 }
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
Index = 0;
03741
while (
Index < GroupIds->GroupCount) {
03742
03743 Found =
RtlEqualSid(
03744
Owner,
03745 GroupIds->Groups[
Index].Sid
03746 );
03747
03748
if ( Found ) {
03749
03750
if ( RtlpIdAssignableAsOwner(GroupIds->Groups[
Index])) {
03751
03752
RtlFreeHeap(
HeapHandle, 0, GroupIds );
03753
return TRUE;
03754
03755 }
else {
03756
03757
break;
03758
03759 }
03760
03761 }
03762
03763
Index++;
03764
03765 }
03766
03767
RtlFreeHeap(
HeapHandle, 0, GroupIds );
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781 PrivilegeSet.PrivilegeCount = 1;
03782 PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
03783 PrivilegeSet.Privilege[0].Luid = RtlConvertLongToLuid(SE_RESTORE_PRIVILEGE);
03784 PrivilegeSet.Privilege[0].Attributes = 0;
03785
03786
Status =
NtPrivilegeCheck(
03787
Token,
03788 &PrivilegeSet,
03789 &HasPrivilege
03790 );
03791
03792
if (!
NT_SUCCESS(
Status )) {
03793 HasPrivilege =
FALSE;
03794 }
03795
03796
if ( HasPrivilege ) {
03797
return TRUE;
03798 }
else {
03799 *ReturnStatus = STATUS_INVALID_OWNER;
03800
return FALSE;
03801 }
03802 }
03803
#endif // NTOS_KERNEL_RUNTIME
03804
03805
#endif // WIN16
03806
03807
03808
03809
03810
03811
VOID
03812 RtlpApplyAclToObject (
03813 IN PACL Acl,
03814 IN PGENERIC_MAPPING GenericMapping
03815 )
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842 {
03843 ULONG i;
03844
03845 PACE_HEADER Ace;
03846
03847
RTL_PAGED_CODE();
03848
03849
03850
03851
03852
03853
if (Acl ==
NULL) {
03854
03855
return;
03856
03857 }
03858
03859
03860
03861
03862
03863
03864
for (i = 0, Ace =
FirstAce(Acl);
03865 i < Acl->AceCount;
03866 i += 1, Ace =
NextAce(Ace)) {
03867
03868
if (IsMSAceType( Ace )) {
03869
03870 RtlApplyAceToObject( Ace, GenericMapping );
03871 }
03872
03873 }
03874
03875
return;
03876 }
03877
03878
03879 BOOLEAN
03880 RtlpCopyEffectiveAce (
03881 IN PACE_HEADER OldAce,
03882 IN BOOLEAN AutoInherit,
03883 IN BOOLEAN WillGenerateInheritAce,
03884 IN PSID ClientOwnerSid,
03885 IN PSID ClientGroupSid,
03886 IN PSID ServerOwnerSid OPTIONAL,
03887 IN PSID ServerGroupSid OPTIONAL,
03888 IN PGENERIC_MAPPING GenericMapping,
03889 IN GUID *NewObjectType OPTIONAL,
03890 IN OUT PVOID *AcePosition,
03891 OUT PULONG NewAceLength,
03892 OUT PACL NewAcl,
03893 OUT PBOOLEAN ObjectAceInherited OPTIONAL,
03894 OUT PBOOLEAN EffectiveAceMapped,
03895 OUT PBOOLEAN AclOverflowed
03896 )
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960 {
03961 ULONG LengthRequired;
03962 ACCESS_MASK LocalMask;
03963
03964 PSID LocalServerOwner;
03965 PSID LocalServerGroup;
03966
03967 ULONG
CreatorSid[
CREATOR_SID_SIZE];
03968
03969 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
03970
03971
03972
RTL_PAGED_CODE();
03973
03974
03975
03976
03977
03978
03979
ASSERT(
RtlLengthRequiredSid( 1 ) ==
CREATOR_SID_SIZE);
03980
RtlInitializeSid( (PSID)
CreatorSid, &CreatorSidAuthority, 1 );
03981 *(RtlpSubAuthoritySid( (PSID)
CreatorSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
03982
03983 LocalServerOwner = ARGUMENT_PRESENT(ServerOwnerSid) ? ServerOwnerSid : ClientOwnerSid;
03984 LocalServerGroup = ARGUMENT_PRESENT(ServerGroupSid) ? ServerGroupSid : ClientGroupSid;
03985
03986
03987
03988
03989
03990 *EffectiveAceMapped =
FALSE;
03991
if ( ARGUMENT_PRESENT(ObjectAceInherited)) {
03992 *ObjectAceInherited =
FALSE;
03993 }
03994 *AclOverflowed =
FALSE;
03995 LengthRequired = (ULONG)OldAce->AceSize;
03996
03997
03998
03999
04000
04001
if ( IsMSAceType(OldAce) ) {
04002 ULONG Rid;
04003 PSID SidToCopy =
NULL;
04004 ULONG AceHeaderToCopyLength;
04005 PACE_HEADER AceHeaderToCopy = OldAce;
04006 PSID ServerSidToCopy =
NULL;
04007
04008 UCHAR DummyAce[
sizeof(KNOWN_OBJECT_ACE)+
sizeof(GUID)];
04009
04010
04011
04012
04013
if (IsKnownAceType( OldAce ) ) {
04014 SidToCopy = &((
PKNOWN_ACE)OldAce)->SidStart;
04015 AceHeaderToCopyLength = FIELD_OFFSET(
KNOWN_ACE, SidStart);
04016
04017 }
else if (IsCompoundAceType(OldAce)) {
04018
04019 SidToCopy = RtlCompoundAceClientSid( OldAce );
04020 AceHeaderToCopyLength = FIELD_OFFSET(KNOWN_COMPOUND_ACE, SidStart);
04021
ASSERT( FIELD_OFFSET(KNOWN_COMPOUND_ACE, Mask) ==
04022 FIELD_OFFSET(
KNOWN_ACE, Mask) );
04023
04024
04025
04026
04027 ServerSidToCopy = RtlCompoundAceServerSid( OldAce );
04028
04029
if (
RtlEqualPrefixSid ( ServerSidToCopy,
CreatorSid )) {
04030
04031 Rid = *RtlpSubAuthoritySid( ServerSidToCopy, 0 );
04032
switch (Rid) {
04033
case SECURITY_CREATOR_OWNER_RID:
04034 ServerSidToCopy = ClientOwnerSid;
04035 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(ClientOwnerSid);
04036 *EffectiveAceMapped =
TRUE;
04037
break;
04038
case SECURITY_CREATOR_GROUP_RID:
04039
if ( ClientGroupSid !=
NULL ) {
04040 ServerSidToCopy = ClientGroupSid;
04041 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(ClientGroupSid);
04042 *EffectiveAceMapped =
TRUE;
04043 }
04044
break;
04045
case SECURITY_CREATOR_OWNER_SERVER_RID:
04046 ServerSidToCopy = LocalServerOwner;
04047 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(LocalServerOwner);
04048 *EffectiveAceMapped =
TRUE;
04049
break;
04050
case SECURITY_CREATOR_GROUP_SERVER_RID:
04051 ServerSidToCopy = LocalServerGroup;
04052 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(LocalServerGroup);
04053 *EffectiveAceMapped =
TRUE;
04054
break;
04055 }
04056
04057
04058
04059
04060
if ( !*EffectiveAceMapped ) {
04061 AceHeaderToCopyLength +=
SeLengthSid( ServerSidToCopy );
04062 ServerSidToCopy =
NULL;
04063 }
04064
04065 }
else {
04066
04067
04068
04069 AceHeaderToCopyLength +=
SeLengthSid( ServerSidToCopy );
04070 ServerSidToCopy =
NULL;
04071 }
04072
04073
04074
04075
04076 }
else {
04077 GUID *InheritedObjectType;
04078
04079 SidToCopy = RtlObjectAceSid( OldAce );
04080 AceHeaderToCopyLength = (ULONG) ((PUCHAR)SidToCopy - (PUCHAR)OldAce);
04081
ASSERT( FIELD_OFFSET(KNOWN_OBJECT_ACE, Mask) ==
04082 FIELD_OFFSET(
KNOWN_ACE, Mask) );
04083
04084
04085
04086
04087 InheritedObjectType = RtlObjectAceInheritedObjectType( OldAce );
04088
if ( ARGUMENT_PRESENT(ObjectAceInherited) && InheritedObjectType !=
NULL ) {
04089
04090
04091
04092
04093
04094
04095
if ( NewObjectType ==
NULL ||
04096 !RtlEqualMemory( InheritedObjectType,
04097 NewObjectType,
04098
sizeof(GUID) ) ) {
04099
04100 LengthRequired = 0;
04101
04102
04103
04104
04105
04106
04107 }
else {
04108
04109
04110
04111
04112
04113 *ObjectAceInherited =
TRUE;
04114
04115
04116
04117
04118
04119
04120
04121
04122
if ( !WillGenerateInheritAce ) {
04123 *EffectiveAceMapped =
TRUE;
04124
04125
04126
04127
04128
04129
if ( RtlObjectAceObjectTypePresent( OldAce )) {
04130 LengthRequired -=
sizeof(GUID);
04131 AceHeaderToCopyLength -=
sizeof(GUID);
04132 RtlCopyMemory( DummyAce, OldAce, AceHeaderToCopyLength );
04133
04134 AceHeaderToCopy = (PACE_HEADER)DummyAce;
04135 ((PKNOWN_OBJECT_ACE)AceHeaderToCopy)->Flags &= ~ACE_INHERITED_OBJECT_TYPE_PRESENT;
04136
04137
04138
04139
04140
04141
04142 }
else {
04143 AceHeaderToCopyLength = AceHeaderToCopyLength -
04144
sizeof(GUID) +
04145
sizeof(
KNOWN_ACE) -
04146
sizeof(KNOWN_OBJECT_ACE);
04147 LengthRequired = LengthRequired -
04148
sizeof(GUID) +
04149
sizeof(
KNOWN_ACE) -
04150
sizeof(KNOWN_OBJECT_ACE);
04151
04152 RtlCopyMemory( DummyAce, OldAce, AceHeaderToCopyLength );
04153 AceHeaderToCopy = (PACE_HEADER)DummyAce;
04154
04155 AceHeaderToCopy->AceType =
RtlBaseAceType[ OldAce->AceType ];
04156
04157 }
04158 }
04159 }
04160
04161 }
04162 }
04163
04164
04165
04166
04167
04168
if ( LengthRequired != 0 ) {
04169
04170
04171
04172
04173
04174
04175
04176
04177 LocalMask = ((
PKNOWN_ACE)(OldAce))->Mask;
04178 RtlApplyGenericMask( OldAce, &LocalMask, GenericMapping);
04179
04180
if ( LocalMask != ((
PKNOWN_ACE)(OldAce))->Mask ) {
04181 *EffectiveAceMapped =
TRUE;
04182 }
04183
04184
04185
04186
04187
04188 LocalMask &= ( STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL | ACCESS_SYSTEM_SECURITY );
04189
04190
if (LocalMask == 0) {
04191
04192 LengthRequired = 0;
04193
04194 }
else {
04195
04196
04197
04198
04199
04200
04201
if (
RtlEqualPrefixSid ( SidToCopy,
CreatorSid )) {
04202
04203 Rid = *RtlpSubAuthoritySid( SidToCopy, 0 );
04204
04205
switch (Rid) {
04206
case SECURITY_CREATOR_OWNER_RID:
04207 SidToCopy = ClientOwnerSid;
04208 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(ClientOwnerSid);
04209 *EffectiveAceMapped =
TRUE;
04210
break;
04211
case SECURITY_CREATOR_GROUP_RID:
04212
if ( ClientGroupSid !=
NULL ) {
04213 SidToCopy = ClientGroupSid;
04214 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(ClientGroupSid);
04215 *EffectiveAceMapped =
TRUE;
04216 }
04217
break;
04218
case SECURITY_CREATOR_OWNER_SERVER_RID:
04219 SidToCopy = LocalServerOwner;
04220 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(LocalServerOwner);
04221 *EffectiveAceMapped =
TRUE;
04222
break;
04223
case SECURITY_CREATOR_GROUP_SERVER_RID:
04224 SidToCopy = LocalServerGroup;
04225 LengthRequired = LengthRequired -
CREATOR_SID_SIZE +
SeLengthSid(LocalServerGroup);
04226 *EffectiveAceMapped =
TRUE;
04227
break;
04228
default :
04229
04230
04231
04232
break;
04233 }
04234 }
04235
04236
04237
04238
04239
04240
04241
if ( *AcePosition ==
NULL ||
04242 LengthRequired > (ULONG)NewAcl->AclSize - ((PUCHAR)(*AcePosition) - (PUCHAR)NewAcl) ) {
04243 *AclOverflowed =
TRUE;
04244 }
else {
04245
04246 PUCHAR Target;
04247
04248
04249
04250
04251
04252 Target = (PUCHAR)*AcePosition;
04253
04254 RtlCopyMemory(
04255 Target,
04256 AceHeaderToCopy,
04257 AceHeaderToCopyLength );
04258
04259 Target += AceHeaderToCopyLength;
04260
04261
04262
04263
04264
04265
if ( ServerSidToCopy !=
NULL ) {
04266 RtlCopyMemory(
04267 Target,
04268 ServerSidToCopy,
04269
SeLengthSid(ServerSidToCopy)
04270 );
04271 Target +=
SeLengthSid(ServerSidToCopy);
04272 }
04273
04274
04275
04276
04277
04278 RtlCopyMemory(
04279 Target,
04280 SidToCopy,
04281
SeLengthSid(SidToCopy)
04282 );
04283 Target +=
SeLengthSid(SidToCopy);
04284
04285
04286
04287
04288
04289
if ( LengthRequired < (ULONG)(Target - (PUCHAR)*AcePosition) ) {
04290
return FALSE;
04291 }
04292 LengthRequired = (ULONG)(Target - (PUCHAR)*AcePosition);
04293 ((
PKNOWN_ACE)*AcePosition)->Header.AceSize =
04294 (
USHORT)LengthRequired;
04295
04296
04297
04298
04299
04300
04301 ((
PKNOWN_ACE)*AcePosition)->Mask = LocalMask;
04302
04303 }
04304 }
04305 }
04306
04307 }
else {
04308
04309
04310
04311
04312
04313
04314
if ( LengthRequired > (ULONG)NewAcl->AclSize - ((PUCHAR)*AcePosition - (PUCHAR)NewAcl) ) {
04315 *AclOverflowed =
TRUE;
04316 }
else {
04317
04318
04319
04320
04321
04322 RtlCopyMemory(
04323 *AcePosition,
04324 OldAce,
04325 LengthRequired );
04326 }
04327 }
04328
04329
04330
04331
04332
04333
04334
if ( !*AclOverflowed && LengthRequired != 0 ) {
04335 ((PACE_HEADER)*AcePosition)->AceFlags &= ~VALID_INHERIT_FLAGS;
04336
if ( AutoInherit ) {
04337 ((PACE_HEADER)*AcePosition)->AceFlags |= INHERITED_ACE;
04338 }
04339 NewAcl->AceCount += 1;
04340 }
04341
04342
04343
04344
04345
04346
04347
04348
if (LengthRequired > 0xFFFF) {
04349
return FALSE;
04350 }
04351
04352
04353
04354
04355
if ( !*AclOverflowed ) {
04356 *AcePosition = ((PUCHAR)*AcePosition) + LengthRequired;
04357 }
04358
04359
04360
04361
04362
04363 (*NewAceLength) = LengthRequired;
04364
04365
return TRUE;
04366 }
04367
04368
#ifndef WIN16
04369
04370
NTSTATUS
04371 RtlpCopyAces(
04372 IN PACL Acl,
04373 IN PGENERIC_MAPPING GenericMapping,
04374 IN ACE_TYPE_TO_COPY AceTypeToCopy,
04375 IN UCHAR AceFlagsToReset,
04376 IN BOOLEAN MapSids,
04377 IN PSID ClientOwnerSid,
04378 IN PSID ClientGroupSid,
04379 IN PSID ServerOwnerSid OPTIONAL,
04380 IN PSID ServerGroupSid OPTIONAL,
04381 OUT PULONG NewAclSizeParam,
04382 OUT PACL NewAcl
04383 )
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429 {
04430
04431
NTSTATUS Status;
04432 ULONG i;
04433
04434 PACE_HEADER OldAce;
04435 ULONG NewAclSize, NewAceSize;
04436 BOOLEAN AclOverflowed =
FALSE;
04437 BOOLEAN CopyAce;
04438 PVOID AcePosition;
04439
04440
04441
RTL_PAGED_CODE();
04442
04443
04444
04445
04446
04447
if ( !ValidAclRevision(NewAcl) ) {
04448
return STATUS_UNKNOWN_REVISION;
04449 }
04450
04451
04452
04453
04454
04455
if (!
RtlFirstFreeAce( NewAcl, &AcePosition )) {
04456
return STATUS_BAD_INHERITANCE_ACL;
04457 }
04458
04459
04460
04461
04462
04463 NewAclSize = 0;
04464
for (i = 0, OldAce =
FirstAce(Acl);
04465 i < Acl->AceCount;
04466 i += 1, OldAce =
NextAce(OldAce)) {
04467
04468
04469
04470
04471
04472
04473
switch (AceTypeToCopy) {
04474
case CopyInheritedAces:
04475 CopyAce = AceInherited(OldAce);
04476
break;
04477
case CopyNonInheritedAces:
04478 CopyAce = !AceInherited(OldAce);
04479
break;
04480
case CopyAllAces:
04481 CopyAce =
TRUE;
04482
break;
04483
default:
04484 CopyAce =
FALSE;
04485
break;
04486 }
04487
04488
if ( CopyAce ) {
04489
04490
04491
04492
04493
04494
04495
04496
if ( MapSids ) {
04497 PVOID TempAcePosition;
04498 ULONG EffectiveAceSize = 0;
04499
04500 BOOLEAN EffectiveAceMapped;
04501 BOOLEAN GenerateInheritAce;
04502
04503
04504
04505
04506
04507 TempAcePosition = AcePosition;
04508 NewAceSize = 0;
04509 GenerateInheritAce =
04510 (((PACE_HEADER)OldAce)->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) != 0;
04511
04512
04513
04514
04515
04516
04517
04518
if ( !(((PACE_HEADER)OldAce)->AceFlags & INHERIT_ONLY_ACE)) {
04519 BOOLEAN LocalAclOverflowed;
04520
04521
04522
04523
04524
if ( !
RtlpCopyEffectiveAce (
04525 OldAce,
04526
FALSE,
04527 GenerateInheritAce,
04528 ClientOwnerSid,
04529 ClientGroupSid,
04530 ServerOwnerSid,
04531 ServerGroupSid,
04532 GenericMapping,
04533
NULL,
04534 &TempAcePosition,
04535 &EffectiveAceSize,
04536 NewAcl,
04537
NULL,
04538 &EffectiveAceMapped,
04539 &LocalAclOverflowed ) ) {
04540
04541
return STATUS_BAD_INHERITANCE_ACL;
04542 }
04543
04544
if (LocalAclOverflowed) {
04545 AclOverflowed =
TRUE;
04546 }
04547 NewAceSize += EffectiveAceSize;
04548
04549
04550
04551
04552
04553
if ( !AclOverflowed ) {
04554 ((PACE_HEADER)AcePosition)->AceFlags &= ~AceFlagsToReset;
04555 }
04556
04557 }
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
if ( GenerateInheritAce ) {
04568
04569
04570
04571
04572
04573
04574
04575
04576
if ( EffectiveAceSize != 0 && !EffectiveAceMapped ) {
04577
04578
04579
04580
04581
if ( !AclOverflowed ) {
04582 ((PACE_HEADER)AcePosition)->AceFlags |=
04583 ((PACE_HEADER)OldAce)->AceFlags & (VALID_INHERIT_FLAGS);
04584 ((PACE_HEADER)AcePosition)->AceFlags &= ~AceFlagsToReset;
04585 }
04586
04587
04588
04589
04590
04591
04592
04593
04594 }
else if ( !IsMSAceType(OldAce) || ((
PKNOWN_ACE)(OldAce))->Mask != 0 ) {
04595
04596
04597
04598
04599 NewAceSize += (ULONG)(((PACE_HEADER)OldAce)->AceSize);
04600
04601
if (NewAceSize > 0xFFFF) {
04602
return STATUS_BAD_INHERITANCE_ACL;
04603 }
04604
04605
04606
04607
04608
04609
04610
if ( ((PACE_HEADER)OldAce)->AceSize > NewAcl->AclSize - ((PUCHAR)TempAcePosition - (PUCHAR)NewAcl) ) {
04611 AclOverflowed =
TRUE;
04612 }
else {
04613
04614
04615
04616
04617
04618
if ( !AclOverflowed ) {
04619 RtlCopyMemory(
04620 TempAcePosition,
04621 OldAce,
04622 ((PACE_HEADER)OldAce)->AceSize
04623 );
04624
04625 ((PACE_HEADER)TempAcePosition)->AceFlags |= INHERIT_ONLY_ACE;
04626 ((PACE_HEADER)TempAcePosition)->AceFlags &= ~AceFlagsToReset;
04627 NewAcl->AceCount += 1;
04628 }
04629 }
04630 }
04631
04632 }
04633
04634 }
else {
04635 NewAceSize = (ULONG)OldAce->AceSize;
04636
04637
04638
04639
04640
04641
04642
if ( AcePosition ==
NULL ||
04643 NewAceSize > (ULONG)NewAcl->AclSize - ((PUCHAR)AcePosition - (PUCHAR)NewAcl) ) {
04644 AclOverflowed =
TRUE;
04645 }
else if ( !AclOverflowed ) {
04646
04647
04648
04649
04650
04651
04652 RtlCopyMemory(
04653 AcePosition,
04654 OldAce,
04655 NewAceSize );
04656
04657
04658
04659
04660
04661
04662
04663
04664
if (IsMSAceType( AcePosition )) {
04665 RtlApplyAceToObject( (PACE_HEADER)AcePosition, GenericMapping );
04666 }
04667
04668
04669
04670
04671
04672 ((PACE_HEADER)AcePosition)->AceFlags &= ~AceFlagsToReset;
04673
04674
04675
04676
04677
04678 NewAcl->AceCount += 1;
04679 }
04680 }
04681
04682
04683
04684
04685
04686
if ( !AclOverflowed ) {
04687 AcePosition = ((PUCHAR)AcePosition) + NewAceSize;
04688 }
else {
04689
04690 AcePosition = ((PUCHAR)NewAcl) + NewAcl->AclSize;
04691 }
04692 NewAclSize += NewAceSize;
04693
04694 }
04695 }
04696
04697
04698
04699
04700
04701
04702
04703
04704
if (NewAclSize > 0xFFFF) {
04705
return STATUS_BAD_INHERITANCE_ACL;
04706 }
04707
04708 (*NewAclSizeParam) = NewAclSize;
04709
04710
return AclOverflowed ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
04711
04712 }
04713
04714
04715
NTSTATUS
04716 RtlpInheritAcl2 (
04717 IN PACL DirectoryAcl,
04718 IN PACL ChildAcl,
04719 IN ULONG ChildGenericControl,
04720 IN BOOLEAN IsDirectoryObject,
04721 IN BOOLEAN AutoInherit,
04722 IN BOOLEAN DefaultDescriptorForObject,
04723 IN PSID OwnerSid,
04724 IN PSID GroupSid,
04725 IN PSID ServerOwnerSid OPTIONAL,
04726 IN PSID ServerGroupSid OPTIONAL,
04727 IN PGENERIC_MAPPING GenericMapping,
04728 IN BOOLEAN IsSacl,
04729 IN GUID *NewObjectType OPTIONAL,
04730 IN PULONG AclBufferSize,
04731 IN OUT PUCHAR AclBuffer,
04732 OUT PBOOLEAN NewAclExplicitlyAssigned,
04733 OUT PULONG NewGenericControl
04734 )
04735
04736
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773
04774
04775
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814
04815
04816
04817
04818
04819
04820
04821
04822
04823
04824
04825
04826 {
04827
NTSTATUS Status;
04828 ULONG ChildNewAclSize = 0;
04829 ULONG UsedChildNewAclSize = 0;
04830 ULONG DirectoryNewAclSize = 0;
04831 ULONG AclRevision;
04832
USHORT ChildAceCount;
04833 PVOID ChildAcePosition;
04834 PVOID DirectoryAcePosition;
04835 BOOLEAN AclOverflowed =
FALSE;
04836 BOOLEAN AclProtected =
FALSE;
04837 BOOLEAN NullAclOk =
TRUE;
04838 BOOLEAN ObjectAceInherited;
04839
04840
RTL_PAGED_CODE();
04841
04842
04843
04844
04845
04846
04847 AclRevision = ACL_REVISION;
04848
RtlCreateAcl( (PACL)AclBuffer, *AclBufferSize, AclRevision );
04849 *NewAclExplicitlyAssigned =
FALSE;
04850 *NewGenericControl = AutoInherit ? SEP_ACL_AUTO_INHERITED : 0;
04851
04852
04853
04854
04855
04856
04857
if ( (ChildGenericControl & SEP_ACL_DEFAULTED) == 0 ) {
04858
04859
04860
04861
04862
04863
04864
if ( ChildGenericControl & SEP_ACL_PROTECTED ) {
04865 AclProtected =
TRUE;
04866 *NewGenericControl |= SEP_ACL_PROTECTED;
04867 }
04868
04869
04870
04871
04872
if ( (ChildGenericControl & (SEP_ACL_PRESENT|SEP_ACL_PROTECTED)) != 0 ) {
04873
04874
04875
if ( ChildAcl !=
NULL ) {
04876
ACE_TYPE_TO_COPY AceTypeToCopy;
04877 UCHAR AceFlagsToReset;
04878 BOOLEAN MapSids;
04879
04880
04881 AclRevision =
max( AclRevision, ChildAcl->AclRevision );
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892 NullAclOk =
FALSE;
04893
04894
04895
04896
04897
04898
if ( !AutoInherit ) {
04899
04900 AceTypeToCopy =
CopyAllAces;
04901 AceFlagsToReset = 0;
04902 MapSids =
FALSE;
04903
04904
04905
04906
04907
04908 }
else if ( ChildGenericControl & SEP_ACL_PROTECTED ) {
04909
04910 AceTypeToCopy =
CopyAllAces;
04911 AceFlagsToReset = INHERITED_ACE;
04912 MapSids =
TRUE;
04913
04914
04915
04916
04917
04918
04919
04920 }
else {
04921
04922 AceTypeToCopy =
CopyNonInheritedAces;
04923 AceFlagsToReset = 0;
04924 MapSids =
TRUE;
04925
04926 }
04927
04928
04929
04930
04931
04932
Status =
RtlpCopyAces(
04933 ChildAcl,
04934 GenericMapping,
04935 AceTypeToCopy,
04936 AceFlagsToReset,
04937 MapSids,
04938 OwnerSid,
04939 GroupSid,
04940 ServerOwnerSid,
04941 ServerGroupSid,
04942 &ChildNewAclSize,
04943 (PACL)AclBuffer );
04944
04945 UsedChildNewAclSize = ChildNewAclSize;
04946
if (
Status == STATUS_BUFFER_TOO_SMALL ) {
04947 AclOverflowed =
TRUE;
04948
Status = STATUS_SUCCESS;
04949 }
04950
04951
if ( !
NT_SUCCESS(
Status) ) {
04952
return Status;
04953 }
04954
04955
04956
04957
04958
04959
04960
if ( DefaultDescriptorForObject && ChildNewAclSize != 0 ) {
04961 ChildAceCount = ((PACL)AclBuffer)->AceCount;
04962
04963
if (!
RtlFirstFreeAce( (PACL)AclBuffer, &ChildAcePosition ) ) {
04964
return STATUS_BAD_INHERITANCE_ACL;
04965 }
04966 }
04967
04968
04969
04970
04971
04972
04973 }
else if ( AutoInherit &&
04974 !IsSacl &&
04975 (ChildGenericControl & (SEP_ACL_PRESENT|SEP_ACL_PROTECTED)) == SEP_ACL_PRESENT ) {
04976
return STATUS_INVALID_ACL;
04977
04978 }
04979
04980 *NewAclExplicitlyAssigned =
TRUE;
04981
04982 }
04983
04984 }
04985
04986
04987
04988
04989
04990
04991
04992
04993
04994
if ( (!AutoInherit &&
04995 (ChildGenericControl & SEP_ACL_PRESENT) == 0 ||
04996 (ChildGenericControl & SEP_ACL_DEFAULTED) != 0) ||
04997 (AutoInherit && !AclProtected) ) {
04998
04999
05000
05001
05002
05003
05004
if ( DirectoryAcl !=
NULL ) {
05005
05006
05007
05008
05009
05010
05011
if ( !ValidAclRevision(DirectoryAcl) ) {
05012
return STATUS_UNKNOWN_REVISION;
05013 }
05014
05015 AclRevision =
max( AclRevision, DirectoryAcl->AclRevision );
05016
05017
05018
05019
05020
05021
Status =
RtlpGenerateInheritAcl(
05022 DirectoryAcl,
05023 IsDirectoryObject,
05024 AutoInherit,
05025 OwnerSid,
05026 GroupSid,
05027 ServerOwnerSid,
05028 ServerGroupSid,
05029 GenericMapping,
05030 NewObjectType,
05031 &DirectoryNewAclSize,
05032 (PACL)AclBuffer,
05033 &ObjectAceInherited );
05034
05035
if (
Status == STATUS_BUFFER_TOO_SMALL ) {
05036 AclOverflowed =
TRUE;
05037
Status = STATUS_SUCCESS;
05038 }
05039
05040
if ( !
NT_SUCCESS(
Status) ) {
05041
return Status;
05042 }
05043
05044
05045
05046
05047
05048
05049
05050
if ( DefaultDescriptorForObject &&
05051 ChildNewAclSize != 0 &&
05052 ObjectAceInherited &&
05053 !AclOverflowed ) {
05054
05055
05056
05057
05058
if (!
RtlFirstFreeAce( (PACL)AclBuffer, &DirectoryAcePosition ) ) {
05059
return STATUS_BAD_INHERITANCE_ACL;
05060 }
05061
if ( DirectoryAcePosition ==
NULL ) {
05062 DirectoryAcePosition = AclBuffer + ((PACL)AclBuffer)->AclSize;
05063 }
05064
05065
05066
05067
05068
05069
05070
05071 RtlMoveMemory(
FirstAce( AclBuffer ),
05072 ChildAcePosition,
05073 (ULONG)(((PUCHAR)DirectoryAcePosition) -
05074 (PUCHAR)ChildAcePosition) );
05075
05076
05077
05078
05079
05080 ((PACL)AclBuffer)->AceCount -= ChildAceCount;
05081
05082
05083
05084
05085
05086
05087 UsedChildNewAclSize = 0;
05088
05089 }
05090 }
05091
05092 }
05093
05094
05095
05096
05097
05098
05099
if ( DirectoryNewAclSize + UsedChildNewAclSize == 0) {
05100
05101
05102
05103
05104
05105
if ( !(*NewAclExplicitlyAssigned) ) {
05106 *AclBufferSize = 0;
05107
return STATUS_NO_INHERITANCE;
05108
05109
05110
05111
05112
05113
05114 }
else if ( NullAclOk ) {
05115 *AclBufferSize = 0;
05116
return STATUS_SUCCESS;
05117 }
05118
05119
05120 }
05121
05122
05123
05124
05125
05126
05127
if ( DirectoryNewAclSize + UsedChildNewAclSize +
sizeof(ACL) > 0xFFFF) {
05128
return(STATUS_BAD_INHERITANCE_ACL);
05129 }
05130
05131
05132
05133
05134 (*AclBufferSize) = DirectoryNewAclSize + ChildNewAclSize +
sizeof(ACL);
05135
05136
if ( AclOverflowed ) {
05137
return STATUS_BUFFER_TOO_SMALL;
05138 }
05139
05140
05141
05142
05143
05144 ((PACL)AclBuffer)->AclSize = (
USHORT)
05145 (DirectoryNewAclSize + UsedChildNewAclSize +
sizeof(ACL));
05146 ((PACL)AclBuffer)->AclRevision = (UCHAR) AclRevision;
05147
05148
return STATUS_SUCCESS;
05149 }
05150
05151
05152
NTSTATUS
05153 RtlpInheritAcl (
05154 IN PACL DirectoryAcl,
05155 IN PACL ChildAcl,
05156 IN ULONG ChildGenericControl,
05157 IN BOOLEAN IsDirectoryObject,
05158 IN BOOLEAN AutoInherit,
05159 IN BOOLEAN DefaultDescriptorForObject,
05160 IN PSID OwnerSid,
05161 IN PSID GroupSid,
05162 IN PSID ServerOwnerSid OPTIONAL,
05163 IN PSID ServerGroupSid OPTIONAL,
05164 IN PGENERIC_MAPPING GenericMapping,
05165 IN BOOLEAN IsSacl,
05166 IN GUID *NewObjectType OPTIONAL,
05167 OUT PACL *NewAcl,
05168 OUT PBOOLEAN NewAclExplicitlyAssigned,
05169 OUT PULONG NewGenericControl
05170 )
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244
05245
05246
05247
05248
05249
05250
05251
05252
05253
05254 {
05256
05257
05258
05259
05260
05262
05263
05264
05265
NTSTATUS Status;
05266 ULONG AclBufferSize;
05267 ULONG i;
05268
05269
#ifndef NTOS_KERNEL_RUNTIME
05270
PVOID
HeapHandle;
05271
#endif // NTOS_KERNEL_RUNTIME
05272
05273
RTL_PAGED_CODE();
05274
05275
05276
05277
05278
05279
#ifndef NTOS_KERNEL_RUNTIME
05280
HeapHandle = RtlProcessHeap();
05281
#endif // NTOS_KERNEL_RUNTIME
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291
05292
05293 AclBufferSize = 1024;
05294
for ( i=0; i<2 ; i++ ) {
05295
05296
05297
05298
05299
05300
#ifdef NTOS_KERNEL_RUNTIME
05301
(*NewAcl) =
ExAllocatePoolWithTag(
05302
PagedPool,
05303 AclBufferSize,
05304 'cAeS' );
05305
#else // NTOS_KERNEL_RUNTIME
05306
(*NewAcl) =
RtlAllocateHeap(
05307
HeapHandle,
05308
MAKE_TAG(
SE_TAG),
05309 AclBufferSize );
05310
#endif // NTOS_KERNEL_RUNTIME
05311
05312
if ((*NewAcl) ==
NULL ) {
05313
return( STATUS_NO_MEMORY );
05314 }
05315
05316
05317
05318
05319
05320
Status =
RtlpInheritAcl2 (
05321 DirectoryAcl,
05322 ChildAcl,
05323 ChildGenericControl,
05324 IsDirectoryObject,
05325 AutoInherit,
05326 DefaultDescriptorForObject,
05327 OwnerSid,
05328 GroupSid,
05329 ServerOwnerSid,
05330 ServerGroupSid,
05331 GenericMapping,
05332 IsSacl,
05333 NewObjectType,
05334 &AclBufferSize,
05335 (PUCHAR) *NewAcl,
05336 NewAclExplicitlyAssigned,
05337 NewGenericControl );
05338
05339
05340
if (
NT_SUCCESS(
Status) ) {
05341
05342
05343
05344
05345
05346
05347
if ( AclBufferSize == 0 ) {
05348
05349
#ifdef NTOS_KERNEL_RUNTIME
05350
ExFreePool( *NewAcl );
05351
#else // NTOS_KERNEL_RUNTIME
05352
RtlFreeHeap(
HeapHandle, 0, *NewAcl );
05353
#endif // NTOS_KERNEL_RUNTIME
05354
05355 *NewAcl =
NULL;
05356 }
05357
05358
break;
05359
05360 }
else {
05361
#ifdef NTOS_KERNEL_RUNTIME
05362
ExFreePool( *NewAcl );
05363
#else // NTOS_KERNEL_RUNTIME
05364
RtlFreeHeap(
HeapHandle, 0, *NewAcl );
05365
#endif // NTOS_KERNEL_RUNTIME
05366
05367 *NewAcl =
NULL;
05368
05369
if (
Status != STATUS_BUFFER_TOO_SMALL ) {
05370
break;
05371 }
05372 }
05373 }
05374
05375
05376
return Status;
05377 }
05378
05379
05380
NTSTATUS
05381 RtlpGenerateInheritedAce (
05382 IN PACE_HEADER OldAce,
05383 IN BOOLEAN IsDirectoryObject,
05384 IN BOOLEAN AutoInherit,
05385 IN PSID ClientOwnerSid,
05386 IN PSID ClientGroupSid,
05387 IN PSID ServerOwnerSid OPTIONAL,
05388 IN PSID ServerGroupSid OPTIONAL,
05389 IN PGENERIC_MAPPING GenericMapping,
05390 IN GUID *NewObjectType OPTIONAL,
05391 OUT PULONG NewAceLength,
05392 OUT PACL NewAcl,
05393 OUT PULONG NewAceExtraLength,
05394 OUT PBOOLEAN ObjectAceInherited
05395 )
05396
05397
05398
05399
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413
05414
05415
05416
05417
05418
05419
05420
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451
05452 {
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476
05477
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514
05516
05517
05518
05519 ULONG LengthRequired = 0;
05520 ULONG ExtraLengthRequired = 0;
05521 PVOID AcePosition;
05522 PVOID EffectiveAcePosition;
05523 ULONG EffectiveAceSize = 0;
05524
05525 BOOLEAN EffectiveAceMapped;
05526 BOOLEAN AclOverflowed =
FALSE;
05527 BOOLEAN GenerateInheritAce;
05528
05529
RTL_PAGED_CODE();
05530
05531
05532
05533
05534
05535
05536
05537
ASSERT(
RtlLengthRequiredSid( 1 ) ==
CREATOR_SID_SIZE);
05538 *ObjectAceInherited =
FALSE;
05539 GenerateInheritAce = IsDirectoryObject && Propagate(OldAce);
05540
05541
05542
05543
05544
05545
05546
if (!
RtlFirstFreeAce( NewAcl, &AcePosition ) ) {
05547
return STATUS_BAD_INHERITANCE_ACL;
05548 }
05549
05550
05551
05552
05553
05554
05555
if ( (IsDirectoryObject && ContainerInherit(OldAce)) ||
05556 (!IsDirectoryObject && ObjectInherit(OldAce)) ) {
05557
05558
05559
05560
05561
05562 EffectiveAcePosition = AcePosition;
05563
05564
05565
05566
05567
if ( !
RtlpCopyEffectiveAce (
05568 OldAce,
05569 AutoInherit,
05570 GenerateInheritAce,
05571 ClientOwnerSid,
05572 ClientGroupSid,
05573 ServerOwnerSid,
05574 ServerGroupSid,
05575 GenericMapping,
05576 NewObjectType,
05577 &AcePosition,
05578 &EffectiveAceSize,
05579 NewAcl,
05580 ObjectAceInherited,
05581 &EffectiveAceMapped,
05582 &AclOverflowed ) ) {
05583
05584
return STATUS_BAD_INHERITANCE_ACL;
05585 }
05586
05587
05588
05589
05590
05591
05592
if ( !AclOverflowed &&
05593 EffectiveAceSize > 0 &&
05594 EffectiveAcePosition !=
NULL &&
05595
RtlpIsDuplicateAce(
05596 NewAcl,
05597 EffectiveAcePosition,
05598 NewObjectType ) ) {
05599
05600
05601
05602
05603
05604
05605 NewAcl->AceCount--;
05606 AcePosition = EffectiveAcePosition;
05607 ExtraLengthRequired =
max( ExtraLengthRequired, EffectiveAceSize );
05608 EffectiveAceSize = 0;
05609 }
05610
05611 LengthRequired += EffectiveAceSize;
05612
05613 }
05614
05615
05616
05617
05618
05619
05620
if ( GenerateInheritAce ) {
05621
05622
05623
05624
05625
05626
05627
05628
05629
if ( EffectiveAceSize != 0 && !EffectiveAceMapped ) {
05630
05631
05632
05633
05634
if ( !AclOverflowed ) {
05635 ((PACE_HEADER)EffectiveAcePosition)->AceFlags |=
05636 ((PACE_HEADER)OldAce)->AceFlags & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
05637
if ( AutoInherit ) {
05638 ((PACE_HEADER)EffectiveAcePosition)->AceFlags |= INHERITED_ACE;
05639 }
05640 }
05641
05642
05643
05644
05645
05646
05647
05648
05649 }
else if ( !IsMSAceType(OldAce) || ((
PKNOWN_ACE)(OldAce))->Mask != 0 ) {
05650
05651
05652
05653
05654 LengthRequired += (ULONG)(((PACE_HEADER)OldAce)->AceSize);
05655
05656
if (LengthRequired > 0xFFFF) {
05657
return STATUS_BAD_INHERITANCE_ACL;
05658 }
05659
05660
05661
05662
05663
05664
05665
if ( ((PACE_HEADER)OldAce)->AceSize > NewAcl->AclSize - ((PUCHAR)AcePosition - (PUCHAR)NewAcl) ) {
05666 AclOverflowed =
TRUE;
05667 }
else if (!AclOverflowed){
05668
05669
05670
05671
05672
05673 RtlCopyMemory(
05674 AcePosition,
05675 OldAce,
05676 ((PACE_HEADER)OldAce)->AceSize
05677 );
05678
05679 ((PACE_HEADER)AcePosition)->AceFlags |= INHERIT_ONLY_ACE;
05680 NewAcl->AceCount += 1;
05681
if ( AutoInherit ) {
05682 ((PACE_HEADER)AcePosition)->AceFlags |= INHERITED_ACE;
05683
05684
05685
05686
05687
05688
05689
if (
RtlpIsDuplicateAce(
05690 NewAcl,
05691 AcePosition,
05692 NewObjectType ) ) {
05693
05694
05695
05696
05697
05698
05699 NewAcl->AceCount--;
05700 ExtraLengthRequired =
max( ExtraLengthRequired,
05701 ((PACE_HEADER)OldAce)->AceSize );
05702 LengthRequired -= (ULONG)(((PACE_HEADER)OldAce)->AceSize);
05703 }
05704 }
05705
05706 }
05707 }
05708 }
05709
05710
05711
05712
05713
05714 (*NewAceLength) = LengthRequired;
05715 (*NewAceExtraLength) = ExtraLengthRequired;
05716
05717
return AclOverflowed ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
05718 }
05719
05720
05721
NTSTATUS
05722 RtlpGenerateInheritAcl(
05723 IN PACL Acl,
05724 IN BOOLEAN IsDirectoryObject,
05725 IN BOOLEAN AutoInherit,
05726 IN PSID ClientOwnerSid,
05727 IN PSID ClientGroupSid,
05728 IN PSID ServerOwnerSid OPTIONAL,
05729 IN PSID ServerGroupSid OPTIONAL,
05730 IN PGENERIC_MAPPING GenericMapping,
05731 IN GUID *NewObjectType OPTIONAL,
05732 OUT PULONG NewAclSizeParam,
05733 OUT PACL NewAcl,
05734 OUT PBOOLEAN ObjectAceInherited
05735 )
05736
05737
05738
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780
05781
05782
05783
05784
05785
05786
05787
05788
05789 {
05790
05791
NTSTATUS Status;
05792 ULONG i;
05793
05794 PACE_HEADER OldAce;
05795 ULONG NewAclSize, NewAceSize;
05796 ULONG NewAclExtraSize, NewAceExtraSize;
05797 BOOLEAN AclOverflowed =
FALSE;
05798 BOOLEAN LocalObjectAceInherited;
05799
05800
05801
RTL_PAGED_CODE();
05802
05803
05804
05805
05806
05807
05808 NewAclSize = 0;
05809 NewAclExtraSize = 0;
05810 *ObjectAceInherited =
FALSE;
05811
for (i = 0, OldAce =
FirstAce(Acl);
05812 i < Acl->AceCount;
05813 i += 1, OldAce =
NextAce(OldAce)) {
05814
05815
05816
05817
05818
05819
05820
Status =
RtlpGenerateInheritedAce(
05821 OldAce,
05822 IsDirectoryObject,
05823 AutoInherit,
05824 ClientOwnerSid,
05825 ClientGroupSid,
05826 ServerOwnerSid,
05827 ServerGroupSid,
05828 GenericMapping,
05829 NewObjectType,
05830 &NewAceSize,
05831 NewAcl,
05832 &NewAceExtraSize,
05833 &LocalObjectAceInherited
05834 );
05835
05836
if (
Status == STATUS_BUFFER_TOO_SMALL ) {
05837 AclOverflowed =
TRUE;
05838
Status = STATUS_SUCCESS;
05839 }
05840
05841
if ( !
NT_SUCCESS(
Status) ) {
05842
return Status;
05843 }
05844
05845
if ( LocalObjectAceInherited ) {
05846 *ObjectAceInherited =
TRUE;
05847 }
05848
05849
05850
05851
05852 NewAclSize += NewAceSize;
05853
05854
05855
05856
05857
05858
05859
05860
if ( NewAceSize > NewAclExtraSize ) {
05861 NewAclExtraSize = 0 ;
05862 }
else {
05863 NewAclExtraSize -= NewAceSize;
05864 }
05865
05866
05867
05868
05869
05870 NewAclExtraSize =
max( NewAclExtraSize, NewAceExtraSize );
05871
05872 }
05873
05874
05875
05876
05877
05878
05879
05880
05881
if ( AclOverflowed ) {
05882 (*NewAclSizeParam) = NewAclSize + NewAclExtraSize;
05883
return STATUS_BUFFER_TOO_SMALL;
05884 }
else {
05885 (*NewAclSizeParam) = NewAclSize;
05886
return STATUS_SUCCESS;
05887 }
05888
05889 }
05890
05891
05892
NTSTATUS
05893 RtlpComputeMergedAcl2 (
05894 IN PACL CurrentAcl,
05895 IN ULONG CurrentGenericControl,
05896 IN PACL ModificationAcl,
05897 IN ULONG ModificationGenericControl,
05898 IN PSID ClientOwnerSid,
05899 IN PSID ClientGroupSid,
05900 IN PGENERIC_MAPPING GenericMapping,
05901 IN BOOLEAN IsSacl,
05902 IN PULONG AclBufferSize,
05903 IN OUT PUCHAR AclBuffer,
05904 OUT PULONG NewGenericControl
05905 )
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923
05924
05925
05926
05927
05928
05929
05930
05931
05932
05933
05934
05935
05936
05937
05938
05939
05940
05941
05942
05943
05944
05945
05946
05947
05948
05949
05950
05951
05952
05953
05954
05955
05956
05957
05958
05959
05960
05961
05962
05963
05964
05965
05966
05967
05968
05969
05970
05971
05972
05973 {
05974
NTSTATUS Status;
05975 ULONG ModificationNewAclSize = 0;
05976 ULONG CurrentNewAclSize = 0;
05977 ULONG AclRevision;
05978 BOOLEAN AclOverflowed =
FALSE;
05979 BOOLEAN NullAclOk =
TRUE;
05980
05981
RTL_PAGED_CODE();
05982
05983
05984
05985
05986
05987
05988 AclRevision = ACL_REVISION;
05989
RtlCreateAcl( (PACL)AclBuffer, *AclBufferSize, AclRevision );
05990
05991
05992
05993
05994
05995 *NewGenericControl = SEP_ACL_AUTO_INHERITED;
05996
05997
05998
05999
06000
06001
06002
if ( (ModificationGenericControl & SEP_ACL_PROTECTED) != 0 ) {
06003
06004
06005
06006
06007
06008 *NewGenericControl |= SEP_ACL_PROTECTED;
06009
06010
06011
06012
06013
06014
if ( ModificationAcl !=
NULL ) {
06015
06016 AclRevision =
max( AclRevision, ModificationAcl->AclRevision );
06017
06018
06019
06020
06021
06022
Status =
RtlpCopyAces(
06023 ModificationAcl,
06024 GenericMapping,
06025
CopyAllAces,
06026 INHERITED_ACE,
06027
TRUE,
06028 ClientOwnerSid,
06029 ClientGroupSid,
06030 ClientOwnerSid,
06031 ClientGroupSid,
06032 &ModificationNewAclSize,
06033 (PACL)AclBuffer );
06034
06035
if (
Status == STATUS_BUFFER_TOO_SMALL ) {
06036 AclOverflowed =
TRUE;
06037
Status = STATUS_SUCCESS;
06038 }
06039
06040
if ( !
NT_SUCCESS(
Status) ) {
06041
return Status;
06042 }
06043
06044
06045
06046
06047
06048
06049 NullAclOk =
FALSE;
06050 }
06051
06052
06053
06054
06055
06056
06057
06058
06059 }
else if ( (CurrentGenericControl & SEP_ACL_PROTECTED) != 0 ) {
06060
06061
06062
06063
06064
06065
if ( ModificationAcl !=
NULL ) {
06066 AclRevision =
max( AclRevision, ModificationAcl->AclRevision );
06067
06068
06069
06070
06071
06072
Status =
RtlpCopyAces(
06073 ModificationAcl,
06074 GenericMapping,
06075
CopyAllAces,
06076 0,
06077
TRUE,
06078 ClientOwnerSid,
06079 ClientGroupSid,
06080 ClientOwnerSid,
06081 ClientGroupSid,
06082 &ModificationNewAclSize,
06083 (PACL)AclBuffer );
06084
06085
if (
Status == STATUS_BUFFER_TOO_SMALL ) {
06086 AclOverflowed =
TRUE;
06087
Status = STATUS_SUCCESS;
06088 }
06089
06090
if ( !
NT_SUCCESS(
Status) ) {
06091
return Status;
06092 }
06093
06094
06095
06096
06097
06098
06099 NullAclOk =
FALSE;
06100
06101
06102
06103
06104
06105
06106 }
else if ( !IsSacl ) {
06107
return STATUS_INVALID_ACL;
06108 }
06109
06110
06111
06112
06113
06114
06115
06116
06117 }
else {
06118
06119
06120
06121
06122
06123
06124 NullAclOk = IsSacl;
06125
06126
06127
06128
06129
06130
06131
if ( ModificationAcl !=
NULL ) {
06132 AclRevision =
max( AclRevision, ModificationAcl->AclRevision );
06133
06134
06135
06136
06137
06138
Status =
RtlpCopyAces(
06139 ModificationAcl,
06140 GenericMapping,
06141
CopyNonInheritedAces,
06142 0,
06143
TRUE,
06144 ClientOwnerSid,
06145 ClientGroupSid,
06146 ClientOwnerSid,
06147 ClientGroupSid,
06148 &ModificationNewAclSize,
06149 (PACL)AclBuffer );
06150
06151
if (
Status == STATUS_BUFFER_TOO_SMALL ) {
06152 AclOverflowed =
TRUE;
06153
Status = STATUS_SUCCESS;
06154 }
06155
06156
if ( !
NT_SUCCESS(
Status) ) {
06157
return Status;
06158 }
06159
06160
06161
06162
06163
06164
06165
06166
06167
06168
if ( ModificationAcl->AceCount == 0 ) {
06169 NullAclOk =
FALSE;
06170 }
06171
06172
06173
06174
06175
06176
06177 }
else if ( !IsSacl ) {
06178
return STATUS_INVALID_ACL;
06179 }
06180
06181
06182
06183
06184
06185
06186
if ( CurrentAcl !=
NULL ) {
06187
06188 AclRevision =
max( AclRevision, CurrentAcl->AclRevision );
06189
06190
06191
06192
06193
06194
06195
06196
06197
06198
Status =
RtlpCopyAces(
06199 CurrentAcl,
06200 GenericMapping,
06201
CopyInheritedAces,
06202 0,
06203
FALSE,
06204
NULL,
06205
NULL,
06206
NULL,
06207
NULL,
06208 &CurrentNewAclSize,
06209 (PACL)AclBuffer );
06210
06211
if (
Status == STATUS_BUFFER_TOO_SMALL ) {
06212 AclOverflowed =
TRUE;
06213
Status = STATUS_SUCCESS;
06214 }
06215
06216
if ( !
NT_SUCCESS(
Status) ) {
06217
return Status;
06218 }
06219 }
06220 }
06221
06222
06223
06224
06225
06226
06227
if ( ModificationNewAclSize + CurrentNewAclSize == 0) {
06228
06229
06230
06231
06232
06233
if ( NullAclOk ) {
06234 *AclBufferSize = 0;
06235
return STATUS_SUCCESS;
06236 }
06237 }
06238
06239
06240
06241
06242
06243
06244
if ( ModificationNewAclSize + CurrentNewAclSize +
sizeof(ACL) > 0xFFFF) {
06245
return(STATUS_BAD_INHERITANCE_ACL);
06246 }
06247
06248 (*AclBufferSize) = ModificationNewAclSize + CurrentNewAclSize +
sizeof(ACL);
06249
06250
if ( AclOverflowed ) {
06251
return STATUS_BUFFER_TOO_SMALL;
06252 }
06253
06254
06255
06256
06257
06258 ((PACL)AclBuffer)->AclSize = (
USHORT) *AclBufferSize;
06259 ((PACL)AclBuffer)->AclRevision = (UCHAR) AclRevision;
06260
06261
return STATUS_SUCCESS;
06262 }
06263
06264
06265
NTSTATUS
06266 RtlpComputeMergedAcl (
06267 IN PACL CurrentAcl,
06268 IN ULONG CurrentGenericControl,
06269 IN PACL ModificationAcl,
06270 IN ULONG ModificationGenericControl,
06271 IN PSID ClientOwnerSid,
06272 IN PSID ClientGroupSid,
06273 IN PGENERIC_MAPPING GenericMapping,
06274 IN BOOLEAN IsSacl,
06275 OUT PACL *NewAcl,
06276 OUT PULONG NewGenericControl
06277 )
06278
06279
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293
06294
06295
06296
06297
06298
06299
06300
06301
06302
06303
06304
06305
06306
06307
06308
06309
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
06320
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336
06337
06338
06339 {
06340
NTSTATUS Status;
06341 ULONG AclBufferSize;
06342 ULONG i;
06343
#ifndef NTOS_KERNEL_RUNTIME
06344
PVOID
HeapHandle;
06345
#endif // NTOS_KERNEL_RUNTIME
06346
06347
RTL_PAGED_CODE();
06348
06349
06350
06351
06352
06353
#ifndef NTOS_KERNEL_RUNTIME
06354
HeapHandle = RtlProcessHeap();
06355
#endif // NTOS_KERNEL_RUNTIME
06356
06357
06358
06359
06360
06361
06362
06363
06364
06365
06366 AclBufferSize = 1024;
06367
for ( i=0; i<2 ; i++ ) {
06368
06369
06370
06371
06372
06373
#ifdef NTOS_KERNEL_RUNTIME
06374
(*NewAcl) =
ExAllocatePoolWithTag(
06375
PagedPool,
06376 AclBufferSize,
06377 'cAeS' );
06378
#else // NTOS_KERNEL_RUNTIME
06379
(*NewAcl) =
RtlAllocateHeap(
HeapHandle, 0, AclBufferSize );
06380
#endif // NTOS_KERNEL_RUNTIME
06381
if ((*NewAcl) ==
NULL ) {
06382
return( STATUS_NO_MEMORY );
06383 }
06384
06385
06386
06387
06388
06389
Status =
RtlpComputeMergedAcl2 (
06390 CurrentAcl,
06391 CurrentGenericControl,
06392 ModificationAcl,
06393 ModificationGenericControl,
06394 ClientOwnerSid,
06395 ClientGroupSid,
06396 GenericMapping,
06397 IsSacl,
06398 &AclBufferSize,
06399 (PUCHAR) *NewAcl,
06400 NewGenericControl );
06401
06402
06403
if (
NT_SUCCESS(
Status) ) {
06404
06405
06406
06407
06408
06409
06410
if ( AclBufferSize == 0 ) {
06411
#ifdef NTOS_KERNEL_RUNTIME
06412
ExFreePool( *NewAcl );
06413
#else // NTOS_KERNEL_RUNTIME
06414
RtlFreeHeap(
HeapHandle, 0, *NewAcl );
06415
#endif // NTOS_KERNEL_RUNTIME
06416
*NewAcl =
NULL;
06417 }
06418
06419
break;
06420
06421 }
else {
06422
#ifdef NTOS_KERNEL_RUNTIME
06423
ExFreePool( *NewAcl );
06424
#else // NTOS_KERNEL_RUNTIME
06425
RtlFreeHeap(
HeapHandle, 0, *NewAcl );
06426
#endif // NTOS_KERNEL_RUNTIME
06427
*NewAcl =
NULL;
06428
06429
if (
Status != STATUS_BUFFER_TOO_SMALL ) {
06430
break;
06431 }
06432 }
06433 }
06434
06435
06436
return Status;
06437 }
06438
06439
#endif // WIN16
06440
06441
#if DBG
06442
NTSTATUS
06443 RtlDumpUserSid(
06444 VOID
06445 )
06446 {
06447
NTSTATUS Status;
06448 HANDLE TokenHandle;
06449
CHAR Buffer[200];
06450 ULONG ReturnLength;
06451 PSID pSid;
06452 UNICODE_STRING SidString;
06453 PTOKEN_USER User;
06454
06455
06456
06457
06458
06459
Status =
NtOpenThreadToken(
06460 NtCurrentThread(),
06461 GENERIC_READ,
06462 FALSE,
06463 &TokenHandle
06464 );
06465
06466
if (!
NT_SUCCESS( Status )) {
06467
06468
DbgPrint(
"Not impersonating, status = %X, trying process token\n",Status);
06469
06470
Status =
NtOpenProcessToken(
06471 NtCurrentProcess(),
06472 GENERIC_READ,
06473 &TokenHandle
06474 );
06475
06476
if (!
NT_SUCCESS( Status )) {
06477
DbgPrint(
"Unable to open process token, status = %X\n",Status);
06478
return(
Status );
06479 }
06480 }
06481
06482
Status =
NtQueryInformationToken (
06483 TokenHandle,
06484 TokenUser,
06485 Buffer,
06486 200,
06487 &ReturnLength
06488 );
06489
06490
if (!
NT_SUCCESS( Status )) {
06491
06492
DbgPrint(
"Unable to query user sid, status = %X \n",Status);
06493
NtClose(TokenHandle);
06494
return(
Status );
06495 }
06496
06497 User = (PTOKEN_USER)
Buffer;
06498
06499 pSid = User->User.Sid;
06500
06501
Status =
RtlConvertSidToUnicodeString( &SidString, pSid, TRUE );
06502
06503
if (!
NT_SUCCESS( Status )) {
06504
DbgPrint(
"Unable to format sid string, status = %X \n",Status);
06505
NtClose(TokenHandle);
06506
return(
Status );
06507 }
06508
06509
DbgPrint(
"Current Sid = %wZ \n",&SidString);
06510
06511
RtlFreeUnicodeString( &SidString );
06512
06513
return( STATUS_SUCCESS );
06514 }
06515
06516
#endif
06517
06518
06519
NTSTATUS
06520 RtlpConvertToAutoInheritSecurityObject(
06521 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
06522 IN PSECURITY_DESCRIPTOR CurrentSecurityDescriptor,
06523 OUT PSECURITY_DESCRIPTOR *NewSecurityDescriptor,
06524 IN GUID *ObjectType OPTIONAL,
06525 IN BOOLEAN IsDirectoryObject,
06526 IN PGENERIC_MAPPING GenericMapping
06527 )
06528
06529
06530
06531
06532
06533
06534
06535
06536
06537
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555
06556
06557
06558
06559
06560
06561
06562
06563
06564
06565
06566
06567
06568
06569
06570
06571 {
06572
NTSTATUS Status;
06573 PISECURITY_DESCRIPTOR CurrentDescriptor;
06574 PACL CurrentSacl;
06575 PACL CurrentDacl;
06576
06577 PSID NewOwner;
06578 PSID NewGroup;
06579
06580 PACL NewSacl =
NULL;
06581 ULONG NewSaclControl = 0;
06582 BOOLEAN NewSaclAllocated =
FALSE;
06583
06584 PACL NewDacl =
NULL;
06585 ULONG NewDaclControl = 0;
06586 BOOLEAN NewDaclAllocated =
FALSE;
06587 PACL TemplateInheritedDacl =
NULL;
06588 ULONG GenericControl;
06589
06590 ULONG AllocationSize;
06591 ULONG NewOwnerSize;
06592 ULONG NewGroupSize;
06593 ULONG NewSaclSize;
06594 ULONG NewDaclSize;
06595
06596 PCHAR Field;
06597 PCHAR Base;
06598
06599 PISECURITY_DESCRIPTOR_RELATIVE INewDescriptor =
NULL;
06600 ULONG ReturnLength;
06601
NTSTATUS PassedStatus;
06602 HANDLE
PrimaryToken;
06603
06604
#ifndef NTOS_KERNEL_RUNTIME
06605
PVOID
HeapHandle;
06606
#endif // NTOS_KERNEL_RUNTIME
06607
06608
RTL_PAGED_CODE();
06609
06610
06611
06612
06613
06614
#ifndef NTOS_KERNEL_RUNTIME
06615
HeapHandle = RtlProcessHeap();
06616
#endif // NTOS_KERNEL_RUNTIME
06617
06618
06619
06620
06621
06622
06623 CurrentDescriptor = CurrentSecurityDescriptor;
06624
06625
06626
06627
06628
06629
if (!
RtlValidSecurityDescriptor ( CurrentDescriptor )) {
06630
Status = STATUS_INVALID_SECURITY_DESCR;
06631
goto Cleanup;
06632 }
06633
06634
06635 NewOwner = RtlpOwnerAddrSecurityDescriptor( CurrentDescriptor );
06636
if ( NewOwner ==
NULL ) {
06637
Status = STATUS_INVALID_SECURITY_DESCR;
06638
goto Cleanup;
06639 }
06640
06641 NewGroup = RtlpGroupAddrSecurityDescriptor( CurrentDescriptor );
06642
06643
06644
06645
06646
06647
06648
06649
06650
06651
06652
06653
06654 CurrentSacl = RtlpSaclAddrSecurityDescriptor( CurrentDescriptor );
06655
06656
if ( CurrentSacl ==
NULL ) {
06657 PACL ParentSacl;
06658
06659
06660 NewSaclControl |= CurrentDescriptor->Control & (SE_SACL_PROTECTED|SE_SACL_PRESENT);
06661
06662
06663 NewSaclControl |= SE_SACL_AUTO_INHERITED;
06664
06665
06666
06667
06668
06669
06670
06671
06672 ParentSacl = ARGUMENT_PRESENT(ParentDescriptor) ?
06673 RtlpSaclAddrSecurityDescriptor( ((SECURITY_DESCRIPTOR *)ParentDescriptor)) :
06674
NULL;
06675
if ( ParentSacl !=
NULL) {
06676 NewSaclControl |= SE_SACL_PROTECTED;
06677 }
06678
06679
06680
06681
06682
06683
06684
06685
06686
06687
06688
06689 }
else if ( RtlpAreControlBitsSet( CurrentDescriptor, SE_SACL_AUTO_INHERITED) ||
06690 RtlpAreControlBitsSet( CurrentDescriptor, SE_SACL_PROTECTED ) ||
06691 !ARGUMENT_PRESENT(ParentDescriptor) ) {
06692
06693
06694 NewSaclControl |= CurrentDescriptor->Control & (SE_SACL_PROTECTED|SE_SACL_PRESENT);
06695
06696
06697 NewSaclControl |= SE_SACL_AUTO_INHERITED;
06698
06699 NewSacl = CurrentSacl;
06700
06701
06702
06703
06704
06705
06706
06707 }
else {
06708
06709
06710
Status =
RtlpConvertAclToAutoInherit (
06711 ARGUMENT_PRESENT(ParentDescriptor) ?
06712 RtlpSaclAddrSecurityDescriptor(
06713 ((SECURITY_DESCRIPTOR *)ParentDescriptor)) :
06714
NULL,
06715 RtlpSaclAddrSecurityDescriptor(CurrentDescriptor),
06716 ObjectType,
06717 IsDirectoryObject,
06718 RtlpOwnerAddrSecurityDescriptor(CurrentDescriptor),
06719 RtlpGroupAddrSecurityDescriptor(CurrentDescriptor),
06720 GenericMapping,
06721 &NewSacl,
06722 &GenericControl );
06723
06724
if ( !
NT_SUCCESS(
Status) ) {
06725
goto Cleanup;
06726 }
06727
06728 NewSaclAllocated =
TRUE;
06729 NewSaclControl |= SE_SACL_PRESENT | SeControlGenericToSacl( GenericControl );
06730 }
06731
06732
06733
06734
06735
06736
06737
06738
06739
06740
06741 CurrentDacl = RtlpDaclAddrSecurityDescriptor( CurrentDescriptor );
06742
06743
if ( CurrentDacl ==
NULL ) {
06744
06745 NewDaclControl |= CurrentDescriptor->Control & SE_DACL_PRESENT;
06746
06747
06748
06749 NewDaclControl |= SE_DACL_AUTO_INHERITED | SE_DACL_PROTECTED;
06750
06751
06752
06753
06754
06755
06756
06757
06758
06759
06760
06761
06762 }
else if ( RtlpAreControlBitsSet( CurrentDescriptor, SE_DACL_AUTO_INHERITED) ||
06763 RtlpAreControlBitsSet( CurrentDescriptor, SE_DACL_PROTECTED ) ||
06764 !ARGUMENT_PRESENT(ParentDescriptor) ) {
06765
06766
06767 NewDaclControl |= CurrentDescriptor->Control & (SE_DACL_PROTECTED|SE_DACL_PRESENT);
06768
06769
06770 NewDaclControl |= SE_DACL_AUTO_INHERITED;
06771
06772 NewDacl = CurrentDacl;
06773
06774
06775
06776
06777
06778
06779
06780
06781 }
else {
06782
06783
06784
Status =
RtlpConvertAclToAutoInherit (
06785 ARGUMENT_PRESENT(ParentDescriptor) ?
06786 RtlpDaclAddrSecurityDescriptor(
06787 ((SECURITY_DESCRIPTOR *)ParentDescriptor)) :
06788
NULL,
06789 RtlpDaclAddrSecurityDescriptor(CurrentDescriptor),
06790 ObjectType,
06791 IsDirectoryObject,
06792 RtlpOwnerAddrSecurityDescriptor(CurrentDescriptor),
06793 RtlpGroupAddrSecurityDescriptor(CurrentDescriptor),
06794 GenericMapping,
06795 &NewDacl,
06796 &GenericControl );
06797
06798
if ( !
NT_SUCCESS(
Status) ) {
06799
goto Cleanup;
06800 }
06801
06802 NewDaclAllocated =
TRUE;
06803 NewDaclControl |= SE_DACL_PRESENT | SeControlGenericToDacl( GenericControl );
06804 }
06805
06806
06807
06808
06809
06810
06811
06812
06813
06814
06815 NewOwnerSize = LongAlignSize(
SeLengthSid(NewOwner));
06816
06817
if ( NewGroup !=
NULL ) {
06818 NewGroupSize = LongAlignSize(
SeLengthSid(NewGroup));
06819 }
else {
06820 NewGroupSize = 0;
06821 }
06822
06823
if (NewSacl !=
NULL) {
06824 NewSaclSize = LongAlignSize(NewSacl->AclSize);
06825 }
else {
06826 NewSaclSize = 0;
06827 }
06828
06829
if (NewDacl !=
NULL) {
06830 NewDaclSize = LongAlignSize(NewDacl->AclSize);
06831 }
else {
06832 NewDaclSize = 0;
06833 }
06834
06835 AllocationSize = LongAlignSize(
sizeof(SECURITY_DESCRIPTOR_RELATIVE)) +
06836 NewOwnerSize +
06837 NewGroupSize +
06838 NewSaclSize +
06839 NewDaclSize;
06840
06841
06842
06843
06844
06845
06846
06847
#ifdef NTOS_KERNEL_RUNTIME
06848
INewDescriptor =
ExAllocatePoolWithTag(
06849
PagedPool,
06850 AllocationSize,
06851 'dSeS' );
06852
#else // NTOS_KERNEL_RUNTIME
06853
INewDescriptor =
RtlAllocateHeap(
06854
HeapHandle,
06855
MAKE_TAG(
SE_TAG),
06856 AllocationSize );
06857
#endif // NTOS_KERNEL_RUNTIME
06858
06859
if ( INewDescriptor ==
NULL ) {
06860
Status = STATUS_NO_MEMORY;
06861
goto Cleanup;
06862 }
06863
06864
06865
06866
06867
06868
06869
RtlCreateSecurityDescriptorRelative(
06870 INewDescriptor,
06871 SECURITY_DESCRIPTOR_REVISION
06872 );
06873
06874 RtlpSetControlBits( INewDescriptor, SE_SELF_RELATIVE );
06875
06876 Base = (PCHAR)(INewDescriptor);
06877 Field = Base +
sizeof(SECURITY_DESCRIPTOR_RELATIVE);
06878
06879
06880
06881
06882
06883 RtlpSetControlBits( INewDescriptor, NewSaclControl );
06884
if (NewSacl !=
NULL ) {
06885
06886 RtlCopyMemory( Field, NewSacl, NewSacl->AclSize );
06887 INewDescriptor->Sacl = RtlPointerToOffset(Base,Field);
06888 Field += NewSaclSize;
06889
06890 }
else {
06891
06892 INewDescriptor->Sacl = 0;
06893 }
06894
06895
06896
06897
06898
06899 RtlpSetControlBits( INewDescriptor, NewDaclControl );
06900
if (NewDacl !=
NULL ) {
06901
06902 RtlCopyMemory( Field, NewDacl, NewDacl->AclSize );
06903 INewDescriptor->Dacl = RtlPointerToOffset(Base,Field);
06904 Field += NewDaclSize;
06905
06906 }
else {
06907
06908 INewDescriptor->Dacl = 0;
06909 }
06910
06911
06912
06913
06914
06915 RtlCopyMemory( Field, NewOwner,
SeLengthSid(NewOwner) );
06916 INewDescriptor->Owner = RtlPointerToOffset(Base,Field);
06917 Field += NewOwnerSize;
06918
06919
if ( NewGroup !=
NULL ) {
06920 RtlCopyMemory( Field, NewGroup,
SeLengthSid(NewGroup) );
06921 INewDescriptor->Group = RtlPointerToOffset(Base,Field);
06922 }
06923
06924
Status = STATUS_SUCCESS;
06925
06926
06927
06928
06929
06930
06931 Cleanup:
06932
if (NewDaclAllocated) {
06933
#ifdef NTOS_KERNEL_RUNTIME
06934
ExFreePool( NewDacl );
06935
#else // NTOS_KERNEL_RUNTIME
06936
RtlFreeHeap(
HeapHandle, 0, NewDacl );
06937
#endif // NTOS_KERNEL_RUNTIME
06938
}
06939
if (NewSaclAllocated) {
06940
#ifdef NTOS_KERNEL_RUNTIME
06941
ExFreePool( NewSacl );
06942
#else // NTOS_KERNEL_RUNTIME
06943
RtlFreeHeap(
HeapHandle, 0, NewSacl );
06944
#endif // NTOS_KERNEL_RUNTIME
06945
}
06946
06947 *NewSecurityDescriptor = (PSECURITY_DESCRIPTOR) INewDescriptor;
06948
06949
return Status;
06950
06951
06952 }
06953
06954
06955
06956
06957
06958
06959
06960
06961
06962
06963
06964 #define MAX_CHILD_SID_GROUP_SIZE 3 // Number of bits in above list
06965 #define EFFECTIVE_ACE INHERIT_ONLY_ACE
06966 #define AceFlagsInAce( _Ace) \
06967
(((PACE_HEADER)(_Ace))->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE) | \
06968
(((PACE_HEADER)(_Ace))->AceFlags & INHERIT_ONLY_ACE) ^ INHERIT_ONLY_ACE )
06969
06970
06971 BOOLEAN
06972 RtlpCompareAces(
06973 IN
PKNOWN_ACE InheritedAce,
06974 IN
PKNOWN_ACE ChildAce,
06975 IN PSID OwnerSid,
06976 IN PSID GroupSid
06977 )
06978
06979
06980
06981
06982
06983
06984
06985
06986
06987
06988
06989
06990
06991
06992
06993
06994
06995
06996
06997
06998
06999
07000
07001
07002
07003
07004
07005
07006 {
07007 BOOLEAN AcesCompare =
FALSE;
07008
07009
if (IsObjectAceType(InheritedAce) && IsObjectAceType(ChildAce)) {
07010
07011 AcesCompare =
RtlpCompareKnownObjectAces( (PKNOWN_OBJECT_ACE)InheritedAce,
07012 (PKNOWN_OBJECT_ACE)ChildAce,
07013 OwnerSid,
07014 GroupSid
07015 );
07016 }
else {
07017
07018
if (!IsObjectAceType(InheritedAce) && !IsObjectAceType(ChildAce)) {
07019
07020 AcesCompare =
RtlpCompareKnownAces( InheritedAce,
07021 ChildAce,
07022 OwnerSid,
07023 GroupSid
07024 );
07025 }
07026 }
07027
07028
return( AcesCompare );
07029 }
07030
07031
07032 BOOLEAN
07033 RtlpCompareKnownAces(
07034 IN
PKNOWN_ACE InheritedAce,
07035 IN
PKNOWN_ACE ChildAce,
07036 IN PSID OwnerSid OPTIONAL,
07037 IN PSID GroupSid OPTIONAL
07038 )
07039
07040
07041
07042
07043
07044
07045
07046
07047
07048
07049
07050
07051
07052
07053
07054
07055
07056
07057
07058
07059
07060
07061
07062
07063
07064
07065 {
07066
NTSTATUS Status;
07067 ACE_HEADER
volatile *InheritedAceHdr = &InheritedAce->Header;
07068
07069
RTL_PAGED_CODE();
07070
07071
ASSERT(!IsObjectAceType(InheritedAce));
07072
ASSERT(!IsObjectAceType(ChildAce));
07073
07074
07075
07076
07077
07078
if (
RtlBaseAceType[ChildAce->Header.AceType] !=
RtlBaseAceType[InheritedAceHdr->AceType] ) {
07079
#if DBG
07080
if (
RtlpVerboseConvert ) {
07081 KdPrint((
"AceType mismatch"));
07082 }
07083
#endif // DBG
07084
return FALSE;
07085 }
07086
07087
07088
07089
07090
07091
07092
if (
RtlIsSystemAceType[ChildAce->Header.AceType] ) {
07093
if ( (ChildAce->Header.AceFlags & (SUCCESSFUL_ACCESS_ACE_FLAG|FAILED_ACCESS_ACE_FLAG)) !=
07094 (InheritedAceHdr->AceFlags & (SUCCESSFUL_ACCESS_ACE_FLAG|FAILED_ACCESS_ACE_FLAG)) ) {
07095
#if DBG
07096
if (
RtlpVerboseConvert ) {
07097 KdPrint((
"System ace success/fail mismatch"));
07098 }
07099
#endif // DBG
07100
return FALSE;
07101 }
07102 }
07103
07104
07105
07106
07107
07108
07109
if ( !
RtlEqualSid( (PSID)&ChildAce->SidStart, (PSID)&InheritedAce->SidStart )) {
07110
07111
07112
07113
07114
07115
07116
if (
AceFlagsInAce(ChildAce) !=
EFFECTIVE_ACE ) {
07117
#if DBG
07118
if (
RtlpVerboseConvert ) {
07119 KdPrint((
"SID mismatch"));
07120 }
07121
#endif // DBG
07122
return FALSE;
07123 }
07124
07125
07126
07127
07128
07129
07130
07131
07132
07133
07134
07135
07136
if ( OwnerSid !=
NULL || GroupSid !=
NULL ) {
07137 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
07138 ULONG
CreatorSid[
CREATOR_SID_SIZE];
07139
07140
07141
07142
07143
07144
07145
ASSERT(
RtlLengthRequiredSid( 1 ) ==
CREATOR_SID_SIZE);
07146
RtlInitializeSid( (PSID)
CreatorSid, &CreatorSidAuthority, 1 );
07147 *(RtlpSubAuthoritySid( (PSID)
CreatorSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
07148
07149
if (
RtlEqualPrefixSid ( (PSID)&InheritedAce->SidStart,
CreatorSid )) {
07150 ULONG Rid;
07151
07152 Rid = *RtlpSubAuthoritySid( (PSID)&InheritedAce->SidStart, 0 );
07153
switch (Rid) {
07154
case SECURITY_CREATOR_OWNER_RID:
07155
if ( OwnerSid ==
NULL ||
07156 !
RtlEqualSid( (PSID)&ChildAce->SidStart, OwnerSid )) {
07157
#if DBG
07158
if (
RtlpVerboseConvert ) {
07159 KdPrint((
"SID mismatch (Creator Owner)"));
07160 }
07161
#endif // DBG
07162
return FALSE;
07163 }
07164
break;
07165
case SECURITY_CREATOR_GROUP_RID:
07166
if ( GroupSid ==
NULL ||
07167 !
RtlEqualSid( (PSID)&ChildAce->SidStart, GroupSid )) {
07168
#if DBG
07169
if (
RtlpVerboseConvert ) {
07170 KdPrint((
"SID mismatch (Creator Group)"));
07171 }
07172
#endif // DBG
07173
return FALSE;
07174 }
07175
break;
07176
default:
07177
#if DBG
07178
if (
RtlpVerboseConvert ) {
07179 KdPrint((
"SID mismatch (Creator)"));
07180 }
07181
#endif // DBG
07182
return FALSE;
07183 }
07184
07185 }
else {
07186
#if DBG
07187
if (
RtlpVerboseConvert ) {
07188 KdPrint((
"SID mismatch"));
07189 }
07190
#endif // DBG
07191
return FALSE;
07192 }
07193 }
else {
07194
#if DBG
07195
if (
RtlpVerboseConvert ) {
07196 KdPrint((
"SID mismatch"));
07197 }
07198
#endif // DBG
07199
return FALSE;
07200 }
07201 }
07202
07203
return TRUE;
07204
07205 }
07206
07207
07208 BOOLEAN
07209 RtlpCompareKnownObjectAces(
07210 IN PKNOWN_OBJECT_ACE InheritedAce,
07211 IN PKNOWN_OBJECT_ACE ChildAce,
07212 IN PSID OwnerSid OPTIONAL,
07213 IN PSID GroupSid OPTIONAL
07214 )
07215
07216
07217
07218
07219
07220
07221
07222
07223
07224
07225
07226
07227
07228
07229
07230
07231
07232
07233
07234
07235
07236
07237
07238
07239
07240
07241
07242
07243
07244
07245 {
07246
NTSTATUS Status;
07247 BOOLEAN DoingObjectAces;
07248 GUID *ChildObjectGuid;
07249 GUID *InhObjectGuid;
07250 GUID *ChildInheritedObjectGuid;
07251 GUID *InhInheritedObjectGuid;
07252 ACE_HEADER
volatile *InheritedAceHdr = &InheritedAce->Header;
07253
07254
RTL_PAGED_CODE();
07255
07256
ASSERT(IsObjectAceType(InheritedAce));
07257
ASSERT(IsObjectAceType(ChildAce));
07258
07259
07260
07261
07262
if (
RtlBaseAceType[ChildAce->Header.AceType] !=
RtlBaseAceType[InheritedAceHdr->AceType] ) {
07263
#if DBG
07264
if (
RtlpVerboseConvert ) {
07265 KdPrint((
"AceType mismatch"));
07266 }
07267
#endif // DBG
07268
return FALSE;
07269 }
07270
07271
07272
07273
07274
07275
07276
if (
RtlIsSystemAceType[ChildAce->Header.AceType] ) {
07277
if ( (ChildAce->Header.AceFlags & (SUCCESSFUL_ACCESS_ACE_FLAG|FAILED_ACCESS_ACE_FLAG)) !=
07278 (InheritedAceHdr->AceFlags & (SUCCESSFUL_ACCESS_ACE_FLAG|FAILED_ACCESS_ACE_FLAG)) ) {
07279
#if DBG
07280
if (
RtlpVerboseConvert ) {
07281 KdPrint((
"System ace success/fail mismatch"));
07282 }
07283
#endif // DBG
07284
return FALSE;
07285 }
07286 }
07287
07288
07289
07290
07291
07292 ChildObjectGuid = RtlObjectAceObjectType(ChildAce);
07293 ChildInheritedObjectGuid = RtlObjectAceInheritedObjectType(ChildAce);
07294
07295 InhObjectGuid = RtlObjectAceObjectType(InheritedAce);
07296 InhInheritedObjectGuid = RtlObjectAceInheritedObjectType(InheritedAce);
07297
07298
07299
07300
07301
07302
07303
if ( ChildInheritedObjectGuid !=
NULL || InhInheritedObjectGuid !=
NULL ) {
07304
07305
if ( ChildInheritedObjectGuid ==
NULL ||
07306 InhInheritedObjectGuid ==
NULL ||
07307 !RtlpIsEqualGuid( ChildInheritedObjectGuid, InhInheritedObjectGuid )) {
07308
#if DBG
07309
if (
RtlpVerboseConvert ) {
07310 KdPrint((
"InheritedObject GUID mismatch"));
07311 }
07312
#endif // DBG
07313
return FALSE;
07314 }
07315 }
07316
07317
07318
07319
07320
07321
07322
07323
07324
if ( (ChildObjectGuid !=
NULL) && (InhObjectGuid !=
NULL) ) {
07325
07326
if (!RtlpIsEqualGuid( ChildObjectGuid, InhObjectGuid )) {
07327
#if DBG
07328
if (
RtlpVerboseConvert ) {
07329 KdPrint((
"Object GUID mismatch"));
07330 }
07331
#endif // DBG
07332
07333
return(
FALSE );
07334 }
07335 }
else {
07336
07337
07338
07339
07340
07341
if ( !((ChildObjectGuid ==
NULL) && (InhObjectGuid ==
NULL)) ) {
07342
#if DBG
07343
if (
RtlpVerboseConvert ) {
07344 KdPrint((
"Object GUID mismatch"));
07345 }
07346
#endif // DBG
07347
07348
return(
FALSE );
07349 }
07350 }
07351
07352
07353
07354
07355
07356
07357
if ( !
RtlEqualSid( RtlObjectAceSid(ChildAce), RtlObjectAceSid(InheritedAce))) {
07358
07359
07360
07361
07362
07363
07364
if (
AceFlagsInAce(ChildAce) !=
EFFECTIVE_ACE ) {
07365
#if DBG
07366
if (
RtlpVerboseConvert ) {
07367 KdPrint((
"SID mismatch"));
07368 }
07369
#endif // DBG
07370
return FALSE;
07371 }
07372
07373
07374
07375
07376
07377
07378
07379
07380
07381
07382
07383
07384
07385
07386
if ( OwnerSid !=
NULL || GroupSid !=
NULL ) {
07387 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
07388 ULONG
CreatorSid[
CREATOR_SID_SIZE];
07389
07390
07391
07392
07393
07394
07395
ASSERT(
RtlLengthRequiredSid( 1 ) ==
CREATOR_SID_SIZE);
07396
RtlInitializeSid( (PSID)
CreatorSid, &CreatorSidAuthority, 1 );
07397 *(RtlpSubAuthoritySid( (PSID)
CreatorSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
07398
07399
if (
RtlEqualPrefixSid ( RtlObjectAceSid(InheritedAce),
CreatorSid )) {
07400 ULONG Rid;
07401
07402 Rid = *RtlpSubAuthoritySid( RtlObjectAceSid(InheritedAce), 0 );
07403
switch (Rid) {
07404
case SECURITY_CREATOR_OWNER_RID:
07405
if ( OwnerSid ==
NULL ||
07406 !
RtlEqualSid( RtlObjectAceSid(ChildAce), OwnerSid )) {
07407
#if DBG
07408
if (
RtlpVerboseConvert ) {
07409 KdPrint((
"SID mismatch (Creator Owner)"));
07410 }
07411
#endif // DBG
07412
return FALSE;
07413 }
07414
break;
07415
case SECURITY_CREATOR_GROUP_RID:
07416
if ( GroupSid ==
NULL ||
07417 !
RtlEqualSid( RtlObjectAceSid(ChildAce), GroupSid )) {
07418
#if DBG
07419
if (
RtlpVerboseConvert ) {
07420 KdPrint((
"SID mismatch (Creator Group)"));
07421 }
07422
#endif // DBG
07423
return FALSE;
07424 }
07425
break;
07426
default:
07427
#if DBG
07428
if (
RtlpVerboseConvert ) {
07429 KdPrint((
"SID mismatch (Creator)"));
07430 }
07431
#endif // DBG
07432
return FALSE;
07433 }
07434
07435 }
else {
07436
#if DBG
07437
if (
RtlpVerboseConvert ) {
07438 KdPrint((
"SID mismatch"));
07439 }
07440
#endif // DBG
07441
return FALSE;
07442 }
07443 }
else {
07444
#if DBG
07445
if (
RtlpVerboseConvert ) {
07446 KdPrint((
"SID mismatch"));
07447 }
07448
#endif // DBG
07449
return FALSE;
07450 }
07451 }
07452
07453
return TRUE;
07454
07455 }
07456
07457
07458
07459
07460
NTSTATUS
07461 RtlpConvertAclToAutoInherit (
07462 IN PACL ParentAcl OPTIONAL,
07463 IN PACL ChildAcl,
07464 IN GUID *ObjectType OPTIONAL,
07465 IN BOOLEAN IsDirectoryObject,
07466 IN PSID OwnerSid,
07467 IN PSID GroupSid,
07468 IN PGENERIC_MAPPING GenericMapping,
07469 OUT PACL *NewAcl,
07470 OUT PULONG NewGenericControl
07471 )
07472
07473
07474
07475
07476
07477
07478
07479
07480
07481
07482
07483
07484
07485
07486
07487
07488
07489
07490
07491
07492
07493
07494
07495
07496
07497
07498
07499
07500
07501
07502
07503
07504
07505
07506
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516
07517
07518
07519
07520
07521
07522
07523
07524
07525
07526
07527
07528
07529
07530
07531
07532
07533
07534 {
07535
NTSTATUS Status;
07536
07537 PACL InheritedAcl =
NULL;
07538 PACL RealInheritedAcl =
NULL;
07539 BOOLEAN AclExplicitlyAssigned;
07540 ULONG GenericControl;
07541
07542
PKNOWN_ACE ChildAce =
NULL;
07543
PKNOWN_ACE InheritedAce;
07544
07545 LONG ChildAceIndex;
07546 LONG InheritedAceIndex;
07547
07548 BOOLEAN InheritedAllowFound;
07549 BOOLEAN InheritedDenyFound;
07550
07551 BOOLEAN AcesCompare;
07552
07553 ACCESS_MASK InheritedContainerInheritMask;
07554 ACCESS_MASK InheritedObjectInheritMask;
07555 ACCESS_MASK InheritedEffectiveMask;
07556 ACCESS_MASK OriginalInheritedContainerInheritMask;
07557 ACCESS_MASK OriginalInheritedObjectInheritMask;
07558 ACCESS_MASK OriginalInheritedEffectiveMask;
07559
07560 ULONG InheritedAceFlags;
07561 ULONG MatchedFlags;
07562 ULONG NonInheritedAclSize;
07563
07564
07565 PACE_HEADER AceHeader;
07566 PUCHAR Where;
07567
07568
07569
07570
07571
07572
07573
07574
07575
07576
07577
07578
07579
07580
07581
07582
07583
07584
07585
07586
07587
typedef struct {
07588 ACCESS_MASK OriginalContainerInheritMask;
07589 ACCESS_MASK OriginalObjectInheritMask;
07590 ACCESS_MASK OriginalEffectiveMask;
07591
07592 ACCESS_MASK ContainerInheritMask;
07593 ACCESS_MASK ObjectInheritMask;
07594 ACCESS_MASK EffectiveMask;
07595 } ACE_INFO, *PACE_INFO;
07596
07597 PACE_INFO ChildAceInfo =
NULL;
07598
07599 ULONG
CreatorOwnerSid[
CREATOR_SID_SIZE];
07600 ULONG CreatorGroupSid[
CREATOR_SID_SIZE];
07601
07602 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
07603
07604
#ifndef NTOS_KERNEL_RUNTIME
07605
PVOID
HeapHandle;
07606
#endif // NTOS_KERNEL_RUNTIME
07607
07608
RTL_PAGED_CODE();
07609
07610
07611
07612
07613
07614
#ifndef NTOS_KERNEL_RUNTIME
07615
HeapHandle = RtlProcessHeap();
07616
#endif // NTOS_KERNEL_RUNTIME
07617
07618
07619
07620
07621
07622
07623
ASSERT(
RtlLengthRequiredSid( 1 ) ==
CREATOR_SID_SIZE);
07624
RtlInitializeSid( (PSID)
CreatorOwnerSid, &CreatorSidAuthority, 1 );
07625 *(RtlpSubAuthoritySid( (PSID)
CreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
07626
07627
RtlInitializeSid( (PSID)CreatorGroupSid, &CreatorSidAuthority, 1 );
07628 *(RtlpSubAuthoritySid( (PSID)CreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;
07629
07630
07631
07632
07633
07634 *NewGenericControl = SEP_ACL_AUTO_INHERITED;
07635 *NewAcl =
NULL;
07636
07637
if ( ParentAcl !=
NULL && !
RtlValidAcl( ParentAcl ) ) {
07638
Status = STATUS_INVALID_ACL;
07639
goto Cleanup;
07640 }
07641
07642
if (!
RtlValidAcl( ChildAcl ) ) {
07643
Status = STATUS_INVALID_ACL;
07644
goto Cleanup;
07645 }
07646
07647
07648
07649
07650
07651
07652
07653
07654
07655
07656
Status =
RtlpInheritAcl (
07657 ParentAcl,
07658
NULL,
07659 0,
07660 IsDirectoryObject,
07661
TRUE,
07662
FALSE,
07663
CreatorOwnerSid,
07664 CreatorGroupSid,
07665
CreatorOwnerSid,
07666 CreatorGroupSid,
07667 GenericMapping,
07668
TRUE,
07669 ObjectType,
07670 &InheritedAcl,
07671 &AclExplicitlyAssigned,
07672 &GenericControl );
07673
07674
if (
Status == STATUS_NO_INHERITANCE ) {
07675 *NewGenericControl |= SEP_ACL_PROTECTED;
07676
#if DBG
07677
if (
RtlpVerboseConvert ) {
07678 KdPrint((
"NO_INHERITANCE of the parent ACL\n" ));
07679 }
07680
#endif // DBG
07681
Status = STATUS_SUCCESS;
07682
goto Cleanup;
07683 }
07684
07685
if ( !
NT_SUCCESS(
Status) ) {
07686
#if DBG
07687
if (
RtlpVerboseConvert ) {
07688 KdPrint((
"Can't build inherited ACL %lX\n",
Status ));
07689 }
07690
#endif // DBG
07691
goto Cleanup;
07692 }
07693
07694
07695
07696
07697
07698
07699
07700
07701
07702
#ifdef NTOS_KERNEL_RUNTIME
07703
ChildAceInfo =
ExAllocatePoolWithTag(
07704
PagedPool,
07705 ChildAcl->AceCount *
sizeof(ACE_INFO),
07706 'cAeS' );
07707
#else // NTOS_KERNEL_RUNTIME
07708
ChildAceInfo =
RtlAllocateHeap(
07709
HeapHandle,
07710
MAKE_TAG(
SE_TAG),
07711 ChildAcl->AceCount *
sizeof(ACE_INFO) );
07712
#endif // NTOS_KERNEL_RUNTIME
07713
07714
if (ChildAceInfo ==
NULL ) {
07715
Status = STATUS_NO_MEMORY;
07716
goto Cleanup;
07717 }
07718
07719
for (ChildAceIndex = 0, ChildAce =
FirstAce(ChildAcl);
07720 ChildAceIndex < ChildAcl->AceCount;
07721 ChildAceIndex += 1, ChildAce =
NextAce(ChildAce)) {
07722 ACCESS_MASK LocalMask;
07723 ULONG ChildAceFlags;
07724
07725
if ( !IsV4AceType(ChildAce) || IsCompoundAceType(ChildAce)) {
07726 *NewGenericControl |= SEP_ACL_PROTECTED;
07727
#if DBG
07728
if (
RtlpVerboseConvert ) {
07729 KdPrint((
"Inherited Ace type (%ld) not known\n", ChildAce->Header.AceType ));
07730 }
07731
#endif // DBG
07732
Status = STATUS_SUCCESS;
07733
goto Cleanup;
07734 }
07735
07736
07737
07738
07739
07740
07741
07742 LocalMask = ((
PKNOWN_ACE)(ChildAce))->Mask;
07743 RtlApplyGenericMask( ChildAce, &LocalMask, GenericMapping);
07744
07745
07746
07747
07748
07749 ChildAceFlags =
AceFlagsInAce( ChildAce );
07750
if ( ChildAceFlags & CONTAINER_INHERIT_ACE ) {
07751 ChildAceInfo[ChildAceIndex].OriginalContainerInheritMask = LocalMask;
07752 ChildAceInfo[ChildAceIndex].ContainerInheritMask = LocalMask;
07753 }
else {
07754 ChildAceInfo[ChildAceIndex].OriginalContainerInheritMask = 0;
07755 ChildAceInfo[ChildAceIndex].ContainerInheritMask = 0;
07756 }
07757
07758
if ( ChildAceFlags & OBJECT_INHERIT_ACE ) {
07759 ChildAceInfo[ChildAceIndex].OriginalObjectInheritMask = LocalMask;
07760 ChildAceInfo[ChildAceIndex].ObjectInheritMask = LocalMask;
07761 }
else {
07762 ChildAceInfo[ChildAceIndex].OriginalObjectInheritMask = 0;
07763 ChildAceInfo[ChildAceIndex].ObjectInheritMask = 0;
07764 }
07765
07766
if ( ChildAceFlags &
EFFECTIVE_ACE ) {
07767 ChildAceInfo[ChildAceIndex].OriginalEffectiveMask = LocalMask;
07768 ChildAceInfo[ChildAceIndex].EffectiveMask = LocalMask;
07769 }
else {
07770 ChildAceInfo[ChildAceIndex].OriginalEffectiveMask = 0;
07771 ChildAceInfo[ChildAceIndex].EffectiveMask = 0;
07772 }
07773
07774 }
07775
07776
07777
07778
07779
07780
07781
for (InheritedAceIndex = 0, InheritedAce =
FirstAce(InheritedAcl);
07782 InheritedAceIndex < InheritedAcl->AceCount;
07783 InheritedAceIndex += 1, InheritedAce =
NextAce(InheritedAce)) {
07784
07785 ACCESS_MASK LocalMask;
07786
07787
07788
07789
07790
07791
07792
if ( !IsV4AceType(InheritedAce) || IsCompoundAceType(InheritedAce)) {
07793 *NewGenericControl |= SEP_ACL_PROTECTED;
07794
#if DBG
07795
if (
RtlpVerboseConvert ) {
07796 KdPrint((
"Inherited Ace type (%ld) not known\n", InheritedAce->Header.AceType ));
07797 }
07798
#endif // DBG
07799
Status = STATUS_SUCCESS;
07800
goto Cleanup;
07801 }
07802
07803
07804
07805
07806
07807
07808
07809 LocalMask = ((
PKNOWN_ACE)(InheritedAce))->Mask;
07810 RtlApplyGenericMask( InheritedAce, &LocalMask, GenericMapping);
07811
07812
if ( LocalMask == 0 ) {
07813
#if DBG
07814
if (
RtlpVerboseConvert ) {
07815 KdPrint((
"Worthless INH ACE: %ld 0x%8.8lx\n", InheritedAceIndex, LocalMask ));
07816 }
07817
#endif // DBG
07818
continue;
07819 }
07820
07821
07822
07823
07824
07825
07826
07827
07828 InheritedAceFlags =
AceFlagsInAce( InheritedAce );
07829
07830
if ( InheritedAceFlags == 0 ) {
07831
#if DBG
07832
if (
RtlpVerboseConvert ) {
07833 KdPrint((
"Worthless INH ACE: %ld 0x%lx\n", InheritedAceIndex, InheritedAceFlags ));
07834 }
07835
#endif // DBG
07836
continue;
07837 }
07838
07839
if ( InheritedAceFlags & CONTAINER_INHERIT_ACE ) {
07840 OriginalInheritedContainerInheritMask = InheritedContainerInheritMask = LocalMask;
07841 }
else {
07842 OriginalInheritedContainerInheritMask = InheritedContainerInheritMask = 0;
07843 }
07844
07845
if ( InheritedAceFlags & OBJECT_INHERIT_ACE ) {
07846 OriginalInheritedObjectInheritMask = InheritedObjectInheritMask = LocalMask;
07847 }
else {
07848 OriginalInheritedObjectInheritMask = InheritedObjectInheritMask = 0;
07849 }
07850
07851
if ( InheritedAceFlags &
EFFECTIVE_ACE ) {
07852 OriginalInheritedEffectiveMask = InheritedEffectiveMask = LocalMask;
07853 }
else {
07854 OriginalInheritedEffectiveMask = InheritedEffectiveMask = 0;
07855 }
07856
07857
#if DBG
07858
if (
RtlpVerboseConvert ) {
07859 KdPrint((
"Doing INH ACE: %ld %8.8lX %8.8lX %8.8lX\n", InheritedAceIndex, InheritedEffectiveMask, InheritedContainerInheritMask, InheritedObjectInheritMask ));
07860 }
07861
#endif // DBG
07862
07863
07864
07865
07866
07867
07868
07869
07870
07871
07872
07873
for (ChildAceIndex = 0, ChildAce =
FirstAce(ChildAcl);
07874 ChildAceIndex < ChildAcl->AceCount;
07875 ChildAceIndex += 1, ChildAce =
NextAce(ChildAce)) {
07876
07877
07878
07879
07880
07881
07882
#if DBG
07883
if (
RtlpVerboseConvert ) {
07884 KdPrint((
"Compare Child Ace: %ld ", ChildAceIndex ));
07885 }
07886
#endif // DBG
07887
07888
if ( !
RtlpCompareAces( InheritedAce,
07889 ChildAce,
07890 OwnerSid,
07891 GroupSid ) ) {
07892
#if DBG
07893
if (
RtlpVerboseConvert ) {
07894 KdPrint((
"\n" ));
07895 }
07896
#endif // DBG
07897
continue;
07898 }
07899
#if DBG
07900
if (
RtlpVerboseConvert ) {
07901 KdPrint((
"\n" ));
07902 }
07903
#endif // DBG
07904
07905
07906
07907
07908
07909
07910
07911
07912
07913
07914
07915
07916 InheritedEffectiveMask &= ~ChildAceInfo[ChildAceIndex].OriginalEffectiveMask;
07917 InheritedContainerInheritMask &= ~ChildAceInfo[ChildAceIndex].OriginalContainerInheritMask;
07918 InheritedObjectInheritMask &= ~ChildAceInfo[ChildAceIndex].OriginalObjectInheritMask;
07919
07920
#if DBG
07921
if (
RtlpVerboseConvert ) {
07922 KdPrint((
"New INH MASKs %ld %8.8lX %8.8lX %8.8lX\n", InheritedAceIndex, InheritedEffectiveMask, InheritedContainerInheritMask, InheritedObjectInheritMask ));
07923 }
07924
#endif // DBG
07925
07926
07927
07928
07929
07930
07931
07932
07933 ChildAceInfo[ChildAceIndex].EffectiveMask &= ~OriginalInheritedEffectiveMask;
07934 ChildAceInfo[ChildAceIndex].ContainerInheritMask &= ~OriginalInheritedContainerInheritMask;
07935 ChildAceInfo[ChildAceIndex].ObjectInheritMask &= ~OriginalInheritedObjectInheritMask;
07936
07937
#if DBG
07938
if (
RtlpVerboseConvert ) {
07939 KdPrint((
"New Child MASKs %ld %8.8lX %8.8lX %8.8lX\n", ChildAceIndex, ChildAceInfo[ChildAceIndex].EffectiveMask, ChildAceInfo[ChildAceIndex].ContainerInheritMask, ChildAceInfo[ChildAceIndex].ObjectInheritMask ));
07940 }
07941
#endif // DBG
07942
07943 }
07944
07945
07946
07947
07948
07949
07950
07951
if ( (InheritedEffectiveMask | InheritedContainerInheritMask | InheritedObjectInheritMask) != 0 ) {
07952 *NewGenericControl |= SEP_ACL_PROTECTED;
07953
#if DBG
07954
if (
RtlpVerboseConvert ) {
07955 KdPrint((
"INH ACE not completely matched: %ld %8.8lX %8.8lX %8.8lX\n", InheritedAceIndex, InheritedEffectiveMask, InheritedContainerInheritMask, InheritedObjectInheritMask ));
07956 }
07957
#endif // DBG
07958
Status = STATUS_SUCCESS;
07959
goto Cleanup;
07960 }
07961
07962
07963 }
07964
07965
07966
07967
07968
07969
07970
07971
07972
07973 InheritedAllowFound =
FALSE;
07974 InheritedDenyFound =
FALSE;
07975 NonInheritedAclSize = 0;
07976
for (ChildAceIndex = 0, ChildAce =
FirstAce(ChildAcl);
07977 ChildAceIndex < ChildAcl->AceCount;
07978 ChildAceIndex += 1, ChildAce =
NextAce(ChildAce)) {
07979
07980 ACCESS_MASK ResultantMask;
07981
07982
07983
07984
07985
07986
07987
07988
07989
07990
07991
07992
07993 ResultantMask =
07994 ChildAceInfo[ChildAceIndex].EffectiveMask |
07995 ChildAceInfo[ChildAceIndex].ContainerInheritMask |
07996 ChildAceInfo[ChildAceIndex].ObjectInheritMask;
07997
07998
07999
08000
08001
08002
08003
if ( ResultantMask == 0 ) {
08004
08005
08006
08007
08008
08009
if (
RtlBaseAceType[ChildAce->Header.AceType] == ACCESS_ALLOWED_ACE_TYPE ) {
08010 InheritedAllowFound =
TRUE;
08011 }
08012
08013
if (
RtlBaseAceType[ChildAce->Header.AceType] == ACCESS_DENIED_ACE_TYPE ) {
08014 InheritedDenyFound =
TRUE;
08015 }
08016
08017
08018
08019
08020
08021 }
else {
08022
08023
08024
08025
08026
08027 NonInheritedAclSize += ChildAce->Header.AceSize;
08028
08029
08030
08031
08032
08033
08034
08035
08036
if (
RtlBaseAceType[ChildAce->Header.AceType] == ACCESS_ALLOWED_ACE_TYPE && InheritedDenyFound ) {
08037 *NewGenericControl |= SEP_ACL_PROTECTED;
08038
#if DBG
08039
if (
RtlpVerboseConvert ) {
08040 KdPrint((
"Previous deny found Child ACE: %ld\n", ChildAceIndex ));
08041 }
08042
#endif // DBG
08043
Status = STATUS_SUCCESS;
08044
goto Cleanup;
08045 }
08046
08047
if (
RtlBaseAceType[ChildAce->Header.AceType] == ACCESS_DENIED_ACE_TYPE && InheritedAllowFound ) {
08048 *NewGenericControl |= SEP_ACL_PROTECTED;
08049
#if DBG
08050
if (
RtlpVerboseConvert ) {
08051 KdPrint((
"Previous allow found Child ACE: %ld\n", ChildAceIndex ));
08052 }
08053
#endif // DBG
08054
Status = STATUS_SUCCESS;
08055
goto Cleanup;
08056 }
08057
08058 }
08059
08060 }
08061
08062
08063
08064
08065
08066
08067
08068
08069
08070
08071
08072
Status =
RtlpInheritAcl (
08073 ParentAcl,
08074
NULL,
08075 0,
08076 IsDirectoryObject,
08077
TRUE,
08078
FALSE,
08079 OwnerSid,
08080 GroupSid,
08081 OwnerSid,
08082 GroupSid,
08083 GenericMapping,
08084
TRUE,
08085 ObjectType,
08086 &RealInheritedAcl,
08087 &AclExplicitlyAssigned,
08088 &GenericControl );
08089
08090
if ( !
NT_SUCCESS(
Status) ) {
08091
#if DBG
08092
if (
RtlpVerboseConvert ) {
08093 KdPrint((
"Can't build real inherited ACL %lX\n",
Status ));
08094 }
08095
#endif // DBG
08096
goto Cleanup;
08097 }
08098
08099
08100
08101
08102
08103
08104
08105
#ifdef NTOS_KERNEL_RUNTIME
08106
*NewAcl =
ExAllocatePoolWithTag(
08107
PagedPool,
08108 RealInheritedAcl->AclSize + NonInheritedAclSize,
08109 'cAeS' );
08110
#else // NTOS_KERNEL_RUNTIME
08111
*NewAcl =
RtlAllocateHeap(
08112
HeapHandle,
08113
MAKE_TAG(
SE_TAG),
08114 RealInheritedAcl->AclSize + NonInheritedAclSize );
08115
#endif // NTOS_KERNEL_RUNTIME
08116
08117
if ( *NewAcl ==
NULL ) {
08118
Status = STATUS_NO_MEMORY;
08119
goto Cleanup;
08120 }
08121
08122
08123
08124
08125
08126
08127
08128
08129
Status =
RtlCreateAcl( *NewAcl,
08130 RealInheritedAcl->AclSize + NonInheritedAclSize,
08131
max( RealInheritedAcl->AclRevision, ChildAcl->AclRevision ) );
08132
08133
if ( !
NT_SUCCESS(
Status) ) {
08134
#if DBG
08135
if (
RtlpVerboseConvert ) {
08136 KdPrint((
"Can't create final ACL %lX\n",
Status ));
08137 }
08138
#endif // DBG
08139
08140
08141
08142
08143 *NewGenericControl |= SEP_ACL_PROTECTED;
08144
Status = STATUS_SUCCESS;
08145
goto Cleanup;
08146 }
08147
08148
08149
08150
08151
08152 Where = ((PUCHAR)(*NewAcl)) +
sizeof(ACL);
08153
for (ChildAceIndex = 0, ChildAce =
FirstAce(ChildAcl);
08154 ChildAceIndex < ChildAcl->AceCount;
08155 ChildAceIndex += 1, ChildAce =
NextAce(ChildAce)) {
08156
08157 ACCESS_MASK ResultantMask;
08158
08159
08160
08161
08162
08163 ResultantMask =
08164 ChildAceInfo[ChildAceIndex].EffectiveMask |
08165 ChildAceInfo[ChildAceIndex].ContainerInheritMask |
08166 ChildAceInfo[ChildAceIndex].ObjectInheritMask;
08167
08168
if ( ResultantMask != 0 ) {
08169
PKNOWN_ACE NewAce;
08170 ULONG GenericBitToTry;
08171
08172
08173
08174
08175
08176 RtlCopyMemory( Where, ChildAce, ChildAce->Header.AceSize );
08177 NewAce = (
PKNOWN_ACE)Where;
08178 NewAce->
Header.AceFlags &= ~INHERITED_ACE;
08179 Where += ChildAce->Header.AceSize;
08180
08181 (*NewAcl)->AceCount ++;
08182
08183
08184
08185
08186
08187
08188 NewAce->
Mask = ChildAce->Mask & ResultantMask;
08189 ResultantMask &= ~ChildAce->Mask;
08190
#if DBG
08191
if (
RtlpVerboseConvert ) {
08192 KdPrint((
"Original non-inherited: %ld %8.8lX %8.8lX\n", ChildAceIndex, NewAce->
Mask, ResultantMask ));
08193 }
08194
#endif // DBG
08195
08196
08197
08198
08199
08200
08201
08202
08203
ASSERT( GENERIC_WRITE == (GENERIC_READ >> 1));
08204
ASSERT( GENERIC_EXECUTE == (GENERIC_WRITE >> 1));
08205
ASSERT( GENERIC_ALL == (GENERIC_EXECUTE >> 1));
08206
08207 GenericBitToTry = GENERIC_READ;
08208
08209
while ( ResultantMask && GenericBitToTry >= GENERIC_ALL ) {
08210
08211
08212
08213
08214
08215
if ( GenericBitToTry & ChildAce->Mask ) {
08216 ACCESS_MASK GenericMask;
08217
08218
08219
08220
08221
08222 GenericMask = GenericBitToTry;
08223
RtlMapGenericMask( &GenericMask, GenericMapping );
08224
08225
08226
08227
08228
08229
08230
if ( (ResultantMask & GenericMask) != 0 ) {
08231 NewAce->
Mask |= GenericBitToTry;
08232 ResultantMask &= ~GenericMask;
08233 }
08234
#if DBG
08235
if (
RtlpVerboseConvert ) {
08236 KdPrint((
"Generic non-inherited: %ld %8.8lX %8.8lX\n", ChildAceIndex, NewAce->
Mask, ResultantMask ));
08237 }
08238
#endif // DBG
08239
}
08240
08241
08242
08243
08244
08245 GenericBitToTry >>= 1;
08246 }
08247
08248
08249
08250
08251
08252
08253
ASSERT(ResultantMask == 0 );
08254 NewAce->
Mask |= ResultantMask;
08255
#if DBG
08256
if (
RtlpVerboseConvert ) {
08257 KdPrint((
"Final non-inherited: %ld %8.8lX %8.8lX\n", ChildAceIndex, NewAce->
Mask, ResultantMask ));
08258 }
08259
#endif // DBG
08260
08261 }
08262 }
08263
08264
08265
08266
08267
08268
08269 RtlCopyMemory( Where,
08270
FirstAce(RealInheritedAcl),
08271 RealInheritedAcl->AclSize - (ULONG)(((PUCHAR)
FirstAce(RealInheritedAcl)) - (PUCHAR)RealInheritedAcl));
08272 Where += RealInheritedAcl->AclSize - (ULONG)(((PUCHAR)
FirstAce(RealInheritedAcl)) - (PUCHAR)RealInheritedAcl);
08273
08274 (*NewAcl)->AceCount += RealInheritedAcl->AceCount;
08275
ASSERT( (*NewAcl)->AclSize == Where - (PUCHAR)(*NewAcl) );
08276
08277
08278
Status = STATUS_SUCCESS;
08279 Cleanup:
08280
08281
08282
08283
08284
08285
08286
if (
NT_SUCCESS(
Status) ) {
08287
08288
08289
08290
08291
08292
08293
if ( *NewGenericControl & SEP_ACL_PROTECTED ) {
08294
08295
08296
08297
08298
08299
if ( *NewAcl !=
NULL) {
08300
#ifdef NTOS_KERNEL_RUNTIME
08301
ExFreePool( *NewAcl );
08302
#else // NTOS_KERNEL_RUNTIME
08303
RtlFreeHeap(
HeapHandle, 0, *NewAcl );
08304
#endif // NTOS_KERNEL_RUNTIME
08305
*NewAcl =
NULL;
08306 }
08307
08308
08309
08310
08311
08312
#ifdef NTOS_KERNEL_RUNTIME
08313
*NewAcl =
ExAllocatePoolWithTag(
08314
PagedPool,
08315 ChildAcl->AclSize,
08316 'cAeS' );
08317
#else // NTOS_KERNEL_RUNTIME
08318
*NewAcl =
RtlAllocateHeap(
08319
HeapHandle,
08320
MAKE_TAG(
SE_TAG),
08321 ChildAcl->AclSize );
08322
#endif // NTOS_KERNEL_RUNTIME
08323
08324
if ( *NewAcl ==
NULL ) {
08325
Status = STATUS_NO_MEMORY;
08326 }
else {
08327 RtlCopyMemory( *NewAcl, ChildAcl, ChildAcl->AclSize );
08328 }
08329 }
08330
08331 }
08332
08333
if ( ChildAceInfo !=
NULL) {
08334
#ifdef NTOS_KERNEL_RUNTIME
08335
ExFreePool( ChildAceInfo );
08336
#else // NTOS_KERNEL_RUNTIME
08337
RtlFreeHeap(
HeapHandle, 0, ChildAceInfo );
08338
#endif // NTOS_KERNEL_RUNTIME
08339
}
08340
08341
if ( InheritedAcl !=
NULL) {
08342
#ifdef NTOS_KERNEL_RUNTIME
08343
ExFreePool( InheritedAcl );
08344
#else // NTOS_KERNEL_RUNTIME
08345
RtlFreeHeap(
HeapHandle, 0, InheritedAcl );
08346
#endif // NTOS_KERNEL_RUNTIME
08347
}
08348
08349
if ( RealInheritedAcl !=
NULL) {
08350
#ifdef NTOS_KERNEL_RUNTIME
08351
ExFreePool( RealInheritedAcl );
08352
#else // NTOS_KERNEL_RUNTIME
08353
RtlFreeHeap(
HeapHandle, 0, RealInheritedAcl );
08354
#endif // NTOS_KERNEL_RUNTIME
08355
}
08356
08357
return Status;
08358 }
08359
08360
08361 BOOLEAN
08362 RtlpIsDuplicateAce(
08363 IN PACL Acl,
08364 IN
PKNOWN_ACE NewAce,
08365 IN GUID *ObjectType OPTIONAL
08366 )
08367
08368
08369
08370
08371
08372
08373
08374
08375
08376
08377
08378
08379
08380
08381
08382
08383
08384
08385
08386
08387
08388
08389
08390
08391
08392
08393
08394
08395
08396
08397
08398 {
08399
NTSTATUS Status;
08400 BOOLEAN RetVal =
FALSE;
08401
08402 LONG AceIndex;
08403
08404 ACCESS_MASK NewAceContainerInheritMask;
08405 ACCESS_MASK NewAceObjectInheritMask;
08406 ACCESS_MASK NewAceEffectiveMask;
08407
08408 ACCESS_MASK LocalMask;
08409
08410
PKNOWN_ACE AceFromAcl;
08411
08412
RTL_PAGED_CODE();
08413
08414
08415
08416
08417
08418
08419
if ( !IsV4AceType(NewAce) || IsCompoundAceType(NewAce)) {
08420
#if DBG
08421
if (
RtlpVerboseConvert ) {
08422 KdPrint((
"New Ace type (%ld) not known\n", NewAce->Header.AceType ));
08423 }
08424
#endif // DBG
08425
RetVal =
FALSE;
08426
goto Cleanup;
08427 }
08428
08429
08430
08431
08432
08433
if ( (NewAce->Header.AceFlags & INHERITED_ACE ) == 0 ) {
08434
#if DBG
08435
if (
RtlpVerboseConvert ) {
08436 KdPrint((
"New Ace type isn't inherited\n" ));
08437 }
08438
#endif // DBG
08439
RetVal =
FALSE;
08440
goto Cleanup;
08441 }
08442
08443
08444
08445
08446
08447
08448
08449 LocalMask = ((
PKNOWN_ACE)(NewAce))->Mask;
08450
08451
if ( NewAce->Header.AceFlags & CONTAINER_INHERIT_ACE ) {
08452 NewAceContainerInheritMask = LocalMask;
08453 }
else {
08454 NewAceContainerInheritMask = 0;
08455 }
08456
08457
if ( NewAce->Header.AceFlags & OBJECT_INHERIT_ACE ) {
08458 NewAceObjectInheritMask = LocalMask;
08459 }
else {
08460 NewAceObjectInheritMask = 0;
08461 }
08462
08463
if ( (NewAce->Header.AceFlags & INHERIT_ONLY_ACE) == 0 ) {
08464 NewAceEffectiveMask = LocalMask;
08465 }
else {
08466 NewAceEffectiveMask = 0;
08467 }
08468
#if DBG
08469
if (
RtlpVerboseConvert ) {
08470 KdPrint((
"Starting MASKs: %8.8lX %8.8lX %8.8lX", NewAceEffectiveMask, NewAceContainerInheritMask, NewAceObjectInheritMask ));
08471 }
08472
#endif // DBG
08473
08474
08475
08476
08477
08478
08479
08480
08481
for (AceIndex = 0, AceFromAcl =
FirstAce(Acl);
08482 AceIndex < Acl->AceCount-1;
08483 AceIndex += 1, AceFromAcl =
NextAce(AceFromAcl)) {
08484
08485
08486
08487
08488
08489
08490
08491
if ( !IsV4AceType(AceFromAcl) || IsCompoundAceType(AceFromAcl)) {
08492
continue;
08493 }
08494
08495
08496
08497
08498
08499
if ( (AceFromAcl->Header.AceFlags & INHERITED_ACE ) == 0 ) {
08500
continue;
08501 }
08502
08503
08504
08505
08506
08507
08508
08509
08510
08511
#if DBG
08512
if (
RtlpVerboseConvert ) {
08513 KdPrint((
"Compare Ace: %ld ", AceIndex ));
08514 }
08515
#endif // DBG
08516
08517
if (
RtlpCompareAces( AceFromAcl,
08518 NewAce,
08519
NULL,
08520
NULL ) ) {
08521
08522
08523
08524
08525
08526
08527
08528
08529 LocalMask = ((
PKNOWN_ACE)(AceFromAcl))->Mask;
08530
08531
if ( AceFromAcl->Header.AceFlags & CONTAINER_INHERIT_ACE ) {
08532 NewAceContainerInheritMask &= ~LocalMask;
08533 }
08534
08535
if ( AceFromAcl->Header.AceFlags & OBJECT_INHERIT_ACE ) {
08536 NewAceObjectInheritMask &= ~LocalMask;
08537 }
08538
08539
if ( (AceFromAcl->Header.AceFlags & INHERIT_ONLY_ACE) == 0 ) {
08540 NewAceEffectiveMask &= ~LocalMask;
08541 }
08542
08543
#if DBG
08544
if (
RtlpVerboseConvert ) {
08545 KdPrint((
"Remaining MASKs: %8.8lX %8.8lX %8.8lX", NewAceEffectiveMask, NewAceContainerInheritMask, NewAceObjectInheritMask ));
08546 }
08547
#endif // DBG
08548
08549
08550
08551
08552
08553
08554
if ( (NewAceEffectiveMask | NewAceContainerInheritMask | NewAceObjectInheritMask) == 0 ) {
08555
#if DBG
08556
if (
RtlpVerboseConvert ) {
08557 KdPrint((
"\n"));
08558 }
08559
#endif // DBG
08560
RetVal =
TRUE;
08561
goto Cleanup;
08562 }
08563 }
08564
#if DBG
08565
if (
RtlpVerboseConvert ) {
08566 KdPrint((
"\n"));
08567 }
08568
#endif // DBG
08569
08570
08571 }
08572
08573
08574
08575
08576
08577
08578
08579 RetVal =
FALSE;
08580 Cleanup:
08581
08582
return RetVal;
08583
08584 }
08585
08586
08587
NTSTATUS
08588 RtlpCreateServerAcl(
08589 IN PACL Acl,
08590 IN BOOLEAN AclUntrusted,
08591 IN PSID ServerSid,
08592 OUT PACL *ServerAcl,
08593 OUT BOOLEAN *ServerAclAllocated
08594 )
08595
08596
08597
08598
08599
08600
08601
08602
08603
08604
08605
08606
08607
08608
08609
08610
08611
08612
08613
08614 {
08615
USHORT RequiredSize =
sizeof(ACL);
08616
USHORT AceSizeAdjustment;
08617
USHORT ServerSidSize;
08618 PACE_HEADER Ace;
08619 ULONG i;
08620 PVOID Target;
08621 PVOID AcePosition;
08622 PSID UntrustedSid;
08623 PSID ClientSid;
08624
NTSTATUS Status;
08625
08626
RTL_PAGED_CODE();
08627
08628
if (Acl ==
NULL) {
08629 *ServerAclAllocated =
FALSE;
08630 *ServerAcl =
NULL;
08631
return( STATUS_SUCCESS );
08632 }
08633
08634 AceSizeAdjustment =
sizeof( KNOWN_COMPOUND_ACE ) -
sizeof(
KNOWN_ACE );
08635
ASSERT(
sizeof( KNOWN_COMPOUND_ACE ) >=
sizeof(
KNOWN_ACE ) );
08636
08637 ServerSidSize = (
USHORT)
SeLengthSid( ServerSid );
08638
08639
08640
08641
08642
08643
08644
08645
for (i = 0, Ace =
FirstAce(Acl);
08646 i < Acl->AceCount;
08647 i += 1, Ace =
NextAce(Ace)) {
08648
08649
08650
08651
08652
08653
08654
if (Ace->AceType == ACCESS_ALLOWED_ACE_TYPE) {
08655
08656
08657
08658
08659
08660
08661 RequiredSize += ( ServerSidSize + AceSizeAdjustment );
08662
08663 }
else {
08664
08665
if (AclUntrusted && Ace->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE ) {
08666
08667
08668
08669
08670
08671
08672 UntrustedSid = RtlCompoundAceServerSid( Ace );
08673
if ((
USHORT)
SeLengthSid(UntrustedSid) > ServerSidSize) {
08674 RequiredSize += ((
USHORT)
SeLengthSid(UntrustedSid) - ServerSidSize);
08675 }
else {
08676 RequiredSize += (ServerSidSize - (
USHORT)
SeLengthSid(UntrustedSid));
08677
08678 }
08679 }
08680 }
08681
08682 RequiredSize += Ace->AceSize;
08683 }
08684
08685
#ifdef NTOS_KERNEL_RUNTIME
08686
(*ServerAcl) = (PACL)
ExAllocatePoolWithTag(
PagedPool, RequiredSize, 'cAeS' );
08687
#else // NTOS_KERNEL_RUNTIME
08688
(*ServerAcl) = (PACL)
RtlAllocateHeap( RtlProcessHeap(),
MAKE_TAG(
SE_TAG ), RequiredSize );
08689
#endif // NTOS_KERNEL_RUNTIME
08690
08691
if ((*ServerAcl) ==
NULL) {
08692
return STATUS_INSUFFICIENT_RESOURCES;
08693 }
08694
08695
08696
08697
08698
08699 *ServerAclAllocated =
TRUE;
08700
08701
Status =
RtlCreateAcl( (*ServerAcl), RequiredSize, ACL_REVISION3 );
08702
ASSERT(
NT_SUCCESS(
Status ));
08703
08704
for (i = 0, Ace =
FirstAce(Acl), Target=
FirstAce( *ServerAcl );
08705 i < Acl->AceCount;
08706 i += 1, Ace =
NextAce(Ace)) {
08707
08708
08709
08710
08711
08712
if (Ace->AceType == ACCESS_ALLOWED_ACE_TYPE ||
08713 (AclUntrusted && Ace->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE )) {
08714
08715 AcePosition = Target;
08716
08717
if (Ace->AceType == ACCESS_ALLOWED_ACE_TYPE) {
08718 ClientSid = &((
PKNOWN_ACE)Ace)->SidStart;
08719 }
else {
08720 ClientSid = RtlCompoundAceClientSid( Ace );
08721 }
08722
08723
08724
08725
08726
08727 RtlCopyMemory(
08728 Target,
08729 Ace,
08730 FIELD_OFFSET(
KNOWN_ACE, SidStart)
08731 );
08732
08733
08734
08735
08736
08737 Target = ((PCHAR)Target + (UCHAR)(FIELD_OFFSET(KNOWN_COMPOUND_ACE, SidStart)));
08738
08739 RtlCopyMemory(
08740 Target,
08741 ServerSid,
08742
SeLengthSid(ServerSid)
08743 );
08744
08745 Target = ((PCHAR)Target + (UCHAR)
SeLengthSid(ServerSid));
08746
08747
08748
08749
08750
08751
08752 RtlCopyMemory(
08753 Target,
08754 ClientSid,
08755
SeLengthSid(ClientSid)
08756 );
08757
08758 Target = ((PCHAR)Target +
SeLengthSid(ClientSid));
08759
08760
08761
08762
08763
08764 ((PKNOWN_COMPOUND_ACE)AcePosition)->Header.AceSize =
08765 (
USHORT)FIELD_OFFSET(KNOWN_COMPOUND_ACE, SidStart) +
08766 (
USHORT)
SeLengthSid(ServerSid) +
08767 (
USHORT)
SeLengthSid(ClientSid);
08768
08769
08770
08771
08772
08773 ((PKNOWN_COMPOUND_ACE)AcePosition)->Header.AceType = ACCESS_ALLOWED_COMPOUND_ACE_TYPE;
08774 ((PKNOWN_COMPOUND_ACE)AcePosition)->CompoundAceType = COMPOUND_ACE_IMPERSONATION;
08775
08776 }
else {
08777
08778
08779
08780
08781
08782 RtlCopyMemory( Target, Ace, Ace->AceSize );
08783
08784 Target = ((PCHAR)Target + Ace->AceSize);
08785 }
08786 }
08787
08788 (*ServerAcl)->AceCount = Acl->AceCount;
08789
08790
return( STATUS_SUCCESS );
08791 }
08792
08793
#ifndef NTOS_KERNEL_RUNTIME
08794
NTSTATUS
08795 RtlpGetDefaultsSubjectContext(
08796 HANDLE ClientToken,
08797 OUT PTOKEN_OWNER *OwnerInfo,
08798 OUT PTOKEN_PRIMARY_GROUP *GroupInfo,
08799 OUT PTOKEN_DEFAULT_DACL *DefaultDaclInfo,
08800 OUT PTOKEN_OWNER *ServerOwner,
08801 OUT PTOKEN_PRIMARY_GROUP *ServerGroup
08802 )
08803 {
08804 HANDLE
PrimaryToken;
08805 PVOID
HeapHandle;
08806
NTSTATUS Status;
08807 ULONG ServerGroupInfoSize;
08808 ULONG ServerOwnerInfoSize;
08809 ULONG TokenDaclInfoSize;
08810 ULONG TokenGroupInfoSize;
08811 ULONG TokenOwnerInfoSize;
08812
08813 BOOLEAN ClosePrimaryToken =
FALSE;
08814
08815 *OwnerInfo =
NULL;
08816 *GroupInfo =
NULL;
08817 *DefaultDaclInfo =
NULL;
08818 *ServerOwner =
NULL;
08819 *ServerGroup =
NULL;
08820
08821
HeapHandle = RtlProcessHeap();
08822
08823
08824
08825
08826
08827
08828
if (
ClientToken !=
NULL ) {
08829
08830
08831
08832
08833
Status =
NtQueryInformationToken(
08834
ClientToken,
08835 TokenOwner,
08836
NULL,
08837 0,
08838 &TokenOwnerInfoSize
08839 );
08840
08841
if ( STATUS_BUFFER_TOO_SMALL !=
Status ) {
08842
goto Cleanup;
08843 }
08844
08845 *OwnerInfo =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), TokenOwnerInfoSize );
08846
08847
if ( *OwnerInfo ==
NULL ) {
08848
Status = STATUS_NO_MEMORY;
08849
goto Cleanup;
08850 }
08851
08852
Status =
NtQueryInformationToken(
08853
ClientToken,
08854 TokenOwner,
08855 *OwnerInfo,
08856 TokenOwnerInfoSize,
08857 &TokenOwnerInfoSize
08858 );
08859
08860
if (!
NT_SUCCESS(
Status )) {
08861
goto Cleanup;
08862 }
08863
08864
08865
08866
08867
08868
Status =
NtQueryInformationToken(
08869
ClientToken,
08870 TokenPrimaryGroup,
08871 *GroupInfo,
08872 0,
08873 &TokenGroupInfoSize
08874 );
08875
08876
if ( STATUS_BUFFER_TOO_SMALL !=
Status ) {
08877
goto Cleanup;
08878 }
08879
08880 *GroupInfo =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), TokenGroupInfoSize );
08881
08882
if ( *GroupInfo ==
NULL ) {
08883
08884
Status = STATUS_NO_MEMORY;
08885
goto Cleanup;
08886 }
08887
08888
Status =
NtQueryInformationToken(
08889
ClientToken,
08890 TokenPrimaryGroup,
08891 *GroupInfo,
08892 TokenGroupInfoSize,
08893 &TokenGroupInfoSize
08894 );
08895
08896
if (!
NT_SUCCESS(
Status )) {
08897
goto Cleanup;
08898 }
08899
08900
Status =
NtQueryInformationToken(
08901
ClientToken,
08902 TokenDefaultDacl,
08903 *DefaultDaclInfo,
08904 0,
08905 &TokenDaclInfoSize
08906 );
08907
08908
if ( STATUS_BUFFER_TOO_SMALL !=
Status ) {
08909
goto Cleanup;
08910 }
08911
08912 *DefaultDaclInfo =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), TokenDaclInfoSize );
08913
08914
if ( *DefaultDaclInfo ==
NULL ) {
08915
08916
Status = STATUS_NO_MEMORY;
08917
goto Cleanup;
08918 }
08919
08920
Status =
NtQueryInformationToken(
08921
ClientToken,
08922 TokenDefaultDacl,
08923 *DefaultDaclInfo,
08924 TokenDaclInfoSize,
08925 &TokenDaclInfoSize
08926 );
08927
08928
if (!
NT_SUCCESS(
Status )) {
08929
goto Cleanup;
08930 }
08931 }
08932
08933
08934
08935
08936
08937
08938
Status =
NtOpenProcessToken(
08939 NtCurrentProcess(),
08940 TOKEN_QUERY,
08941 &
PrimaryToken
08942 );
08943
08944
if (!
NT_SUCCESS(
Status )) {
08945 ClosePrimaryToken =
FALSE;
08946
goto Cleanup;
08947 }
else {
08948 ClosePrimaryToken =
TRUE;
08949 }
08950
08951
Status =
NtQueryInformationToken(
08952
PrimaryToken,
08953 TokenOwner,
08954
NULL,
08955 0,
08956 &ServerOwnerInfoSize
08957 );
08958
08959
if ( STATUS_BUFFER_TOO_SMALL !=
Status ) {
08960
goto Cleanup;
08961 }
08962
08963 *ServerOwner =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), ServerOwnerInfoSize );
08964
08965
if ( *ServerOwner ==
NULL ) {
08966
Status = STATUS_NO_MEMORY;
08967
goto Cleanup;
08968 }
08969
08970
Status =
NtQueryInformationToken(
08971
PrimaryToken,
08972 TokenOwner,
08973 *ServerOwner,
08974 ServerOwnerInfoSize,
08975 &ServerOwnerInfoSize
08976 );
08977
08978
if (!
NT_SUCCESS(
Status )) {
08979
goto Cleanup;
08980 }
08981
08982
08983
08984
08985
08986
Status =
NtQueryInformationToken(
08987
PrimaryToken,
08988 TokenPrimaryGroup,
08989 *ServerGroup,
08990 0,
08991 &ServerGroupInfoSize
08992 );
08993
08994
if ( STATUS_BUFFER_TOO_SMALL !=
Status ) {
08995
goto Cleanup;
08996 }
08997
08998 *ServerGroup =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), ServerGroupInfoSize );
08999
09000
if ( *ServerGroup ==
NULL ) {
09001
goto Cleanup;
09002 }
09003
09004
Status =
NtQueryInformationToken(
09005
PrimaryToken,
09006 TokenPrimaryGroup,
09007 *ServerGroup,
09008 ServerGroupInfoSize,
09009 &ServerGroupInfoSize
09010 );
09011
09012
if (!
NT_SUCCESS(
Status )) {
09013
goto Cleanup;
09014 }
09015
09016
NtClose(
PrimaryToken );
09017
09018
return( STATUS_SUCCESS );
09019
09020 Cleanup:
09021
09022
if (*OwnerInfo !=
NULL) {
09023
RtlFreeHeap(
HeapHandle, 0, (PVOID)*OwnerInfo );
09024 *OwnerInfo =
NULL;
09025 }
09026
09027
if (*GroupInfo !=
NULL) {
09028
RtlFreeHeap(
HeapHandle, 0, (PVOID)*GroupInfo );
09029 *GroupInfo =
NULL;
09030 }
09031
09032
if (*DefaultDaclInfo !=
NULL) {
09033
RtlFreeHeap(
HeapHandle, 0, (PVOID)*DefaultDaclInfo );
09034 *DefaultDaclInfo =
NULL;
09035 }
09036
09037
if (*ServerOwner !=
NULL) {
09038
RtlFreeHeap(
HeapHandle, 0, (PVOID)*ServerOwner );
09039 *ServerOwner =
NULL;
09040 }
09041
09042
if (*ServerGroup !=
NULL) {
09043
RtlFreeHeap(
HeapHandle, 0, (PVOID)*ServerGroup );
09044 *ServerGroup =
NULL;
09045 }
09046
09047
if (ClosePrimaryToken ==
TRUE) {
09048
NtClose(
PrimaryToken );
09049 }
09050
09051
return(
Status );
09052 }
09053
#endif // NTOS_KERNEL_RUNTIME
09054
09055
09056
NTSTATUS
09057 RtlpNewSecurityObject (
09058 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
09059 IN PSECURITY_DESCRIPTOR CreatorDescriptor OPTIONAL,
09060 OUT PSECURITY_DESCRIPTOR * NewDescriptor,
09061 IN GUID *ObjectType OPTIONAL,
09062 IN BOOLEAN IsDirectoryObject,
09063 IN ULONG AutoInheritFlags,
09064 IN HANDLE Token OPTIONAL,
09065 IN PGENERIC_MAPPING GenericMapping
09066 )
09067
09068
09069
09070
09071
09072
09073
09074
09075
09076
09077
09078
09079
09080
09081
09082
09083
09084
09085
09086
09087
09088
09089
09090
09091
09092
09093
09094
09095
09096
09097
09098
09099
09100
09101
09102
09103
09104
09105
09106
09107
09108
09109
09110
09111
09112
09113
09114
09115
09116
09117
09118
09119
09120
09121
09122
09123
09124
09125
09126
09127
09128
09129
09130
09131
09132
09133
09134
09135
09136
09137
09138
09139
09140
09141
09142
09143
09144
09145
09146
09147
09148
09149
09150
09151
09152
09153
09154
09155
09156
09157
09158
09159
09160
09161
09162
09163
09164
09165
09166
09167
09168
09169
09170
09171
09172
09173
09174
09175
09176
09177
09178
09179
09180
09181
09182
09183
09184
09185
09186
09187
09188
09189
09190
09191
09192
09193
09194
09195
09196
09197
09198
09199
09200
09201
09202
09203
09204
09205
09206
09207
09208
09209
09210
09211
09212
09213
09214
09215
09216
09217
09218
09219
09220
09221
09222
09223
09224
09225
09226
09227
09228
09229
09230
09231
09232
09233
09234
09235
09236
09237
09238
09239
09240
09241
09242
09243 {
09244
09245
09246 SECURITY_DESCRIPTOR *CapturedDescriptor;
09247 SECURITY_DESCRIPTOR InCaseOneNotPassed;
09248 BOOLEAN SecurityDescriptorPassed;
09249
09250
NTSTATUS Status;
09251
09252 PACL NewSacl =
NULL;
09253 BOOLEAN NewSaclInherited =
FALSE;
09254
09255 PACL NewDacl =
NULL;
09256 PACL ServerDacl =
NULL;
09257 BOOLEAN NewDaclInherited =
FALSE;
09258
09259 PSID NewOwner =
NULL;
09260 PSID NewGroup =
NULL;
09261
09262 BOOLEAN SaclExplicitlyAssigned =
FALSE;
09263 BOOLEAN OwnerExplicitlyAssigned =
FALSE;
09264 BOOLEAN DaclExplicitlyAssigned =
FALSE;
09265
09266 BOOLEAN ServerDaclAllocated =
FALSE;
09267
09268 BOOLEAN ServerObject;
09269 BOOLEAN DaclUntrusted;
09270
09271 BOOLEAN HasPrivilege;
09272 PRIVILEGE_SET PrivilegeSet;
09273
09274 PSID SubjectContextOwner =
NULL;
09275 PSID SubjectContextGroup =
NULL;
09276 PSID ServerOwner =
NULL;
09277 PSID ServerGroup =
NULL;
09278
09279 PACL SubjectContextDacl =
NULL;
09280
09281 ULONG AllocationSize;
09282 ULONG NewOwnerSize;
09283 ULONG NewGroupSize;
09284 ULONG NewSaclSize;
09285 ULONG NewDaclSize;
09286
09287 PCHAR Field;
09288 PCHAR Base;
09289
09290
09291
09292 PISECURITY_DESCRIPTOR_RELATIVE INewDescriptor =
NULL;
09293
NTSTATUS PassedStatus;
09294
KPROCESSOR_MODE RequestorMode;
09295
09296 ULONG GenericControl;
09297 ULONG NewControlBits = SE_SELF_RELATIVE;
09298
09299
#ifndef NTOS_KERNEL_RUNTIME
09300
PTOKEN_OWNER TokenOwnerInfo =
NULL;
09301 PTOKEN_PRIMARY_GROUP TokenPrimaryGroupInfo =
NULL;
09302 PTOKEN_DEFAULT_DACL TokenDefaultDaclInfo =
NULL;
09303
09304 PTOKEN_OWNER ServerOwnerInfo =
NULL;
09305 PTOKEN_PRIMARY_GROUP ServerGroupInfo =
NULL;
09306 PVOID
HeapHandle;
09307
09308
#else
09309
09310
09311
09312
09313
09314
09315
PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
09316 PVOID SubjectContextInfo =
NULL;
09317
09318 SubjectSecurityContext = (
PSECURITY_SUBJECT_CONTEXT)
Token;
09319
09320
#endif // NTOS_KERNEL_RUNTIME
09321
09322
09323
#ifdef NTOS_KERNEL_RUNTIME
09324
09325
09326
09327
09328 RequestorMode = KeGetPreviousMode();
09329
#else // NTOS_KERNEL_RUNTIME
09330
RequestorMode =
UserMode;
09331
09332
09333
09334
09335
09336
HeapHandle = RtlProcessHeap();
09337
09338
09339
09340
09341
if (
Token !=
NULL ) {
09342 TOKEN_STATISTICS ThreadTokenStatistics;
09343 ULONG ReturnLength;
09344
09345
Status =
NtQueryInformationToken(
09346
Token,
09347 TokenStatistics,
09348 &ThreadTokenStatistics,
09349
sizeof(TOKEN_STATISTICS),
09350 &ReturnLength
09351 );
09352
09353
if (!
NT_SUCCESS(
Status )) {
09354
return(
Status );
09355 }
09356
09357
09358
09359
09360
09361
09362
if (ThreadTokenStatistics.TokenType == TokenImpersonation) {
09363
09364
if (ThreadTokenStatistics.ImpersonationLevel < SecurityIdentification ) {
09365
09366
return( STATUS_BAD_IMPERSONATION_LEVEL );
09367 }
09368 }
09369
09370 }
09371
#endif // NTOS_KERNEL_RUNTIME
09372
09373
09374
09375
09376
09377
09378
09379
09380
09381
09382
09383
09384
09385
09386
09387
09388
09389
09390
09391
09392
09393
09394
if (ARGUMENT_PRESENT(CreatorDescriptor)) {
09395
09396 CapturedDescriptor = CreatorDescriptor;
09397 SecurityDescriptorPassed =
TRUE;
09398
09399 }
else {
09400
09401
09402
09403
09404
09405 SecurityDescriptorPassed =
FALSE;
09406
09407
RtlCreateSecurityDescriptor(&InCaseOneNotPassed,
09408 SECURITY_DESCRIPTOR_REVISION);
09409 CapturedDescriptor = &InCaseOneNotPassed;
09410
09411 }
09412
09413
09414
if ( CapturedDescriptor->Control & SE_SERVER_SECURITY ) {
09415 ServerObject =
TRUE;
09416 }
else {
09417 ServerObject =
FALSE;
09418 }
09419
09420
if ( CapturedDescriptor->Control & SE_DACL_UNTRUSTED ) {
09421 DaclUntrusted =
TRUE;
09422 }
else {
09423 DaclUntrusted =
FALSE;
09424 }
09425
09426
09427
09428
09429
09430
09431
09432
09433
09434
09435
if (
Token !=
NULL || ServerObject ) {
09436
09437
#ifdef NTOS_KERNEL_RUNTIME
09438
09439 PSID TmpSubjectContextOwner =
NULL;
09440 PSID TmpSubjectContextGroup =
NULL;
09441 PSID TmpServerOwner =
NULL;
09442 PSID TmpServerGroup =
NULL;
09443
09444 PACL TmpSubjectContextDacl =
NULL;
09445
09446 SIZE_T SubjectContextInfoSize = 0;
09447
09448
09449
09450
09451
09452
09453
SeLockSubjectContext( SubjectSecurityContext );
09454
09455
SepGetDefaultsSubjectContext(
09456 SubjectSecurityContext,
09457 &TmpSubjectContextOwner,
09458 &TmpSubjectContextGroup,
09459 &TmpServerOwner,
09460 &TmpServerGroup,
09461 &TmpSubjectContextDacl
09462 );
09463
09464
09465
09466
09467
09468
09469
09470
09471
09472
09473
09474
09475
09476
09477 SubjectContextInfoSize =
SeLengthSid( TmpSubjectContextOwner ) +
09478
SeLengthSid( TmpServerOwner ) +
09479 (TmpSubjectContextGroup !=
NULL ?
SeLengthSid( TmpSubjectContextGroup ) : 0) +
09480 (TmpServerGroup !=
NULL ?
SeLengthSid( TmpServerGroup ) : 0) +
09481 (TmpSubjectContextDacl !=
NULL ? TmpSubjectContextDacl->AclSize : 0);
09482
09483 SubjectContextInfo =
ExAllocatePoolWithTag(
PagedPool, SubjectContextInfoSize, 'dSeS');
09484
09485
if (SubjectContextInfo) {
09486
09487
09488
09489
09490
09491 Base = SubjectContextInfo;
09492
09493
09494
09495
09496
09497 SubjectContextOwner = (PSID)Base;
09498
RtlCopySid(
SeLengthSid( TmpSubjectContextOwner), Base, TmpSubjectContextOwner );
09499 Base +=
SeLengthSid( TmpSubjectContextOwner);
09500
09501
09502
09503
09504
09505
if (TmpSubjectContextGroup !=
NULL) {
09506 SubjectContextGroup = (PSID)Base;
09507
RtlCopySid(
SeLengthSid( TmpSubjectContextGroup), Base, TmpSubjectContextGroup );
09508 Base +=
SeLengthSid( TmpSubjectContextGroup );
09509 }
else {
09510 SubjectContextGroup =
NULL;
09511 }
09512
09513 ServerOwner = (PSID)Base;
09514
RtlCopySid(
SeLengthSid( TmpServerOwner ), Base, TmpServerOwner );
09515 Base +=
SeLengthSid( TmpServerOwner );
09516
09517
09518
09519
09520
09521
if (TmpServerGroup !=
NULL) {
09522 ServerGroup = (PSID)Base;
09523
RtlCopySid(
SeLengthSid( TmpServerGroup ), Base, TmpServerGroup );
09524 Base +=
SeLengthSid( TmpServerGroup );
09525 }
else {
09526 ServerGroup =
NULL;
09527 }
09528
09529
if (TmpSubjectContextDacl !=
NULL) {
09530 SubjectContextDacl = (PACL)Base;
09531 RtlCopyMemory( Base, TmpSubjectContextDacl, TmpSubjectContextDacl->AclSize );
09532
09533 }
else {
09534 SubjectContextDacl =
NULL;
09535 }
09536
09537 }
else {
09538
09539
SeUnlockSubjectContext( SubjectSecurityContext );
09540
09541
return( STATUS_INSUFFICIENT_RESOURCES );
09542 }
09543
09544
SeUnlockSubjectContext( SubjectSecurityContext );
09545
09546
09547
#else // NTOS_KERNEL_RUNTIME
09548
Status =
RtlpGetDefaultsSubjectContext(
09549
Token,
09550 &TokenOwnerInfo,
09551 &TokenPrimaryGroupInfo,
09552 &TokenDefaultDaclInfo,
09553 &ServerOwnerInfo,
09554 &ServerGroupInfo
09555 );
09556
09557
if (!
NT_SUCCESS(
Status )) {
09558
return(
Status );
09559 }
09560
09561 SubjectContextOwner = TokenOwnerInfo->Owner;
09562 SubjectContextGroup = TokenPrimaryGroupInfo->PrimaryGroup;
09563 SubjectContextDacl = TokenDefaultDaclInfo->DefaultDacl;
09564 ServerOwner = ServerOwnerInfo->Owner;
09565 ServerGroup = ServerGroupInfo->PrimaryGroup;
09566
#endif // NTOS_KERNEL_RUNTIME
09567
}
09568
09569
09570
09571
09572
09573
09574
09575 NewOwner = RtlpOwnerAddrSecurityDescriptor(CapturedDescriptor);
09576
09577
if ((NewOwner) !=
NULL) {
09578
09579
09580
09581
09582
09583 OwnerExplicitlyAssigned =
TRUE;
09584
09585 }
else {
09586
09587
09588
09589
09590
09591
09592
if ( AutoInheritFlags & SEF_DEFAULT_OWNER_FROM_PARENT) {
09593
if ( !ARGUMENT_PRESENT(ParentDescriptor) ) {
09594
Status = STATUS_INVALID_OWNER;
09595
goto Cleanup;
09596 }
09597 NewOwner = RtlpOwnerAddrSecurityDescriptor((SECURITY_DESCRIPTOR *)ParentDescriptor);
09598 OwnerExplicitlyAssigned =
TRUE;
09599
09600
if ( NewOwner ==
NULL ) {
09601
Status = STATUS_INVALID_OWNER;
09602
goto Cleanup;
09603 }
09604 }
else {
09605
09606
09607
09608
09609
09610
09611
09612
09613
09614
09615
09616
09617
09618
09619
09620
09621
09622
09623 NewOwner = ServerObject ? ServerOwner : SubjectContextOwner;
09624
09625
09626
09627
09628
09629
if ( NewOwner ==
NULL ) {
09630
Status = STATUS_NO_TOKEN;
09631
goto Cleanup;
09632 }
09633 }
09634 }
09635
09636
09637
09638
09639
09640
09641 NewGroup = RtlpGroupAddrSecurityDescriptor(CapturedDescriptor);
09642
09643
if (NewGroup ==
NULL) {
09644
09645
09646
09647
09648
09649
09650
if ( AutoInheritFlags & SEF_DEFAULT_GROUP_FROM_PARENT) {
09651
if ( !ARGUMENT_PRESENT(ParentDescriptor) ) {
09652
Status = STATUS_INVALID_PRIMARY_GROUP;
09653
goto Cleanup;
09654 }
09655 NewGroup = RtlpGroupAddrSecurityDescriptor((SECURITY_DESCRIPTOR *)ParentDescriptor);
09656 }
else {
09657
09658
09659
09660
09661
09662
09663
09664 NewGroup = ServerObject ? ServerGroup : SubjectContextGroup;
09665 }
09666
09667 }
09668
09669
if (NewGroup !=
NULL) {
09670
if (!
RtlValidSid( NewGroup )) {
09671
Status = STATUS_INVALID_PRIMARY_GROUP;
09672
goto Cleanup;
09673 }
09674 }
else {
09675
Status = STATUS_INVALID_PRIMARY_GROUP;
09676
goto Cleanup;
09677 }
09678
09679
09680
09681
09682
09683
09684
09685
09686
Status =
RtlpInheritAcl (
09687 ARGUMENT_PRESENT(ParentDescriptor) ?
09688 RtlpSaclAddrSecurityDescriptor(
09689 ((SECURITY_DESCRIPTOR *)ParentDescriptor)) :
09690
NULL,
09691 RtlpSaclAddrSecurityDescriptor(CapturedDescriptor),
09692 SeControlSaclToGeneric( CapturedDescriptor->Control ),
09693 IsDirectoryObject,
09694 (BOOLEAN)((AutoInheritFlags & SEF_SACL_AUTO_INHERIT) != 0),
09695 (BOOLEAN)((AutoInheritFlags & SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT) != 0),
09696 NewOwner,
09697 NewGroup,
09698 ServerOwner,
09699 ServerGroup,
09700 GenericMapping,
09701
TRUE,
09702 ObjectType,
09703 &NewSacl,
09704 &SaclExplicitlyAssigned,
09705 &GenericControl );
09706
09707
if (
NT_SUCCESS(
Status) ) {
09708 NewSaclInherited =
TRUE;
09709 NewControlBits |= SE_SACL_PRESENT | SeControlGenericToSacl( GenericControl );
09710
09711 }
else if (
Status == STATUS_NO_INHERITANCE ) {
09712
09713
09714
09715
09716
09717
if ( AutoInheritFlags & SEF_SACL_AUTO_INHERIT) {
09718 NewControlBits |= SE_SACL_AUTO_INHERITED;
09719 }
09720
09721
09722
09723
09724
if ( RtlpAreControlBitsSet( CapturedDescriptor,
09725 SE_SACL_PRESENT | SE_SACL_DEFAULTED ) ) {
09726
09727
09728
09729
09730
09731 NewSacl = RtlpSaclAddrSecurityDescriptor(CapturedDescriptor);
09732 NewControlBits |= SE_SACL_PRESENT;
09733 NewControlBits |= (CapturedDescriptor->Control & SE_SACL_PROTECTED);
09734
09735
09736
09737
09738 SaclExplicitlyAssigned =
TRUE;
09739 }
09740
09741 }
else {
09742
09743
09744
09745
09746
09747
goto Cleanup;
09748 }
09749
09750
09751
09752
09753
09754
09755
09756
09757
Status =
RtlpInheritAcl (
09758 ARGUMENT_PRESENT(ParentDescriptor) ?
09759 RtlpDaclAddrSecurityDescriptor(
09760 ((SECURITY_DESCRIPTOR *)ParentDescriptor)) :
09761
NULL,
09762 RtlpDaclAddrSecurityDescriptor(CapturedDescriptor),
09763 SeControlDaclToGeneric( CapturedDescriptor->Control ),
09764 IsDirectoryObject,
09765 (BOOLEAN)((AutoInheritFlags & SEF_DACL_AUTO_INHERIT) != 0),
09766 (BOOLEAN)((AutoInheritFlags & SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT) != 0),
09767 NewOwner,
09768 NewGroup,
09769 ServerOwner,
09770 ServerGroup,
09771 GenericMapping,
09772
FALSE,
09773 ObjectType,
09774 &NewDacl,
09775 &DaclExplicitlyAssigned,
09776 &GenericControl );
09777
09778
if (
NT_SUCCESS(
Status) ) {
09779 NewDaclInherited =
TRUE;
09780 NewControlBits |= SE_DACL_PRESENT | SeControlGenericToDacl( GenericControl );
09781
09782 }
else if (
Status == STATUS_NO_INHERITANCE ) {
09783
09784
09785
09786
09787
09788
if ( AutoInheritFlags & SEF_DACL_AUTO_INHERIT) {
09789 NewControlBits |= SE_DACL_AUTO_INHERITED;
09790 }
09791
09792
09793
09794
09795
if ( RtlpAreControlBitsSet( CapturedDescriptor,
09796 SE_DACL_PRESENT | SE_DACL_DEFAULTED ) ) {
09797
09798
09799
09800
09801
09802 NewDacl = RtlpDaclAddrSecurityDescriptor(CapturedDescriptor);
09803 NewControlBits |= SE_DACL_PRESENT;
09804 NewControlBits |= (CapturedDescriptor->Control & SE_DACL_PROTECTED);
09805
09806
09807
09808
09809 DaclExplicitlyAssigned =
TRUE;
09810
09811
09812
09813
09814 }
else if (ARGUMENT_PRESENT(SubjectContextDacl)) {
09815
09816 NewDacl = SubjectContextDacl;
09817 NewControlBits |= SE_DACL_PRESENT;
09818
09819 }
09820
09821
09822 }
else {
09823
09824
09825
09826
09827
09828
goto Cleanup;
09829 }
09830
09831
09832
09833
09834
09835
09836
09837
09838
09839
09840
if ( (AutoInheritFlags & SEF_DACL_AUTO_INHERIT) != 0 &&
09841 NewDacl ==
NULL ) {
09842 NewControlBits |= SE_DACL_PROTECTED;
09843 }
09844
09845
09846
09847
09848
09849
09850
09851
09852
if (RequestorMode ==
UserMode) {
09853
09854
09855
09856
09857
09858
09859
09860
09861
09862
09863
if ( SaclExplicitlyAssigned &&
09864 (AutoInheritFlags & SEF_AVOID_PRIVILEGE_CHECK) == 0 ) {
09865
09866
09867
09868
09869
09870
if (
Token ==
NULL ) {
09871
Status = STATUS_NO_TOKEN;
09872
goto Cleanup;
09873 }
09874
09875
#ifdef NTOS_KERNEL_RUNTIME
09876
09877
09878
09879
09880
09881
09882
09883
09884
09885
09886
09887
09888 PrivilegeSet.PrivilegeCount = 1;
09889 PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
09890 PrivilegeSet.Privilege[0].Luid =
SeSecurityPrivilege;
09891 PrivilegeSet.Privilege[0].Attributes = 0;
09892
09893 HasPrivilege =
SePrivilegeCheck(
09894 &PrivilegeSet,
09895 SubjectSecurityContext,
09896 RequestorMode
09897 );
09898
09899
if ( RequestorMode !=
KernelMode ) {
09900
09901
SePrivilegedServiceAuditAlarm (
09902
NULL,
09903 SubjectSecurityContext,
09904 &PrivilegeSet,
09905 HasPrivilege
09906 );
09907 }
09908
09909
#else // NTOS_KERNEL_RUNTIME
09910
09911
09912
09913
09914
09915
09916
09917 PrivilegeSet.PrivilegeCount = 1;
09918 PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
09919 PrivilegeSet.Privilege[0].Luid = RtlConvertLongToLuid(SE_SECURITY_PRIVILEGE);
09920 PrivilegeSet.Privilege[0].Attributes = 0;
09921
09922
Status =
NtPrivilegeCheck(
09923
Token,
09924 &PrivilegeSet,
09925 &HasPrivilege
09926 );
09927
09928
if (!
NT_SUCCESS(
Status )) {
09929
goto Cleanup;
09930 }
09931
09932
#endif // NTOS_KERNEL_RUNTIME
09933
09934
if ( !HasPrivilege ) {
09935
Status = STATUS_PRIVILEGE_NOT_HELD;
09936
goto Cleanup;
09937 }
09938
09939 }
09940
09941
09942
09943
09944
09945
if (OwnerExplicitlyAssigned &&
09946 (AutoInheritFlags & SEF_AVOID_OWNER_CHECK) == 0 ) {
09947
09948
#ifdef NTOS_KERNEL_RUNTIME
09949
09950
09951
if (!
SepValidOwnerSubjectContext(
09952 SubjectSecurityContext,
09953 NewOwner,
09954 ServerObject)
09955 ) {
09956
09957
Status = STATUS_INVALID_OWNER;
09958
goto Cleanup;
09959 }
09960
09961
#else // NTOS_KERNEL_RUNTIME
09962
09963
09964
09965
09966
09967
if (
Token ==
NULL ) {
09968
Status = STATUS_NO_TOKEN;
09969
goto Cleanup;
09970 }
09971
09972
if (!
RtlpValidOwnerSubjectContext(
09973
Token,
09974 NewOwner,
09975 ServerObject,
09976 &PassedStatus) ) {
09977
09978
Status = PassedStatus;
09979
goto Cleanup;
09980 }
09981
#endif // NTOS_KERNEL_RUNTIME
09982
}
09983
09984
09985
09986
09987
09988
09989
09990
if (DaclExplicitlyAssigned && ServerObject) {
09991
09992
Status =
RtlpCreateServerAcl(
09993 NewDacl,
09994 DaclUntrusted,
09995 ServerOwner,
09996 &ServerDacl,
09997 &ServerDaclAllocated
09998 );
09999
10000
if (!
NT_SUCCESS(
Status )) {
10001
goto Cleanup;
10002 }
10003
10004 NewDacl = ServerDacl;
10005 }
10006 }
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018 NewOwnerSize = LongAlignSize(
SeLengthSid(NewOwner));
10019
if (NewGroup !=
NULL) {
10020 NewGroupSize = LongAlignSize(
SeLengthSid(NewGroup));
10021 }
10022
10023
if ((NewControlBits & SE_SACL_PRESENT) && (NewSacl !=
NULL)) {
10024 NewSaclSize = LongAlignSize(NewSacl->AclSize);
10025 }
else {
10026 NewSaclSize = 0;
10027 }
10028
10029
if ( (NewControlBits & SE_DACL_PRESENT) && (NewDacl !=
NULL)) {
10030 NewDaclSize = LongAlignSize(NewDacl->AclSize);
10031 }
else {
10032 NewDaclSize = 0;
10033 }
10034
10035 AllocationSize = LongAlignSize(
sizeof(SECURITY_DESCRIPTOR_RELATIVE)) +
10036 NewOwnerSize +
10037 NewGroupSize +
10038 NewSaclSize +
10039 NewDaclSize;
10040
10041
10042
10043
10044
10045
10046
#ifdef NTOS_KERNEL_RUNTIME
10047
INewDescriptor = (PSECURITY_DESCRIPTOR)
ExAllocatePoolWithTag(
PagedPool, AllocationSize, 'dSeS');
10048
#else // NTOS_KERNEL_RUNTIME
10049
INewDescriptor =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), AllocationSize );
10050
#endif // NTOS_KERNEL_RUNTIME
10051
10052
if ( INewDescriptor ==
NULL ) {
10053
#ifdef NTOS_KERNEL_RUNTIME
10054
Status = STATUS_INSUFFICIENT_RESOURCES;
10055
#else // NTOS_KERNEL_RUNTIME
10056
Status = STATUS_NO_MEMORY;
10057
#endif // NTOS_KERNEL_RUNTIME
10058
goto Cleanup;
10059 }
10060
10061
RtlCreateSecurityDescriptorRelative(
10062 INewDescriptor,
10063 SECURITY_DESCRIPTOR_REVISION
10064 );
10065
10066 RtlpSetControlBits( INewDescriptor, NewControlBits );
10067
10068 Base = (PCHAR)(INewDescriptor);
10069 Field = Base +
sizeof(SECURITY_DESCRIPTOR_RELATIVE);
10070
10071
10072
10073
10074
10075
if (NewControlBits & SE_SACL_PRESENT) {
10076
10077
if (NewSacl !=
NULL) {
10078
10079 RtlCopyMemory( Field, NewSacl, NewSacl->AclSize );
10080
10081
if (!NewSaclInherited) {
10082
RtlpApplyAclToObject( (PACL)Field, GenericMapping );
10083 }
10084
10085 INewDescriptor->Sacl = RtlPointerToOffset(Base,Field);
10086 Field += NewSaclSize;
10087
10088 }
else {
10089
10090 INewDescriptor->Sacl = 0;
10091 }
10092
10093 }
10094
10095
10096
10097
10098
10099
if (NewControlBits & SE_DACL_PRESENT) {
10100
10101
if (NewDacl !=
NULL) {
10102
10103 RtlCopyMemory( Field, NewDacl, NewDacl->AclSize );
10104
10105
if (!NewDaclInherited) {
10106
RtlpApplyAclToObject( (PACL)Field, GenericMapping );
10107 }
10108
10109 INewDescriptor->Dacl = RtlPointerToOffset(Base,Field);
10110 Field += NewDaclSize;
10111
10112 }
else {
10113
10114 INewDescriptor->Dacl = 0;
10115 }
10116
10117 }
10118
10119
10120
10121
10122
10123 RtlCopyMemory( Field, NewOwner,
SeLengthSid(NewOwner) );
10124 INewDescriptor->Owner = RtlPointerToOffset(Base,Field);
10125 Field += NewOwnerSize;
10126
10127
if (NewGroup !=
NULL) {
10128 RtlCopyMemory( Field, NewGroup,
SeLengthSid(NewGroup) );
10129 INewDescriptor->Group = RtlPointerToOffset(Base,Field);
10130 }
10131
10132
Status = STATUS_SUCCESS;
10133
10134
10135
10136 Cleanup:
10137
10138
10139
10140
10141
if (ServerDaclAllocated) {
10142
#ifdef NTOS_KERNEL_RUNTIME
10143
ExFreePool( ServerDacl );
10144
#else // NTOS_KERNEL_RUNTIME
10145
RtlFreeHeap(RtlProcessHeap(), 0, ServerDacl );
10146
#endif // NTOS_KERNEL_RUNTIME
10147
}
10148
10149
10150
10151
10152
10153
10154
#ifdef NTOS_KERNEL_RUNTIME
10155
10156
10157
10158
10159
if (SubjectContextInfo !=
NULL) {
10160
ExFreePool( SubjectContextInfo );
10161 }
10162
10163
#else // NTOS_KERNEL_RUNTIME
10164
RtlFreeHeap(
HeapHandle, 0, (PVOID)TokenOwnerInfo );
10165
RtlFreeHeap(
HeapHandle, 0, (PVOID)TokenPrimaryGroupInfo );
10166
RtlFreeHeap(
HeapHandle, 0, (PVOID)TokenDefaultDaclInfo );
10167
RtlFreeHeap(
HeapHandle, 0, (PVOID)ServerOwnerInfo );
10168
RtlFreeHeap(
HeapHandle, 0, (PVOID)ServerGroupInfo );
10169
#endif // NTOS_KERNEL_RUNTIME
10170
10171
if (NewSaclInherited && NewSacl !=
NULL ) {
10172
#ifdef NTOS_KERNEL_RUNTIME
10173
ExFreePool( NewSacl );
10174
#else // NTOS_KERNEL_RUNTIME
10175
RtlFreeHeap(
HeapHandle, 0, (PVOID)NewSacl );
10176
#endif // NTOS_KERNEL_RUNTIME
10177
}
10178
10179
if (NewDaclInherited && NewDacl !=
NULL ) {
10180
#ifdef NTOS_KERNEL_RUNTIME
10181
ExFreePool( NewDacl );
10182
#else // NTOS_KERNEL_RUNTIME
10183
RtlFreeHeap(
HeapHandle, 0, (PVOID)NewDacl );
10184
#endif // NTOS_KERNEL_RUNTIME
10185
}
10186
10187 *NewDescriptor = (PSECURITY_DESCRIPTOR) INewDescriptor;
10188
10189
10190
return Status;
10191 }
10192
10193
10194
NTSTATUS
10195 RtlpSetSecurityObject (
10196 IN PVOID Object OPTIONAL,
10197 IN SECURITY_INFORMATION SecurityInformation,
10198 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
10199 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
10200 IN ULONG AutoInheritFlags,
10201 IN ULONG PoolType,
10202 IN PGENERIC_MAPPING GenericMapping,
10203 IN HANDLE Token OPTIONAL
10204 )
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305 {
10306 BOOLEAN NewGroupPresent =
FALSE;
10307 BOOLEAN NewOwnerPresent =
FALSE;
10308
10309 BOOLEAN ServerAclAllocated =
FALSE;
10310 BOOLEAN LocalDaclAllocated =
FALSE;
10311 BOOLEAN LocalSaclAllocated =
FALSE;
10312 BOOLEAN ServerObject;
10313 BOOLEAN DaclUntrusted;
10314
10315 PCHAR Field;
10316 PCHAR Base;
10317
10318 PISECURITY_DESCRIPTOR_RELATIVE NewDescriptor =
NULL;
10319
10320
NTSTATUS Status;
10321
10322 TOKEN_STATISTICS ThreadTokenStatistics;
10323
10324 ULONG ReturnLength;
10325
10326 PSID NewGroup;
10327 PSID NewOwner;
10328
10329 PACL NewDacl;
10330 PACL LocalDacl;
10331 PACL NewSacl;
10332 PACL LocalSacl;
10333
10334 ULONG NewDaclSize;
10335 ULONG NewSaclSize;
10336 ULONG NewOwnerSize;
10337 ULONG NewGroupSize;
10338 ULONG AllocationSize;
10339 ULONG ServerOwnerInfoSize;
10340
10341 HANDLE
PrimaryToken;
10342 ULONG GenericControl;
10343 ULONG NewControlBits = SE_SELF_RELATIVE;
10344
10345 PACL ServerDacl;
10346
10347
SECURITY_SUBJECT_CONTEXT SubjectContext;
10348
10349
10350
10351
10352
10353
10354
10355 PISECURITY_DESCRIPTOR IModificationDescriptor =
10356 (PISECURITY_DESCRIPTOR)ModificationDescriptor;
10357
10358 PISECURITY_DESCRIPTOR *IObjectsSecurityDescriptor =
10359 (PISECURITY_DESCRIPTOR *)(ObjectsSecurityDescriptor);
10360
10361
#ifndef NTOS_KERNEL_RUNTIME
10362
PVOID
HeapHandle;
10363
#endif // NTOS_KERNEL_RUNTIME
10364
10365
RTL_PAGED_CODE();
10366
10367
10368
10369
10370
10371
#ifndef NTOS_KERNEL_RUNTIME
10372
HeapHandle = RtlProcessHeap();
10373
#endif // NTOS_KERNEL_RUNTIME
10374
10375
10376
10377
10378
10379
if ( !RtlpAreControlBitsSet(*IObjectsSecurityDescriptor, SE_SELF_RELATIVE) ) {
10380
Status = STATUS_BAD_DESCRIPTOR_FORMAT;
10381
goto Cleanup;
10382 }
10383
10384
10385
10386
10387
10388
10389
10390
if (ARGUMENT_PRESENT(ModificationDescriptor)) {
10391
10392
if ( RtlpAreControlBitsSet(IModificationDescriptor, SE_SERVER_SECURITY)) {
10393 ServerObject =
TRUE;
10394 }
else {
10395 ServerObject =
FALSE;
10396 }
10397
10398
if ( RtlpAreControlBitsSet(IModificationDescriptor, SE_DACL_UNTRUSTED)) {
10399 DaclUntrusted =
TRUE;
10400 }
else {
10401 DaclUntrusted =
FALSE;
10402 }
10403
10404 }
else {
10405
10406 ServerObject =
FALSE;
10407 DaclUntrusted =
FALSE;
10408
10409 }
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
if (SecurityInformation & OWNER_SECURITY_INFORMATION) {
10424
10425 NewOwner = RtlpOwnerAddrSecurityDescriptor( IModificationDescriptor );
10426 NewOwnerPresent =
TRUE;
10427
10428
if ((AutoInheritFlags & SEF_AVOID_PRIVILEGE_CHECK) == 0 ) {
10429
10430
#ifdef NTOS_KERNEL_RUNTIME
10431
10432
SeCaptureSubjectContext( &SubjectContext );
10433
10434
if (!
SepValidOwnerSubjectContext( &SubjectContext, NewOwner, ServerObject ) ) {
10435
10436
SeReleaseSubjectContext( &SubjectContext );
10437
return( STATUS_INVALID_OWNER );
10438
10439 }
else {
10440
10441
SeReleaseSubjectContext( &SubjectContext );
10442 }
10443
#else // NTOS_KERNEL_RUNTIME
10444
10445
if ( ARGUMENT_PRESENT(
Token )) {
10446
10447
Status =
NtQueryInformationToken(
10448
Token,
10449 TokenStatistics,
10450 &ThreadTokenStatistics,
10451
sizeof(TOKEN_STATISTICS),
10452 &ReturnLength
10453 );
10454
10455
if (!
NT_SUCCESS(
Status )) {
10456
goto Cleanup;
10457 }
10458
10459
10460
10461
10462
10463
10464
if (ThreadTokenStatistics.TokenType == TokenImpersonation) {
10465
10466
if (ThreadTokenStatistics.ImpersonationLevel < SecurityIdentification ) {
10467
Status = STATUS_BAD_IMPERSONATION_LEVEL;
10468
goto Cleanup;
10469 }
10470 }
10471
10472 }
else {
10473
10474
Status = STATUS_INVALID_OWNER;
10475
goto Cleanup;
10476 }
10477
10478
if (!
RtlpValidOwnerSubjectContext(
10479
Token,
10480 NewOwner,
10481 ServerObject,
10482 &
Status) ) {
10483
10484
Status = STATUS_INVALID_OWNER;
10485
goto Cleanup;
10486 }
10487
#endif // NTOS_KERNEL_RUNTIME
10488
}
10489
10490 }
else {
10491
10492 NewOwner = RtlpOwnerAddrSecurityDescriptor ( *IObjectsSecurityDescriptor );
10493
if (NewOwner ==
NULL) {
10494
Status = STATUS_INVALID_OWNER;
10495
goto Cleanup;
10496 }
10497
10498 }
10499
ASSERT( NewOwner !=
NULL );
10500
if (!
RtlValidSid( NewOwner )) {
10501
Status = STATUS_INVALID_OWNER;
10502
goto Cleanup;
10503 }
10504
10505
10506
if (SecurityInformation & GROUP_SECURITY_INFORMATION) {
10507
10508 NewGroup = RtlpGroupAddrSecurityDescriptor(IModificationDescriptor);
10509 NewGroupPresent =
TRUE;
10510
10511 }
else {
10512
10513 NewGroup = RtlpGroupAddrSecurityDescriptor( *IObjectsSecurityDescriptor );
10514 }
10515
10516
if (NewGroup !=
NULL) {
10517
if (!
RtlValidSid( NewGroup )) {
10518
Status = STATUS_INVALID_PRIMARY_GROUP;
10519
goto Cleanup;
10520 }
10521 }
else {
10522
Status = STATUS_INVALID_PRIMARY_GROUP;
10523
goto Cleanup;
10524 }
10525
10526
10527
if (SecurityInformation & DACL_SECURITY_INFORMATION) {
10528
10529
10530
10531
10532
10533
10534
if ( AutoInheritFlags & SEF_DACL_AUTO_INHERIT ) {
10535
Status =
RtlpComputeMergedAcl(
10536 RtlpDaclAddrSecurityDescriptor( *IObjectsSecurityDescriptor ),
10537 SeControlDaclToGeneric( (*IObjectsSecurityDescriptor)->Control ),
10538 RtlpDaclAddrSecurityDescriptor( IModificationDescriptor ),
10539 SeControlDaclToGeneric( IModificationDescriptor->Control ),
10540 NewOwner,
10541 NewGroup,
10542 GenericMapping,
10543
FALSE,
10544 &LocalDacl,
10545 &GenericControl );
10546
10547
if ( !
NT_SUCCESS(
Status)) {
10548
goto Cleanup;
10549 }
10550
10551 LocalDaclAllocated =
TRUE;
10552 NewDacl = LocalDacl;
10553 NewControlBits |= SE_DACL_PRESENT;
10554 NewControlBits |= SeControlGenericToDacl( GenericControl );
10555
10556
10557
10558
10559
10560
10561 }
else {
10562 NewDacl = RtlpDaclAddrSecurityDescriptor( IModificationDescriptor );
10563 NewControlBits |= SE_DACL_PRESENT;
10564 NewControlBits |= IModificationDescriptor->Control & SE_DACL_PROTECTED;
10565
10566
10567
10568
10569
10570
10571
if ( RtlpAreControlBitsSet(IModificationDescriptor, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED) ) {
10572 NewControlBits |= SE_DACL_AUTO_INHERITED;
10573 }
10574 }
10575
10576
if (ServerObject) {
10577
10578
#ifdef NTOS_KERNEL_RUNTIME
10579
10580 PSID SubjectContextOwner;
10581 PSID SubjectContextGroup;
10582 PSID SubjectContextServerOwner;
10583 PSID SubjectContextServerGroup;
10584 PACL SubjectContextDacl;
10585
10586
SeCaptureSubjectContext( &SubjectContext );
10587
10588
SepGetDefaultsSubjectContext(
10589 &SubjectContext,
10590 &SubjectContextOwner,
10591 &SubjectContextGroup,
10592 &SubjectContextServerOwner,
10593 &SubjectContextServerGroup,
10594 &SubjectContextDacl
10595 );
10596
10597
Status =
RtlpCreateServerAcl(
10598 NewDacl,
10599 DaclUntrusted,
10600 SubjectContextServerOwner,
10601 &ServerDacl,
10602 &ServerAclAllocated
10603 );
10604
10605
SeReleaseSubjectContext( &SubjectContext );
10606
#else // NTOS_KERNEL_RUNTIME
10607
PTOKEN_OWNER ServerSid;
10608
10609
10610
10611
10612
10613
10614 ServerOwnerInfoSize =
RtlLengthRequiredSid( SID_MAX_SUB_AUTHORITIES );
10615
10616 ServerSid =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), ServerOwnerInfoSize );
10617
10618
if (ServerSid ==
NULL) {
10619
Status = STATUS_NO_MEMORY;
10620
goto Cleanup;
10621 }
10622
10623
Status =
NtOpenProcessToken(
10624 NtCurrentProcess(),
10625 TOKEN_QUERY,
10626 &
PrimaryToken
10627 );
10628
10629
if (!
NT_SUCCESS(
Status )) {
10630
RtlFreeHeap(
HeapHandle, 0, ServerSid );
10631
goto Cleanup;
10632 }
10633
10634
Status =
NtQueryInformationToken(
10635
PrimaryToken,
10636 TokenOwner,
10637 ServerSid,
10638 ServerOwnerInfoSize,
10639 &ServerOwnerInfoSize
10640 );
10641
10642
NtClose(
PrimaryToken );
10643
10644
if (!
NT_SUCCESS(
Status )) {
10645
RtlFreeHeap(
HeapHandle, 0, ServerSid );
10646
goto Cleanup;
10647 }
10648
10649
Status =
RtlpCreateServerAcl(
10650 NewDacl,
10651 DaclUntrusted,
10652 ServerSid->Owner,
10653 &ServerDacl,
10654 &ServerAclAllocated
10655 );
10656
10657
RtlFreeHeap(
HeapHandle, 0, ServerSid );
10658
#endif // NTOS_KERNEL_RUNTIME
10659
10660
if (!
NT_SUCCESS(
Status )) {
10661
goto Cleanup;
10662 }
10663
10664 NewDacl = ServerDacl;
10665
10666 }
10667
10668 }
else {
10669
10670 NewDacl = RtlpDaclAddrSecurityDescriptor( *IObjectsSecurityDescriptor );
10671 }
10672
10673
10674
10675
if (SecurityInformation & SACL_SECURITY_INFORMATION) {
10676
10677
10678
10679
10680
10681
10682
10683
if ( AutoInheritFlags & SEF_SACL_AUTO_INHERIT ) {
10684
Status =
RtlpComputeMergedAcl(
10685 RtlpSaclAddrSecurityDescriptor( *IObjectsSecurityDescriptor ),
10686 SeControlSaclToGeneric( (*IObjectsSecurityDescriptor)->Control ),
10687 RtlpSaclAddrSecurityDescriptor( IModificationDescriptor ),
10688 SeControlSaclToGeneric( IModificationDescriptor->Control ),
10689 NewOwner,
10690 NewGroup,
10691 GenericMapping,
10692
TRUE,
10693 &LocalSacl,
10694 &GenericControl );
10695
10696
if ( !
NT_SUCCESS(
Status)) {
10697
goto Cleanup;
10698 }
10699 LocalSaclAllocated =
TRUE;
10700 NewSacl = LocalSacl;
10701 NewControlBits |= SE_SACL_PRESENT;
10702 NewControlBits |= SeControlGenericToSacl( GenericControl );
10703 }
else {
10704 NewSacl = RtlpSaclAddrSecurityDescriptor( IModificationDescriptor );
10705 NewControlBits |= SE_SACL_PRESENT;
10706 NewControlBits |= IModificationDescriptor->Control & SE_SACL_PROTECTED;
10707
10708
10709
10710
10711
10712
10713
if ( RtlpAreControlBitsSet(IModificationDescriptor, SE_SACL_AUTO_INHERIT_REQ|SE_SACL_AUTO_INHERITED) ) {
10714 NewControlBits |= SE_SACL_AUTO_INHERITED;
10715 }
10716 }
10717
10718 }
else {
10719
10720 NewSacl = RtlpSaclAddrSecurityDescriptor( *IObjectsSecurityDescriptor );
10721 }
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733 NewOwnerSize = LongAlignSize(
SeLengthSid(NewOwner));
10734
10735
if (NewGroup !=
NULL) {
10736 NewGroupSize = LongAlignSize(
SeLengthSid(NewGroup));
10737 }
else {
10738 NewGroupSize = 0;
10739 }
10740
10741
if (NewSacl !=
NULL) {
10742 NewSaclSize = LongAlignSize(NewSacl->AclSize);
10743 }
else {
10744 NewSaclSize = 0;
10745 }
10746
10747
if (NewDacl !=
NULL) {
10748 NewDaclSize = LongAlignSize(NewDacl->AclSize);
10749 }
else {
10750 NewDaclSize = 0;
10751 }
10752
10753 AllocationSize = LongAlignSize(
sizeof(SECURITY_DESCRIPTOR_RELATIVE)) +
10754 NewOwnerSize +
10755 NewGroupSize +
10756 NewSaclSize +
10757 NewDaclSize;
10758
10759
10760
10761
10762
10763
10764
#ifdef NTOS_KERNEL_RUNTIME
10765
NewDescriptor =
ExAllocatePoolWithTag(PoolType, AllocationSize, 'dSeS');
10766
#else // NTOS_KERNEL_RUNTIME
10767
NewDescriptor =
RtlAllocateHeap(
HeapHandle,
MAKE_TAG(
SE_TAG ), AllocationSize );
10768
#endif // NTOS_KERNEL_RUNTIME
10769
10770
if ( NewDescriptor ==
NULL ) {
10771
Status = STATUS_NO_MEMORY;
10772
goto Cleanup;
10773 }
10774
10775
Status =
RtlCreateSecurityDescriptorRelative(
10776 NewDescriptor,
10777 SECURITY_DESCRIPTOR_REVISION
10778 );
10779
10780
ASSERT(
NT_SUCCESS(
Status ) );
10781
10782
#ifdef NTOS_KERNEL_RUNTIME
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
if (ARGUMENT_PRESENT( Object )) {
10793
10794
Status =
ObValidateSecurityQuota(
10795 Object,
10796 NewGroupSize + NewDaclSize
10797 );
10798
10799
if (!
NT_SUCCESS(
Status )) {
10800
10801
10802
10803
10804
10805
ExFreePool( NewDescriptor );
10806
goto Cleanup;
10807 }
10808
10809 }
10810
#endif // NTOS_KERNEL_RUNTIME
10811
10812
10813 Base = (PCHAR)NewDescriptor;
10814 Field = Base +
sizeof(SECURITY_DESCRIPTOR_RELATIVE);
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839 RtlpSetControlBits( NewDescriptor, NewControlBits );
10840
10841
10842
if (IModificationDescriptor->Control & SE_RM_CONTROL_VALID) {
10843 NewDescriptor->Sbz1 = IModificationDescriptor->Sbz1;
10844 NewDescriptor->Control |= SE_RM_CONTROL_VALID;
10845 }
10846
10847
if (NewSacl ==
NULL) {
10848 NewDescriptor->Sacl = 0;
10849
10850 }
else {
10851 RtlCopyMemory( Field, NewSacl, NewSacl->AclSize );
10852
RtlpApplyAclToObject( (PACL)Field, GenericMapping );
10853 NewDescriptor->Sacl = RtlPointerToOffset(Base,Field);
10854 Field += NewSaclSize;
10855 }
10856
10857
10858
10859
10860
if ( (NewControlBits & SE_SACL_PRESENT) == 0 ) {
10861
10862
10863
10864
10865
10866
10867
10868 RtlpPropagateControlBits(
10869 NewDescriptor,
10870 *IObjectsSecurityDescriptor,
10871 SE_SACL_DEFAULTED | SE_SACL_PRESENT | SE_SACL_PROTECTED
10872 );
10873
10874 }
10875
10876
10877
10878
10879
10880
10881
10882
if (NewDacl ==
NULL) {
10883 NewDescriptor->Dacl = 0;
10884
10885 }
else {
10886 RtlCopyMemory( Field, NewDacl, NewDacl->AclSize );
10887
RtlpApplyAclToObject( (PACL)Field, GenericMapping );
10888 NewDescriptor->Dacl = RtlPointerToOffset(Base,Field);
10889 Field += NewDaclSize;
10890 }
10891
10892
10893
if ( (NewControlBits & SE_DACL_PRESENT) == 0 ) {
10894
10895
10896
10897
10898
10899
10900
10901 RtlpPropagateControlBits(
10902 NewDescriptor,
10903 *IObjectsSecurityDescriptor,
10904 SE_DACL_DEFAULTED | SE_DACL_PRESENT | SE_DACL_PROTECTED
10905 );
10906
10907 }
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932 RtlCopyMemory( Field, NewOwner,
SeLengthSid(NewOwner) );
10933 NewDescriptor->Owner = RtlPointerToOffset(Base,Field);
10934 Field += NewOwnerSize;
10935
10936
if (!NewOwnerPresent) {
10937
10938
10939
10940
10941
10942
10943
10944 RtlpPropagateControlBits(
10945 NewDescriptor,
10946 *IObjectsSecurityDescriptor,
10947 SE_OWNER_DEFAULTED
10948 );
10949
10950 }
else {
10951
ASSERT( !RtlpAreControlBitsSet( NewDescriptor, SE_OWNER_DEFAULTED ) );
10952 }
10953
10954
10955
10956
10957
10958
10959
if ( NewGroup !=
NULL) {
10960 RtlCopyMemory( Field, NewGroup,
SeLengthSid(NewGroup) );
10961 NewDescriptor->Group = RtlPointerToOffset(Base,Field);
10962 }
10963
10964
if (!NewGroupPresent) {
10965
10966
10967
10968
10969
10970
10971
10972 RtlpPropagateControlBits(
10973 NewDescriptor,
10974 *IObjectsSecurityDescriptor,
10975 SE_GROUP_DEFAULTED
10976 );
10977 }
else {
10978
ASSERT( !RtlpAreControlBitsSet( NewDescriptor, SE_GROUP_DEFAULTED ) );
10979
10980 }
10981
10982
10983
10984
10985
10986
10987
#ifndef NTOS_KERNEL_RUNTIME
10988
RtlFreeHeap(
HeapHandle, 0, (PVOID) *IObjectsSecurityDescriptor );
10989
#endif // NTOS_KERNEL_RUNTIME
10990
10991 *ObjectsSecurityDescriptor = (PSECURITY_DESCRIPTOR)NewDescriptor;
10992
Status = STATUS_SUCCESS;
10993
10994 Cleanup:
10995
if ( LocalDaclAllocated ) {
10996
#ifdef NTOS_KERNEL_RUNTIME
10997
ExFreePool( LocalDacl );
10998
#else // NTOS_KERNEL_RUNTIME
10999
RtlFreeHeap(
HeapHandle, 0, LocalDacl );
11000
#endif // NTOS_KERNEL_RUNTIME
11001
}
11002
if ( LocalSaclAllocated ) {
11003
#ifdef NTOS_KERNEL_RUNTIME
11004
ExFreePool( LocalSacl );
11005
#else // NTOS_KERNEL_RUNTIME
11006
RtlFreeHeap(
HeapHandle, 0, LocalSacl );
11007
#endif // NTOS_KERNEL_RUNTIME
11008
}
11009
if (ServerAclAllocated) {
11010
#ifdef NTOS_KERNEL_RUNTIME
11011
ExFreePool( ServerDacl );
11012
#else // NTOS_KERNEL_RUNTIME
11013
RtlFreeHeap(
HeapHandle, 0, ServerDacl );
11014
#endif // NTOS_KERNEL_RUNTIME
11015
}
11016
11017
return(
Status );
11018 }
11019
11020 BOOLEAN
RtlpValidateSDOffsetAndSize (
11021 IN ULONG Offset,
11022 IN ULONG Length,
11023 IN ULONG MinLength,
11024 OUT PULONG MaxLength
11025 )
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050 {
11051 ULONG Left;
11052
11053 *MaxLength = 0;
11054
11055
11056
11057
if (
Offset <
sizeof (SECURITY_DESCRIPTOR_RELATIVE)) {
11058
return FALSE;
11059 }
11060
11061
11062
11063
11064
if (
Offset >= Length) {
11065
return FALSE;
11066 }
11067
11068
11069
11070
11071 Left = Length -
Offset;
11072
11073
if (Left < MinLength) {
11074
return FALSE;
11075 }
11076
11077
11078
11079
11080
if (
Offset & (
sizeof (ULONG) - 1)) {
11081
return FALSE;
11082 }
11083 *MaxLength = Left;
11084
return TRUE;
11085 }
11086
11087
11088 BOOLEAN
11089 RtlValidRelativeSecurityDescriptor (
11090 IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
11091 IN ULONG SecurityDescriptorLength,
11092 IN SECURITY_INFORMATION RequiredInformation
11093 )
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124 {
11125 PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor;
11126 PISID OwnerSid;
11127 PISID GroupSid;
11128 PACE_HEADER Ace;
11129 PACL
Dacl;
11130 PACL Sacl;
11131 ULONG MaxOwnerSidLength;
11132 ULONG MaxGroupSidLength;
11133 ULONG MaxDaclLength;
11134 ULONG MaxSaclLength;
11135
11136
if (SecurityDescriptorLength <
sizeof(SECURITY_DESCRIPTOR_RELATIVE)) {
11137
return FALSE;
11138 }
11139
11140
11141
11142
11143
11144
if (((PISECURITY_DESCRIPTOR) SecurityDescriptorInput)->Revision !=
11145 SECURITY_DESCRIPTOR_REVISION) {
11146
return FALSE;
11147 }
11148
11149
11150
11151
11152
11153
if (!(((PISECURITY_DESCRIPTOR) SecurityDescriptorInput)->Control & SE_SELF_RELATIVE)) {
11154
return FALSE;
11155 }
11156
11157 SecurityDescriptor = (PISECURITY_DESCRIPTOR_RELATIVE) SecurityDescriptorInput;
11158
11159
11160
11161
11162
if (SecurityDescriptor->Owner == 0) {
11163
if (RequiredInformation & OWNER_SECURITY_INFORMATION) {
11164
return FALSE;
11165 }
11166 }
else {
11167
if (!
RtlpValidateSDOffsetAndSize (SecurityDescriptor->Owner,
11168 SecurityDescriptorLength,
11169 sizeof (SID),
11170 &MaxOwnerSidLength)) {
11171
return FALSE;
11172 }
11173
11174
11175
11176
11177
11178 OwnerSid = (PSID)RtlOffsetToPointer (SecurityDescriptor,
11179 SecurityDescriptor->Owner);
11180
11181
if (OwnerSid->Revision != SID_REVISION) {
11182
return FALSE;
11183 }
11184
11185
if (OwnerSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
11186
return FALSE;
11187 }
11188
11189
if (MaxOwnerSidLength < (ULONG)
SeLengthSid (OwnerSid)) {
11190
return FALSE;
11191 }
11192
11193 }
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
if (SecurityDescriptor->Group == 0) {
11204
if (RequiredInformation & GROUP_SECURITY_INFORMATION) {
11205
return FALSE;
11206 }
11207 }
else {
11208
if (!
RtlpValidateSDOffsetAndSize (SecurityDescriptor->Group,
11209 SecurityDescriptorLength,
11210 sizeof (SID),
11211 &MaxGroupSidLength)) {
11212
return FALSE;
11213 }
11214
11215
11216
11217
11218
11219 GroupSid = (PSID)RtlOffsetToPointer (SecurityDescriptor,
11220 SecurityDescriptor->Group);
11221
11222
if (GroupSid->Revision != SID_REVISION) {
11223
return FALSE;
11224 }
11225
11226
if (GroupSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
11227
return FALSE;
11228 }
11229
11230
if (MaxGroupSidLength < (ULONG)
SeLengthSid (GroupSid)) {
11231
return FALSE;
11232 }
11233
11234 }
11235
11236
11237
11238
11239
11240
if (!RtlpAreControlBitsSet (SecurityDescriptor, SE_DACL_PRESENT)) {
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253 }
else if (SecurityDescriptor->Dacl) {
11254
if (!
RtlpValidateSDOffsetAndSize (SecurityDescriptor->Dacl,
11255 SecurityDescriptorLength,
11256 sizeof (ACL),
11257 &MaxDaclLength)) {
11258
return FALSE;
11259 }
11260
11261
Dacl = (PACL) RtlOffsetToPointer (SecurityDescriptor,
11262 SecurityDescriptor->Dacl);
11263
11264
11265
11266
11267
if (MaxDaclLength <
Dacl->AclSize) {
11268
return FALSE;
11269 }
11270
11271
11272
11273
11274
if (!
RtlValidAcl (
Dacl)) {
11275
return FALSE;
11276 }
11277 }
11278
11279
11280
11281
11282
11283
if (!RtlpAreControlBitsSet (SecurityDescriptor, SE_SACL_PRESENT)) {
11284
11285
11286
11287 }
else if (SecurityDescriptor->Sacl) {
11288
if (!
RtlpValidateSDOffsetAndSize (SecurityDescriptor->Sacl,
11289 SecurityDescriptorLength,
11290 sizeof (ACL),
11291 &MaxSaclLength)) {
11292
return FALSE;
11293 }
11294
11295 Sacl = (PACL) RtlOffsetToPointer (SecurityDescriptor,
11296 SecurityDescriptor->Sacl);
11297
11298
11299
11300
11301
11302
if (MaxSaclLength < Sacl->AclSize) {
11303
return FALSE;
11304 }
11305
11306
11307
11308
11309
11310
if (!
RtlValidAcl (Sacl)) {
11311
return FALSE;
11312 }
11313 }
11314
11315
return TRUE;
11316 }
11317
11318
11319
11320
11321
11322 BOOLEAN
11323 RtlGetSecurityDescriptorRMControl(
11324 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
11325 OUT PUCHAR RMControl
11326 )
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354 {
11355 PISECURITY_DESCRIPTOR ISecurityDescriptor = (PISECURITY_DESCRIPTOR) SecurityDescriptor;
11356
11357
if (!(ISecurityDescriptor->Control & SE_RM_CONTROL_VALID))
11358 {
11359 *RMControl = 0;
11360
return FALSE;
11361 }
11362
11363 *RMControl = ISecurityDescriptor->Sbz1;
11364
11365
return TRUE;
11366 }
11367
11368
11369
VOID
11370 RtlSetSecurityDescriptorRMControl(
11371 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
11372 IN PUCHAR RMControl OPTIONAL
11373 )
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395 {
11396 PISECURITY_DESCRIPTOR ISecurityDescriptor = (PISECURITY_DESCRIPTOR) SecurityDescriptor;
11397
11398
if (ARGUMENT_PRESENT(RMControl)) {
11399 ISecurityDescriptor->Control |= SE_RM_CONTROL_VALID;
11400 ISecurityDescriptor->Sbz1 = *RMControl;
11401 }
else {
11402 ISecurityDescriptor->Control &= ~SE_RM_CONTROL_VALID;
11403 ISecurityDescriptor->Sbz1 = 0;
11404 }
11405 }