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
#include <ntos.h>
00028
#include <nturtl.h>
00029
#include <ntlsa.h>
00030
#include "seopaque.h"
00031
#include "sertlp.h"
00032
#include "ldrp.h"
00033
00034
00035
00036
00037
00039
00040
00041
00043
00044
00045
#if WHEN_LSAUDLL_MOVED_TO_NTDLL
00046
NTSTATUS
00047 RtlGetPrimaryDomain(
00048 IN ULONG SidLength,
00049 OUT PBOOLEAN PrimaryDomainPresent,
00050 OUT PUNICODE_STRING PrimaryDomainName,
00051 OUT PUSHORT RequiredNameLength,
00052 OUT PSID PrimaryDomainSid OPTIONAL,
00053 OUT PULONG RequiredSidLength
00054 )
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 {
00113
NTSTATUS Status, IgnoreStatus;
00114 OBJECT_ATTRIBUTES
ObjectAttributes;
00115 LSA_HANDLE LsaHandle;
00116 SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
00117 PPOLICY_PRIMARY_DOMAIN_INFO PrimaryDomainInfo;
00118
00119
00120
00121
00122
00123
00124 SecurityQualityOfService.Length =
sizeof(SECURITY_QUALITY_OF_SERVICE);
00125 SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
00126 SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
00127 SecurityQualityOfService.EffectiveOnly =
FALSE;
00128
00129
00130
00131
00132
00133 InitializeObjectAttributes(&ObjectAttributes,
00134 NULL,
00135 0L,
00136 (HANDLE)NULL,
00137 NULL);
00138
ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
00139
00140
00141
00142
00143
00144
Status = LsaOpenPolicy( NULL,
00145 &ObjectAttributes,
00146 POLICY_VIEW_LOCAL_INFORMATION,
00147 &LsaHandle
00148 );
00149
if (
NT_SUCCESS(Status)) {
00150
00151
00152
00153
00154
Status = LsaQueryInformationPolicy(LsaHandle,
00155 PolicyPrimaryDomainInformation,
00156 (PVOID *)&PrimaryDomainInfo);
00157 IgnoreStatus = LsaClose(LsaHandle);
00158
ASSERT(
NT_SUCCESS(IgnoreStatus));
00159 }
00160
00161
if (
NT_SUCCESS(Status)) {
00162
00163
00164
00165
00166
00167
if (PrimaryDomainInfo->Sid !=
NULL) {
00168
00169
00170
00171
00172
00173 (*PrimaryDomainPresent) =
TRUE;
00174 (*RequiredNameLength) = PrimaryDomainInfo->Name.Length;
00175 (*RequiredSidLength) =
RtlLengthSid(PrimaryDomainInfo->Sid);
00176
00177
00178
00179
00180
00181
00182
00183
if (PrimaryDomainName->MaximumLength >=
00184 PrimaryDomainInfo->Name.Length) {
00185
RtlCopyUnicodeString(
00186 PrimaryDomainName,
00187 &PrimaryDomainInfo->Name
00188 );
00189 }
else {
00190
Status = STATUS_BUFFER_TOO_SMALL;
00191 }
00192
00193
00194
00195
00196
00197
00198
if (PrimaryDomainSid !=
NULL &&
NT_SUCCESS(Status)) {
00199
00200
Status =
RtlCopySid(SidLength,
00201 PrimaryDomainSid,
00202 PrimaryDomainInfo->Sid
00203 );
00204 }
00205 }
else {
00206
00207 (*PrimaryDomainPresent) =
FALSE;
00208 }
00209
00210
00211
00212
00213
00214 IgnoreStatus = LsaFreeMemory(PrimaryDomainInfo);
00215
ASSERT(
NT_SUCCESS(IgnoreStatus));
00216
00217 }
00218
00219
00220
return(
Status);
00221 }
00222
#endif //WHEN_LSAUDLL_MOVED_TO_NTDLL
00223
00224
00225
NTSTATUS
00226 RtlNewSecurityObjectEx (
00227 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
00228 IN PSECURITY_DESCRIPTOR CreatorDescriptor OPTIONAL,
00229 OUT PSECURITY_DESCRIPTOR * NewDescriptor,
00230 IN GUID *ObjectType OPTIONAL,
00231 IN BOOLEAN IsDirectoryObject,
00232 IN ULONG AutoInheritFlags,
00233 IN HANDLE Token OPTIONAL,
00234 IN PGENERIC_MAPPING GenericMapping
00235 )
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 {
00259
00260
00261
00262
00263
00264
return RtlpNewSecurityObject (
00265 ParentDescriptor,
00266 CreatorDescriptor,
00267 NewDescriptor,
00268 ObjectType,
00269 IsDirectoryObject,
00270 AutoInheritFlags,
00271
Token,
00272 GenericMapping );
00273
00274 }
00275
00276
00277
00278
00279
NTSTATUS
00280 RtlNewSecurityObject (
00281 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
00282 IN PSECURITY_DESCRIPTOR CreatorDescriptor OPTIONAL,
00283 OUT PSECURITY_DESCRIPTOR * NewDescriptor,
00284 IN BOOLEAN IsDirectoryObject,
00285 IN HANDLE Token,
00286 IN PGENERIC_MAPPING GenericMapping
00287 )
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 {
00311
00312
00313
00314
00315
00316
return RtlpNewSecurityObject (
00317 ParentDescriptor,
00318 CreatorDescriptor,
00319 NewDescriptor,
00320
NULL,
00321 IsDirectoryObject,
00322 0,
00323
Token,
00324 GenericMapping );
00325
00326 }
00327
00328
00329
00330
NTSTATUS
00331 RtlSetSecurityObject (
00332 IN SECURITY_INFORMATION SecurityInformation,
00333 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
00334 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
00335 IN PGENERIC_MAPPING GenericMapping,
00336 IN HANDLE Token OPTIONAL
00337 )
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 {
00355
00356
00357
00358
00359
00360
return RtlpSetSecurityObject(
NULL,
00361 SecurityInformation,
00362 ModificationDescriptor,
00363 ObjectsSecurityDescriptor,
00364 0,
00365
PagedPool,
00366 GenericMapping,
00367
Token );
00368 }
00369
00370
00371
00372
NTSTATUS
00373 RtlSetSecurityObjectEx (
00374 IN SECURITY_INFORMATION SecurityInformation,
00375 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
00376 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
00377 IN ULONG AutoInheritFlags,
00378 IN PGENERIC_MAPPING GenericMapping,
00379 IN HANDLE Token OPTIONAL
00380 )
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 {
00398
00399
00400
00401
00402
00403
return RtlpSetSecurityObject(
NULL,
00404 SecurityInformation,
00405 ModificationDescriptor,
00406 ObjectsSecurityDescriptor,
00407 AutoInheritFlags,
00408
PagedPool,
00409 GenericMapping,
00410
Token );
00411 }
00412
00413
00414
00415
00416
00417
NTSTATUS
00418 RtlQuerySecurityObject (
00419 IN PSECURITY_DESCRIPTOR ObjectDescriptor,
00420 IN SECURITY_INFORMATION SecurityInformation,
00421 OUT PSECURITY_DESCRIPTOR ResultantDescriptor,
00422 IN ULONG DescriptorLength,
00423 OUT PULONG ReturnLength
00424 )
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 {
00485
00486 PSID
Group;
00487 PSID
Owner;
00488 PACL
Dacl;
00489 PACL Sacl;
00490
00491 ULONG GroupSize = 0;
00492 ULONG DaclSize = 0;
00493 ULONG SaclSize = 0;
00494 ULONG OwnerSize = 0;
00495
00496 PCHAR Field;
00497 PCHAR Base;
00498
00499
00500 PISECURITY_DESCRIPTOR IObjectDescriptor;
00501 PISECURITY_DESCRIPTOR_RELATIVE IResultantDescriptor;
00502
00503
00504 IResultantDescriptor = (PISECURITY_DESCRIPTOR_RELATIVE)ResultantDescriptor;
00505 IObjectDescriptor = (PISECURITY_DESCRIPTOR)ObjectDescriptor;
00506
00507
00508
00509
00510
00511
00512
00513
if (SecurityInformation & GROUP_SECURITY_INFORMATION) {
00514
00515
Group = RtlpGroupAddrSecurityDescriptor(IObjectDescriptor);
00516 GroupSize = LongAlignSize(
SeLengthSid(
Group));
00517 }
00518
00519
if (SecurityInformation & DACL_SECURITY_INFORMATION) {
00520
00521
Dacl = RtlpDaclAddrSecurityDescriptor( IObjectDescriptor );
00522
00523
if (
Dacl !=
NULL) {
00524 DaclSize = LongAlignSize(
Dacl->AclSize);
00525 }
00526 }
00527
00528
if (SecurityInformation & SACL_SECURITY_INFORMATION) {
00529
00530 Sacl = RtlpSaclAddrSecurityDescriptor( IObjectDescriptor );
00531
00532
if (Sacl !=
NULL) {
00533 SaclSize = LongAlignSize(Sacl->AclSize);
00534 }
00535
00536 }
00537
00538
if (SecurityInformation & OWNER_SECURITY_INFORMATION) {
00539
00540
Owner = RtlpOwnerAddrSecurityDescriptor ( IObjectDescriptor );
00541 OwnerSize = LongAlignSize(
SeLengthSid(
Owner));
00542 }
00543
00544 *ReturnLength =
sizeof( SECURITY_DESCRIPTOR_RELATIVE ) +
00545 GroupSize +
00546 DaclSize +
00547 SaclSize +
00548 OwnerSize;
00549
00550
if (*ReturnLength > DescriptorLength) {
00551
return( STATUS_BUFFER_TOO_SMALL );
00552 }
00553
00554
RtlCreateSecurityDescriptor(
00555 IResultantDescriptor,
00556 SECURITY_DESCRIPTOR_REVISION
00557 );
00558
00559 RtlpSetControlBits( IResultantDescriptor, SE_SELF_RELATIVE );
00560
00561 Base = (PCHAR)(IResultantDescriptor);
00562 Field = Base + (ULONG)
sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00563
00564
if (SecurityInformation & SACL_SECURITY_INFORMATION) {
00565
00566
if (SaclSize > 0) {
00567 RtlMoveMemory( Field, Sacl, SaclSize );
00568 IResultantDescriptor->Sacl = RtlPointerToOffset(Base,Field);
00569 Field += SaclSize;
00570 }
00571
00572 RtlpPropagateControlBits(
00573 IResultantDescriptor,
00574 IObjectDescriptor,
00575 SE_SACL_PRESENT | SE_SACL_DEFAULTED
00576 );
00577 }
00578
00579
if (SecurityInformation & DACL_SECURITY_INFORMATION) {
00580
00581
if (DaclSize > 0) {
00582 RtlMoveMemory( Field,
Dacl, DaclSize );
00583 IResultantDescriptor->Dacl = RtlPointerToOffset(Base,Field);
00584 Field += DaclSize;
00585 }
00586
00587 RtlpPropagateControlBits(
00588 IResultantDescriptor,
00589 IObjectDescriptor,
00590 SE_DACL_PRESENT | SE_DACL_DEFAULTED
00591 );
00592 }
00593
00594
if (SecurityInformation & OWNER_SECURITY_INFORMATION) {
00595
00596
if (OwnerSize > 0) {
00597 RtlMoveMemory( Field,
Owner, OwnerSize );
00598 IResultantDescriptor->Owner = RtlPointerToOffset(Base,Field);
00599 Field += OwnerSize;
00600 }
00601
00602 RtlpPropagateControlBits(
00603 IResultantDescriptor,
00604 IObjectDescriptor,
00605 SE_OWNER_DEFAULTED
00606 );
00607
00608 }
00609
00610
if (SecurityInformation & GROUP_SECURITY_INFORMATION) {
00611
00612
if (GroupSize > 0) {
00613 RtlMoveMemory( Field,
Group, GroupSize );
00614 IResultantDescriptor->Group = RtlPointerToOffset(Base,Field);
00615 }
00616
00617 RtlpPropagateControlBits(
00618 IResultantDescriptor,
00619 IObjectDescriptor,
00620 SE_GROUP_DEFAULTED
00621 );
00622 }
00623
00624
return( STATUS_SUCCESS );
00625
00626 }
00627
00628
00629
00630
00631
00632
NTSTATUS
00633 RtlDeleteSecurityObject (
00634 IN OUT PSECURITY_DESCRIPTOR * ObjectDescriptor
00635 )
00636
00637
00638
00639
00640
00641
00642
00643
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
RtlFreeHeap( RtlProcessHeap(), 0, (PVOID)*ObjectDescriptor );
00671
00672
return( STATUS_SUCCESS );
00673
00674 }
00675
00676
00677
00678
00679
NTSTATUS
00680 RtlNewInstanceSecurityObject(
00681 IN BOOLEAN ParentDescriptorChanged,
00682 IN BOOLEAN CreatorDescriptorChanged,
00683 IN PLUID OldClientTokenModifiedId,
00684 OUT PLUID NewClientTokenModifiedId,
00685 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
00686 IN PSECURITY_DESCRIPTOR CreatorDescriptor OPTIONAL,
00687 OUT PSECURITY_DESCRIPTOR * NewDescriptor,
00688 IN BOOLEAN IsDirectoryObject,
00689 IN HANDLE Token,
00690 IN PGENERIC_MAPPING GenericMapping
00691 )
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757 {
00758
00759 TOKEN_STATISTICS
ClientTokenStatistics;
00760 ULONG ReturnLength;
00761
NTSTATUS Status;
00762
00763
00764
00765
00766
00767
00768
00769
00770
Status =
NtQueryInformationToken(
00771
Token,
00772 TokenStatistics,
00773 &
ClientTokenStatistics,
00774
sizeof(TOKEN_STATISTICS),
00775 &ReturnLength
00776 );
00777
00778
if ( !
NT_SUCCESS(
Status )) {
00779
return(
Status );
00780 }
00781
00782 *NewClientTokenModifiedId =
ClientTokenStatistics.ModifiedId;
00783
00784
if (
RtlEqualLuid(NewClientTokenModifiedId, OldClientTokenModifiedId) ) {
00785
00786
if ( !(ParentDescriptorChanged || CreatorDescriptorChanged) ) {
00787
00788
00789
00790
00791
00792
00793
00794 *NewDescriptor =
NULL;
00795
return( STATUS_SUCCESS );
00796
00797 }
00798 }
00799
00800
00801
00802
00803
00804
00805
return(
RtlNewSecurityObject( ParentDescriptor,
00806 CreatorDescriptor,
00807 NewDescriptor,
00808 IsDirectoryObject,
00809
Token,
00810 GenericMapping
00811 ));
00812 }
00813
00814
00815
00816
00817
NTSTATUS
00818 RtlNewSecurityGrantedAccess(
00819 IN ACCESS_MASK DesiredAccess,
00820 OUT PPRIVILEGE_SET Privileges,
00821 IN OUT PULONG Length,
00822 IN HANDLE Token OPTIONAL,
00823 IN PGENERIC_MAPPING GenericMapping,
00824 OUT PACCESS_MASK RemainingDesiredAccess
00825 )
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 {
00886 PRIVILEGE_SET RequiredPrivilege;
00887 BOOLEAN Result =
FALSE;
00888
NTSTATUS Status;
00889 ULONG PrivilegeCount = 0;
00890 HANDLE ThreadToken;
00891 BOOLEAN TokenPassed;
00892 TOKEN_STATISTICS ThreadTokenStatistics;
00893 ULONG ReturnLength;
00894 ULONG SizeRequired;
00895 ULONG PrivilegeNumber = 0;
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
if (!ARGUMENT_PRESENT(
Token )) {
00907
00908
Status =
NtOpenThreadToken(
00909 NtCurrentThread(),
00910 TOKEN_QUERY,
00911
TRUE,
00912 &ThreadToken
00913 );
00914
00915 TokenPassed =
FALSE;
00916
00917
if (!
NT_SUCCESS(
Status )) {
00918
return(
Status );
00919 }
00920
00921 }
else {
00922
00923 ThreadToken =
Token;
00924 TokenPassed =
TRUE;
00925 }
00926
00927
Status =
NtQueryInformationToken(
00928 ThreadToken,
00929 TokenStatistics,
00930 &ThreadTokenStatistics,
00931
sizeof(TOKEN_STATISTICS),
00932 &ReturnLength
00933 );
00934
00935
ASSERT(
NT_SUCCESS(
Status) );
00936
00937
RtlMapGenericMask(
00938 &DesiredAccess,
00939 GenericMapping
00940 );
00941
00942 *RemainingDesiredAccess = DesiredAccess;
00943
00944
if ( DesiredAccess & ACCESS_SYSTEM_SECURITY ) {
00945
00946 RequiredPrivilege.PrivilegeCount = 1;
00947 RequiredPrivilege.Control = PRIVILEGE_SET_ALL_NECESSARY;
00948 RequiredPrivilege.Privilege[0].Luid = RtlConvertLongToLuid(SE_SECURITY_PRIVILEGE);
00949 RequiredPrivilege.Privilege[0].Attributes = 0;
00950
00951
00952
00953
00954
00955
00956
Status =
NtPrivilegeCheck(
00957 ThreadToken,
00958 &RequiredPrivilege,
00959 &Result
00960 );
00961
00962
if ( (!
NT_SUCCESS (
Status )) || (!Result) ) {
00963
00964
if (!TokenPassed) {
00965
NtClose( ThreadToken );
00966 }
00967
00968
if ( !
NT_SUCCESS(
Status )) {
00969
return(
Status );
00970 }
00971
00972
if ( !Result ) {
00973
return( STATUS_PRIVILEGE_NOT_HELD );
00974 }
00975
00976 }
00977
00978
00979
00980
00981
00982
00983
00984 *RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
00985 }
00986
00987
if (!TokenPassed) {
00988
NtClose( ThreadToken );
00989 }
00990
00991 SizeRequired =
sizeof(PRIVILEGE_SET);
00992
00993
if ( SizeRequired > *Length ) {
00994 *Length = SizeRequired;
00995
return( STATUS_BUFFER_TOO_SMALL );
00996 }
00997
00998
if (Result) {
00999
01000 Privileges->PrivilegeCount = 1;
01001 Privileges->Control = 0;
01002 Privileges->Privilege[PrivilegeNumber].Luid = RtlConvertLongToLuid(SE_SECURITY_PRIVILEGE);
01003 Privileges->Privilege[PrivilegeNumber].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
01004
01005 }
else {
01006
01007 Privileges->PrivilegeCount = 0;
01008 Privileges->Control = 0;
01009 Privileges->Privilege[PrivilegeNumber].Luid = RtlConvertLongToLuid(0);
01010 Privileges->Privilege[PrivilegeNumber].Attributes = 0;
01011
01012 }
01013
01014
return( STATUS_SUCCESS );
01015
01016 }
01017
01018
01019
01020
NTSTATUS
01021 RtlCopySecurityDescriptor(
01022 IN PSECURITY_DESCRIPTOR InputSecurityDescriptor,
01023 OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor
01024 )
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 {
01059
01060 PACL
Dacl;
01061 PACL Sacl;
01062
01063 PSID
Owner;
01064 PSID PrimaryGroup;
01065
01066 ULONG DaclSize;
01067 ULONG OwnerSize;
01068 ULONG PrimaryGroupSize;
01069 ULONG SaclSize;
01070 ULONG TotalSize;
01071
01072 PISECURITY_DESCRIPTOR ISecurityDescriptor =
01073 (PISECURITY_DESCRIPTOR)InputSecurityDescriptor;
01074
01075
01076
RtlpQuerySecurityDescriptor(
01077 ISecurityDescriptor,
01078 &
Owner,
01079 &OwnerSize,
01080 &PrimaryGroup,
01081 &PrimaryGroupSize,
01082 &
Dacl,
01083 &DaclSize,
01084 &Sacl,
01085 &SaclSize
01086 );
01087
01088 TotalSize =
sizeof(SECURITY_DESCRIPTOR) +
01089 OwnerSize +
01090 PrimaryGroupSize +
01091 DaclSize +
01092 SaclSize;
01093
01094 *OutputSecurityDescriptor =
RtlAllocateHeap( RtlProcessHeap(),
MAKE_TAG(
SE_TAG ), TotalSize );
01095
01096
if ( *OutputSecurityDescriptor ==
NULL ) {
01097
return( STATUS_NO_MEMORY );
01098 }
01099
01100 RtlMoveMemory( *OutputSecurityDescriptor,
01101 ISecurityDescriptor,
01102 TotalSize
01103 );
01104
01105
return( STATUS_SUCCESS );
01106
01107 }
01108
01109
01110
NTSTATUS
01111 RtlpInitializeAllowedAce(
01112 IN PACCESS_ALLOWED_ACE AllowedAce,
01113 IN USHORT AceSize,
01114 IN UCHAR InheritFlags,
01115 IN UCHAR AceFlags,
01116 IN ACCESS_MASK Mask,
01117 IN PSID AllowedSid
01118 )
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 {
01146 AllowedAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
01147 AllowedAce->Header.AceSize = AceSize;
01148 AllowedAce->Header.AceFlags = AceFlags | InheritFlags;
01149
01150 AllowedAce->Mask = Mask;
01151
01152
return RtlCopySid(
01153
RtlLengthSid(AllowedSid),
01154 &(AllowedAce->SidStart),
01155 AllowedSid
01156 );
01157 }
01158
01159
01160
NTSTATUS
01161 RtlpInitializeDeniedAce(
01162 IN PACCESS_DENIED_ACE DeniedAce,
01163 IN USHORT AceSize,
01164 IN UCHAR InheritFlags,
01165 IN UCHAR AceFlags,
01166 IN ACCESS_MASK Mask,
01167 IN PSID DeniedSid
01168 )
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195 {
01196 DeniedAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
01197 DeniedAce->Header.AceSize = AceSize;
01198 DeniedAce->Header.AceFlags = AceFlags | InheritFlags;
01199
01200 DeniedAce->Mask = Mask;
01201
01202
return RtlCopySid(
01203
RtlLengthSid(DeniedSid),
01204 &(DeniedAce->SidStart),
01205 DeniedSid
01206 );
01207 }
01208
01209
01210
NTSTATUS
01211 RtlpInitializeAuditAce(
01212 IN PACCESS_ALLOWED_ACE AuditAce,
01213 IN USHORT AceSize,
01214 IN UCHAR InheritFlags,
01215 IN UCHAR AceFlags,
01216 IN ACCESS_MASK Mask,
01217 IN PSID AuditSid
01218 )
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 {
01246 AuditAce->Header.AceType = SYSTEM_AUDIT_ACE_TYPE;
01247 AuditAce->Header.AceSize = AceSize;
01248 AuditAce->Header.AceFlags = AceFlags | InheritFlags;
01249
01250 AuditAce->Mask = Mask;
01251
01252
return RtlCopySid(
01253
RtlLengthSid(AuditSid),
01254 &(AuditAce->SidStart),
01255 AuditSid
01256 );
01257 }
01258
01259
NTSTATUS
01260 RtlCreateAndSetSD(
01261 IN PRTL_ACE_DATA AceData,
01262 IN ULONG AceCount,
01263 IN PSID OwnerSid OPTIONAL,
01264 IN PSID GroupSid OPTIONAL,
01265 OUT PSECURITY_DESCRIPTOR *NewDescriptor
01266 )
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 {
01338
01339
NTSTATUS ntstatus = STATUS_SUCCESS;
01340 ULONG i;
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355 PSECURITY_DESCRIPTOR AbsoluteSd =
NULL;
01356 PACL
Dacl =
NULL;
01357 PACL Sacl =
NULL;
01358
01359 ULONG DaclSize =
sizeof(ACL);
01360 ULONG SaclSize =
sizeof(ACL);
01361 ULONG MaxAceSize = 0;
01362 PVOID MaxAce =
NULL;
01363
01364 PCHAR CurrentAvailable;
01365 ULONG
Size;
01366
01367 PVOID
HeapHandle = RtlProcessHeap();
01368
01369
01370
ASSERT( AceCount > 0 );
01371
01372
01373
01374
01375
01376
01377
for (i = 0; i < AceCount; i++) {
01378 ULONG AceSize;
01379
01380 AceSize =
RtlLengthSid(*(AceData[i].Sid));
01381
01382
switch (AceData[i].AceType) {
01383
case ACCESS_ALLOWED_ACE_TYPE:
01384 AceSize +=
sizeof(ACCESS_ALLOWED_ACE);
01385 DaclSize += AceSize;
01386
break;
01387
01388
case ACCESS_DENIED_ACE_TYPE:
01389 AceSize +=
sizeof(ACCESS_DENIED_ACE);
01390 DaclSize += AceSize;
01391
break;
01392
01393
case SYSTEM_AUDIT_ACE_TYPE:
01394 AceSize +=
sizeof(SYSTEM_AUDIT_ACE);
01395 SaclSize += AceSize;
01396
break;
01397
01398
default:
01399
return STATUS_INVALID_PARAMETER;
01400 }
01401
01402 MaxAceSize = MaxAceSize > AceSize ? MaxAceSize : AceSize;
01403 }
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
01414
if ( DaclSize !=
sizeof(ACL) ) {
01415
Size += DaclSize;
01416 }
01417
if ( SaclSize !=
sizeof(ACL) ) {
01418
Size += SaclSize;
01419 }
01420
01421
if ((AbsoluteSd =
RtlAllocateHeap(
01422
HeapHandle,
MAKE_TAG(
SE_TAG ),
01423
Size
01424 )) ==
NULL) {
01425 ntstatus = STATUS_NO_MEMORY;
01426
goto Cleanup;
01427 }
01428
01429
01430
01431
01432
01433 CurrentAvailable = (PCHAR)AbsoluteSd + SECURITY_DESCRIPTOR_MIN_LENGTH;
01434
01435
if ( DaclSize !=
sizeof(ACL) ) {
01436
Dacl = (PACL)CurrentAvailable;
01437 CurrentAvailable += DaclSize;
01438
01439 ntstatus =
RtlCreateAcl(
Dacl, DaclSize, ACL_REVISION );
01440
01441
if ( !
NT_SUCCESS(ntstatus) ) {
01442
goto Cleanup;
01443 }
01444 }
01445
01446
if ( SaclSize !=
sizeof(ACL) ) {
01447 Sacl = (PACL)CurrentAvailable;
01448 CurrentAvailable += SaclSize;
01449
01450 ntstatus =
RtlCreateAcl( Sacl, SaclSize, ACL_REVISION );
01451
01452
if ( !
NT_SUCCESS(ntstatus) ) {
01453
goto Cleanup;
01454 }
01455 }
01456
01457
01458
01459
01460
01461
if ((MaxAce =
RtlAllocateHeap(
01462
HeapHandle,
MAKE_TAG(
SE_TAG ),
01463 MaxAceSize
01464 )) ==
NULL ) {
01465 ntstatus = STATUS_NO_MEMORY;
01466
goto Cleanup;
01467 }
01468
01469
01470
01471
01472
01473
for (i = 0; i < AceCount; i++) {
01474 ULONG AceSize;
01475 PACL CurrentAcl;
01476
01477 AceSize =
RtlLengthSid(*(AceData[i].Sid));
01478
01479
switch (AceData[i].AceType) {
01480
case ACCESS_ALLOWED_ACE_TYPE:
01481
01482 AceSize +=
sizeof(ACCESS_ALLOWED_ACE);
01483 CurrentAcl =
Dacl;
01484 ntstatus =
RtlpInitializeAllowedAce(
01485 MaxAce,
01486 (
USHORT) AceSize,
01487 AceData[i].InheritFlags,
01488 AceData[i].AceFlags,
01489 AceData[i].Mask,
01490 *(AceData[i].Sid)
01491 );
01492
break;
01493
01494
case ACCESS_DENIED_ACE_TYPE:
01495 AceSize +=
sizeof(ACCESS_DENIED_ACE);
01496 CurrentAcl =
Dacl;
01497 ntstatus =
RtlpInitializeDeniedAce(
01498 MaxAce,
01499 (
USHORT) AceSize,
01500 AceData[i].InheritFlags,
01501 AceData[i].AceFlags,
01502 AceData[i].Mask,
01503 *(AceData[i].Sid)
01504 );
01505
break;
01506
01507
case SYSTEM_AUDIT_ACE_TYPE:
01508 AceSize +=
sizeof(SYSTEM_AUDIT_ACE);
01509 CurrentAcl = Sacl;
01510 ntstatus =
RtlpInitializeAuditAce(
01511 MaxAce,
01512 (
USHORT) AceSize,
01513 AceData[i].InheritFlags,
01514 AceData[i].AceFlags,
01515 AceData[i].Mask,
01516 *(AceData[i].Sid)
01517 );
01518
break;
01519 }
01520
01521
if ( !
NT_SUCCESS( ntstatus ) ) {
01522
goto Cleanup;
01523 }
01524
01525
01526
01527
01528
01529
if (!
NT_SUCCESS (ntstatus =
RtlAddAce(
01530 CurrentAcl,
01531 ACL_REVISION,
01532 MAXULONG,
01533 MaxAce,
01534 AceSize
01535 ))) {
01536
goto Cleanup;
01537 }
01538 }
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
if (!
NT_SUCCESS(ntstatus =
RtlCreateSecurityDescriptor(
01551 AbsoluteSd,
01552 SECURITY_DESCRIPTOR_REVISION
01553 ))) {
01554
goto Cleanup;
01555 }
01556
01557
if (!
NT_SUCCESS(ntstatus =
RtlSetOwnerSecurityDescriptor(
01558 AbsoluteSd,
01559 OwnerSid,
01560
FALSE
01561 ))) {
01562
goto Cleanup;
01563 }
01564
01565
if (!
NT_SUCCESS(ntstatus =
RtlSetGroupSecurityDescriptor(
01566 AbsoluteSd,
01567 GroupSid,
01568
FALSE
01569 ))) {
01570
goto Cleanup;
01571 }
01572
01573
if (!
NT_SUCCESS(ntstatus =
RtlSetDaclSecurityDescriptor(
01574 AbsoluteSd,
01575
TRUE,
01576
Dacl,
01577
FALSE
01578 ))) {
01579
goto Cleanup;
01580 }
01581
01582
if (!
NT_SUCCESS(ntstatus =
RtlSetSaclSecurityDescriptor(
01583 AbsoluteSd,
01584
FALSE,
01585 Sacl,
01586
FALSE
01587 ))) {
01588
goto Cleanup;
01589 }
01590
01591
01592
01593
01594
01595 ntstatus = STATUS_SUCCESS;
01596
01597
01598
01599
01600
01601 Cleanup:
01602
01603
01604
01605
01606
if (
NT_SUCCESS( ntstatus ) ) {
01607 *NewDescriptor = AbsoluteSd;
01608 }
else if ( AbsoluteSd !=
NULL ) {
01609 (
void)
RtlFreeHeap(
HeapHandle, 0, AbsoluteSd);
01610 }
01611
01612
01613
01614
01615
01616
if ( MaxAce !=
NULL ) {
01617 (
void)
RtlFreeHeap(
HeapHandle, 0, MaxAce);
01618 }
01619
return ntstatus;
01620 }
01621
01622
01623
NTSTATUS
01624 RtlCreateUserSecurityObject(
01625 IN PRTL_ACE_DATA AceData,
01626 IN ULONG AceCount,
01627 IN PSID OwnerSid,
01628 IN PSID GroupSid,
01629 IN BOOLEAN IsDirectoryObject,
01630 IN PGENERIC_MAPPING GenericMapping,
01631 OUT PSECURITY_DESCRIPTOR *NewDescriptor
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
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726 {
01727
01728
NTSTATUS ntstatus;
01729 PSECURITY_DESCRIPTOR AbsoluteSd;
01730 HANDLE TokenHandle;
01731 PVOID
HeapHandle = RtlProcessHeap();
01732
01733 ntstatus =
RtlCreateAndSetSD(
01734 AceData,
01735 AceCount,
01736 OwnerSid,
01737 GroupSid,
01738 &AbsoluteSd
01739 );
01740
01741
if (!
NT_SUCCESS(ntstatus)) {
01742
return ntstatus;
01743 }
01744
01745 ntstatus =
NtOpenProcessToken(
01746 NtCurrentProcess(),
01747 TOKEN_QUERY,
01748 &TokenHandle
01749 );
01750
01751
if (!
NT_SUCCESS(ntstatus)) {
01752 (
void)
RtlFreeHeap(
HeapHandle, 0, AbsoluteSd);
01753
return ntstatus;
01754 }
01755
01756
01757
01758
01759
01760
01761
01762
01763 ntstatus =
RtlNewSecurityObject(
01764
NULL,
01765 AbsoluteSd,
01766 NewDescriptor,
01767 IsDirectoryObject,
01768 TokenHandle,
01769 GenericMapping
01770 );
01771
01772 (
void)
NtClose(TokenHandle);
01773
01774
01775
01776
01777 (
void)
RtlFreeHeap(
HeapHandle, 0, AbsoluteSd);
01778
return ntstatus;
01779 }
01780
01781
01782
01783
01784
01785
NTSTATUS
01786 RtlConvertToAutoInheritSecurityObject(
01787 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
01788 IN PSECURITY_DESCRIPTOR CurrentSecurityDescriptor,
01789 OUT PSECURITY_DESCRIPTOR *NewSecurityDescriptor,
01790 IN GUID *ObjectType OPTIONAL,
01791 IN BOOLEAN IsDirectoryObject,
01792 IN PGENERIC_MAPPING GenericMapping
01793 )
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841 {
01842
01843
01844
01845
01846
01847
01848
return RtlpConvertToAutoInheritSecurityObject(
01849 ParentDescriptor,
01850 CurrentSecurityDescriptor,
01851 NewSecurityDescriptor,
01852 ObjectType,
01853 IsDirectoryObject,
01854 GenericMapping );
01855
01856 }
01857
01858
01859
NTSTATUS
01860 RtlDefaultNpAcl(
01861 OUT PACL * pAcl
01862 )
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896 {
01897 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
01898 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
01899 SID_IDENTIFIER_AUTHORITY WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
01900
01901 ULONG AclSize = 0;
01902
NTSTATUS Status = STATUS_SUCCESS;
01903 ULONG ReturnLength = 0;
01904 PTOKEN_OWNER OwnerSid =
NULL;
01905
01906 HANDLE hToken;
01907
01908
01909
01910
01911
01912 *pAcl =
NULL;
01913
01914
01915
01916
01917
01918
Status =
NtOpenThreadToken(
01919 NtCurrentThread(),
01920 TOKEN_QUERY,
01921
TRUE,
01922 &hToken
01923 );
01924
01925
if (STATUS_NO_TOKEN ==
Status) {
01926
01927
01928
01929
01930
01931
Status =
NtOpenProcessToken(
01932 NtCurrentProcess(),
01933 TOKEN_QUERY,
01934 &hToken
01935 );
01936 }
01937
01938
if (
NT_SUCCESS(
Status )) {
01939
01940
01941
01942
01943
01944
Status =
NtQueryInformationToken (
01945 hToken,
01946 TokenOwner,
01947
NULL,
01948 0,
01949 &ReturnLength
01950 );
01951
01952
if (STATUS_BUFFER_TOO_SMALL ==
Status) {
01953
01954 OwnerSid = (PTOKEN_OWNER)
RtlAllocateHeap( RtlProcessHeap(), 0, ReturnLength );
01955
01956
if (OwnerSid) {
01957
01958
Status =
NtQueryInformationToken (
01959 hToken,
01960 TokenOwner,
01961 OwnerSid,
01962 ReturnLength,
01963 &ReturnLength
01964 );
01965
01966
if (
NT_SUCCESS(
Status )) {
01967
01968
01969
01970
01971
01972 UCHAR SidBuffer[16];
01973
ASSERT( 16 ==
RtlLengthRequiredSid( 2 ));
01974
01975 AclSize +=
RtlLengthRequiredSid( 1 );
01976 AclSize +=
RtlLengthRequiredSid( 2 );
01977 AclSize +=
RtlLengthRequiredSid( 1 );
01978
01979 AclSize +=
RtlLengthSid( OwnerSid->Owner );
01980
01981 AclSize +=
sizeof( ACL );
01982 AclSize += 4 * (
sizeof( ACCESS_ALLOWED_ACE ) -
sizeof( ULONG ));
01983
01984
01985
01986
01987
01988 *pAcl = (PACL)
RtlAllocateHeap( RtlProcessHeap(), 0, AclSize );
01989
01990
if (*pAcl !=
NULL) {
01991
01992
RtlCreateAcl( *pAcl, AclSize, ACL_REVISION );
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
RtlInitializeSid( SidBuffer, &NtAuthority, 1);
02004 *(
RtlSubAuthoritySid( SidBuffer, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
02005
RtlAddAccessAllowedAce( *pAcl, ACL_REVISION, GENERIC_ALL, (PSID)SidBuffer );
02006
02007
02008
02009
02010
02011
RtlInitializeSid( SidBuffer, &NtAuthority, 2);
02012 *(
RtlSubAuthoritySid( SidBuffer, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
02013 *(
RtlSubAuthoritySid( SidBuffer, 1 )) = DOMAIN_ALIAS_RID_ADMINS;
02014
RtlAddAccessAllowedAce( *pAcl, ACL_REVISION, GENERIC_ALL, (PSID)SidBuffer );
02015
02016
02017
02018
02019
02020
RtlAddAccessAllowedAce( *pAcl, ACL_REVISION, GENERIC_ALL, OwnerSid->Owner );
02021
02022
02023
02024
02025
02026
RtlInitializeSid( SidBuffer, &WorldSidAuthority, 1 );
02027 *(
RtlSubAuthoritySid( SidBuffer, 0 )) = SECURITY_WORLD_RID;
02028
RtlAddAccessAllowedAce( *pAcl, ACL_REVISION, GENERIC_READ, (PSID)SidBuffer );
02029
02030 }
else {
02031
02032
Status = STATUS_NO_MEMORY;
02033 }
02034 }
02035
02036
RtlFreeHeap( RtlProcessHeap(), 0, OwnerSid );
02037
02038 }
else {
02039
02040
Status = STATUS_NO_MEMORY;
02041 }
02042 }
02043
02044
NtClose( hToken );
02045 }
02046
02047
if (!
NT_SUCCESS(
Status )) {
02048
02049
02050
02051
02052
02053
02054
if (*pAcl !=
NULL) {
02055
RtlFreeHeap( RtlProcessHeap(), 0, *pAcl );
02056 *pAcl =
NULL;
02057 }
02058 }
02059
02060
return(
Status );
02061 }
02062