00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "cmp.h"
00023
00024
00025
00026
00027
00028
00029
NTSTATUS
00030
CmpSetSecurityDescriptorInfo(
00031 IN
PCM_KEY_CONTROL_BLOCK kcb,
00032 IN PSECURITY_INFORMATION SecurityInformation,
00033 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
00034 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
00035 IN POOL_TYPE PoolType,
00036 IN PGENERIC_MAPPING GenericMapping
00037 );
00038
00039
NTSTATUS
00040
CmpQuerySecurityDescriptorInfo(
00041 IN
PCM_KEY_CONTROL_BLOCK kcb,
00042 IN PSECURITY_INFORMATION SecurityInformation,
00043 OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00044 IN OUT PULONG Length,
00045 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor
00046 );
00047
00048
PCM_KEY_SECURITY
00049
CmpGetKeySecurity(
00050 IN
PHHIVE Hive,
00051 IN
PCM_KEY_NODE Key,
00052 OUT PHCELL_INDEX SecurityCell OPTIONAL
00053 );
00054
00055
VOID
00056
CmpGetObjectSecurity(
00057 IN HCELL_INDEX Cell,
00058 IN
PHHIVE Hive,
00059 OUT
PCM_KEY_SECURITY *Security,
00060 OUT PHCELL_INDEX SecurityCell OPTIONAL
00061 );
00062
00063 BOOLEAN
00064
CmpFindMatchingDescriptorCell(
00065 IN
PHHIVE Hive,
00066 IN
PCM_KEY_NODE Node,
00067 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00068 IN ULONG Type,
00069 OUT PHCELL_INDEX MatchingCell
00070 );
00071
00072 BOOLEAN
00073
CmpInsertSecurityCellList(
00074 IN
PHHIVE Hive,
00075 IN HCELL_INDEX NodeCell,
00076 IN HCELL_INDEX SecurityCell
00077 );
00078
00079
VOID
00080
CmpRemoveSecurityCellList(
00081 IN
PHHIVE Hive,
00082 IN HCELL_INDEX SecurityCell
00083 );
00084
00085 ULONG
00086
CmpSecurityExceptionFilter(
00087 IN PEXCEPTION_POINTERS ExceptionPointers
00088 );
00089
00090
00091
00092
00093
00094
00095 #define SECURITY_CELL_LENGTH(pDescriptor) \
00096
FIELD_OFFSET(CM_KEY_SECURITY,Descriptor) + \
00097
RtlLengthSecurityDescriptor(pDescriptor)
00098
00099
#ifdef ALLOC_PRAGMA
00100
#pragma alloc_text(PAGE,CmpSecurityMethod )
00101
#pragma alloc_text(PAGE,CmpSetSecurityDescriptorInfo)
00102
#pragma alloc_text(PAGE,CmpAssignSecurityDescriptor)
00103
#pragma alloc_text(PAGE,CmpQuerySecurityDescriptorInfo)
00104
#pragma alloc_text(PAGE,CmpCheckCreateAccess)
00105
#pragma alloc_text(PAGE,CmpCheckNotifyAccess)
00106
#pragma alloc_text(PAGE,CmpGetObjectSecurity)
00107
#pragma alloc_text(PAGE,CmpGetKeySecurity)
00108
#pragma alloc_text(PAGE,CmpHiveRootSecurityDescriptor)
00109
#pragma alloc_text(PAGE,CmpFreeSecurityDescriptor)
00110
#pragma alloc_text(PAGE,CmpFindMatchingDescriptorCell)
00111
#pragma alloc_text(PAGE,CmpInsertSecurityCellList)
00112
#pragma alloc_text(PAGE,CmpRemoveSecurityCellList)
00113
#pragma alloc_text(PAGE,CmpSecurityExceptionFilter)
00114
#endif
00115
00116 ULONG
00117 CmpSecurityExceptionFilter(
00118 IN PEXCEPTION_POINTERS ExceptionPointers
00119 )
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 {
00134
DbgPrint(
"CM: Registry security exception %lx, ExceptionPointers = %p\n",
00135 ExceptionPointers->ExceptionRecord->ExceptionCode,
00136 ExceptionPointers);
00137
00138
00139
00140
00141
00142
#if DBG
00143
try {
00144 DbgBreakPoint();
00145 } except (
EXCEPTION_EXECUTE_HANDLER) {
00146
00147
00148
00149
00150
00151 }
00152
#endif
00153
00154
return(
EXCEPTION_EXECUTE_HANDLER);
00155 }
00156
00157
NTSTATUS
00158 CmpSecurityMethod (
00159 IN PVOID Object,
00160 IN SECURITY_OPERATION_CODE OperationCode,
00161 IN PSECURITY_INFORMATION SecurityInformation,
00162 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00163 IN OUT PULONG CapturedLength,
00164 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
00165 IN POOL_TYPE PoolType,
00166 IN PGENERIC_MAPPING GenericMapping
00167 )
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 {
00245
PCM_KEY_CONTROL_BLOCK kcb;
00246
NTSTATUS Status;
00247
CM_KEY_REFERENCE Key;
00248
00249
00250
00251
00252
00253
PAGED_CODE();
00254
ASSERT_KEY_OBJECT(Object);
00255
00256
ASSERT( (OperationCode ==
SetSecurityDescriptor) ||
00257 (OperationCode ==
QuerySecurityDescriptor) ||
00258 (OperationCode ==
AssignSecurityDescriptor) ||
00259 (OperationCode ==
DeleteSecurityDescriptor) );
00260
00261
00262
00263
00264
00265
if (OperationCode ==
QuerySecurityDescriptor) {
00266
CmpLockRegistry();
00267 }
else {
00268
CmpLockRegistryExclusive();
00269 }
00270
00271
if (((
PCM_KEY_BODY)Object)->KeyControlBlock->Delete) {
00272
00273
00274
00275
00276
CmpUnlockRegistry();
00277
return(STATUS_KEY_DELETED);
00278 }
00279
00280
kcb = ((
PCM_KEY_BODY)Object)->KeyControlBlock;
00281
00282
try {
00283
00284
00285
00286
00287
00288
switch (OperationCode) {
00289
00290
case SetSecurityDescriptor:
00291
00292
00293
00294
00295
00296
ASSERT( (PoolType ==
PagedPool) || (PoolType ==
NonPagedPool) );
00297
00298
Status =
CmpSetSecurityDescriptorInfo(
kcb,
00299 SecurityInformation,
00300 SecurityDescriptor,
00301 ObjectsSecurityDescriptor,
00302 PoolType,
00303 GenericMapping );
00304
00305
00306
00307
00308
00309
00310
if (
NT_SUCCESS(
Status)) {
00311
CmpReportNotify(
kcb,
00312
kcb->KeyHive,
00313
kcb->KeyCell,
00314 REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_SECURITY);
00315
00316 }
00317
00318
break;
00319
00320
case QuerySecurityDescriptor:
00321
00322
00323
00324
00325
00326
ASSERT( CapturedLength !=
NULL );
00327
Status =
CmpQuerySecurityDescriptorInfo(
kcb,
00328 SecurityInformation,
00329 SecurityDescriptor,
00330 CapturedLength,
00331 ObjectsSecurityDescriptor );
00332
break;
00333
00334
case DeleteSecurityDescriptor:
00335
00336
00337
00338
00339
00340
00341
ASSERT(
FALSE);
00342
00343
break;
00344
00345
case AssignSecurityDescriptor:
00346
00347
00348
00349
00350
00351
00352
00353
Status =
ObAssignObjectSecurityDescriptor(Object,
NULL,
PagedPool);
00354
00355
ASSERT(
NT_SUCCESS(
Status ));
00356
00357
00358
00359
00360
Status =
CmpAssignSecurityDescriptor(
kcb->KeyHive,
00361
kcb->KeyCell,
00362
kcb->KeyNode,
00363 SecurityDescriptor );
00364
00365
00366
00367
ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
00368
kcb->Security =
kcb->KeyNode->Security;
00369
00370
break;
00371
00372
default:
00373
00374
00375
00376
00377
00378
KeBugCheckEx( REGISTRY_ERROR,3,1,(ULONG_PTR)
kcb,0);
00379
00380 }
00381
00382 } except (
CmpSecurityExceptionFilter(GetExceptionInformation())) {
00383
CMLOG(
CML_FLOW,
CMS_SEC) {
00384 KdPrint((
"!!CmpSecurityMethod: code:%08lx\n", GetExceptionCode()));
00385 }
00386
Status = GetExceptionCode();
00387 }
00388
00389
00390
CmpUnlockRegistry();
00391
return(
Status);
00392
00393 }
00394
00395
00396
NTSTATUS
00397 CmpSetSecurityDescriptorInfo(
00398 IN
PCM_KEY_CONTROL_BLOCK Key,
00399 IN PSECURITY_INFORMATION SecurityInformation,
00400 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
00401 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
00402 IN POOL_TYPE PoolType,
00403 IN PGENERIC_MAPPING GenericMapping
00404 )
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 {
00446
NTSTATUS Status;
00447
HCELL_INDEX SecurityCell;
00448
HCELL_INDEX MatchSecurityCell;
00449
HCELL_INDEX NewCell;
00450
HCELL_INDEX OldCell;
00451
PCM_KEY_SECURITY Security;
00452
PCM_KEY_SECURITY NewSecurity;
00453
PCM_KEY_SECURITY FlinkSecurity;
00454
PCM_KEY_SECURITY BlinkSecurity;
00455
PCM_KEY_NODE Node;
00456 ULONG DescriptorLength;
00457 PSECURITY_DESCRIPTOR DescriptorCopy;
00458 PSECURITY_DESCRIPTOR OldDescriptorCopy;
00459 ULONG Type;
00460 LARGE_INTEGER SystemTime;
00461
PHHIVE Hive;
00462
00463
PAGED_CODE();
00464
CMLOG(
CML_FLOW,
CMS_SEC) {
00465 KdPrint((
"CmpSetSecurityDescriptorInfo:\n"));
00466 }
00467
00468
00469
00470
00471
00472
00473
00474 Security =
CmpGetKeySecurity(
Key->KeyHive,
00475
Key->KeyNode,
00476 &SecurityCell);
00477
00478
00479
00480
00481
00482
00483 DescriptorCopy = &Security->
Descriptor;
00484
Status =
SeSetSecurityDescriptorInfo(
NULL,
00485 SecurityInformation,
00486 ModificationDescriptor,
00487 &DescriptorCopy,
00488 PoolType,
00489 GenericMapping );
00490
00491
if (!
NT_SUCCESS(
Status)) {
00492
return(
Status);
00493 }
00494
00495
00496
00497
00498
00499 DescriptorLength =
RtlLengthSecurityDescriptor(DescriptorCopy);
00500 Type =
HvGetCellType(
Key->KeyCell);
00501
Hive =
Key->KeyHive;
00502 Node =
Key->KeyNode;
00503
00504
if (! (
HvMarkCellDirty(
Hive,
Key->KeyCell) &&
00505
HvMarkCellDirty(
Hive, SecurityCell)))
00506 {
00507
ExFreePool(DescriptorCopy);
00508
return STATUS_NO_LOG_SPACE;
00509 }
00510
00511
00512
00513
00514
if (
CmpFindMatchingDescriptorCell(
Hive, Node, DescriptorCopy, Type, &MatchSecurityCell)) {
00515
00516
00517
00518
if (!
HvMarkCellDirty(
Hive, MatchSecurityCell)) {
00519
ExFreePool(DescriptorCopy);
00520
return(STATUS_NO_LOG_SPACE);
00521 }
00522
if (Security->
ReferenceCount == 1) {
00523
00524
00525
00526
if (! (
HvMarkCellDirty(
Hive, Security->
Flink) &&
00527
HvMarkCellDirty(
Hive, Security->
Blink))) {
00528
ExFreePool(DescriptorCopy);
00529
return(STATUS_NO_LOG_SPACE);
00530 }
00531
CmpRemoveSecurityCellList(
Hive, SecurityCell);
00532
HvFreeCell(
Hive, SecurityCell);
00533 }
else {
00534
00535
00536
00537
00538 Security->
ReferenceCount -= 1;
00539 }
00540
00541
00542
00543
00544 Security = (
PCM_KEY_SECURITY)
HvGetCell(
Hive, MatchSecurityCell);
00545 Security->
ReferenceCount += 1;
00546 Node->
Security = MatchSecurityCell;
00547 }
else {
00548
00549
00550
00551
00552
if (Security->
ReferenceCount > 1) {
00553
00554
00555
00556
00557
00558
00559 NewCell =
HvAllocateCell(
Key->KeyHive,
00560
SECURITY_CELL_LENGTH(DescriptorCopy),
00561 Type);
00562
if (NewCell ==
HCELL_NIL) {
00563
ExFreePool(DescriptorCopy);
00564
return(STATUS_INSUFFICIENT_RESOURCES);
00565 }
00566
00567
if (!
HvMarkCellDirty(
Key->KeyHive, Security->
Flink)) {
00568
ExFreePool(DescriptorCopy);
00569
return STATUS_NO_LOG_SPACE;
00570 }
00571
00572 Security->
ReferenceCount -= 1;
00573
00574
00575
00576
00577 NewSecurity = (
PCM_KEY_SECURITY)
HvGetCell(
Key->KeyHive, NewCell);
00578 NewSecurity->
Blink = SecurityCell;
00579 NewSecurity->
Flink = Security->
Flink;
00580 FlinkSecurity = (
PCM_KEY_SECURITY)
HvGetCell(
Key->KeyHive, Security->
Flink);
00581 Security->
Flink = FlinkSecurity->
Blink = NewCell;
00582
00583
00584
00585
00586 NewSecurity->
Signature =
CM_KEY_SECURITY_SIGNATURE;
00587 NewSecurity->
ReferenceCount = 1;
00588 NewSecurity->
DescriptorLength = DescriptorLength;
00589 Security=NewSecurity;
00590
00591
00592
00593
00594 Node->
Security = NewCell;
00595
00596 }
else if (DescriptorLength != Security->
DescriptorLength) {
00597
00598
00599
00600
00601
00602
if (! (
HvMarkCellDirty(
Key->KeyHive, Security->
Flink) &&
00603
HvMarkCellDirty(
Key->KeyHive, Security->
Blink))) {
00604
ExFreePool(DescriptorCopy);
00605
return(STATUS_INSUFFICIENT_RESOURCES);
00606 }
00607
00608
DCmCheckRegistry((
PCMHIVE)(
Key->KeyHive));
00609 OldCell = SecurityCell;
00610 SecurityCell =
HvReallocateCell(
Key->KeyHive,
00611 SecurityCell,
00612
SECURITY_CELL_LENGTH(DescriptorCopy) );
00613
if (SecurityCell ==
HCELL_NIL) {
00614
ExFreePool(DescriptorCopy);
00615
return(STATUS_INSUFFICIENT_RESOURCES);
00616 }
00617
00618
00619
00620
00621 Node->
Security = SecurityCell;
00622
00623
00624
00625
00626 Security = (
PCM_KEY_SECURITY)
HvGetCell(
Key->KeyHive, SecurityCell);
00627
ASSERT_SECURITY(Security);
00628
00629
00630
00631
00632
if (Security->
Flink == OldCell) {
00633 Security->
Flink = SecurityCell;
00634 }
else {
00635 FlinkSecurity = (
PCM_KEY_SECURITY)
HvGetCell(
00636
Key->KeyHive,
00637 Security->
Flink
00638 );
00639 FlinkSecurity->
Blink = SecurityCell;
00640 }
00641
00642
if (Security->
Blink == OldCell) {
00643 Security->
Blink = SecurityCell;
00644 }
else {
00645 BlinkSecurity = (
PCM_KEY_SECURITY)
HvGetCell(
00646
Key->KeyHive,
00647 Security->
Blink
00648 );
00649 BlinkSecurity->
Flink = SecurityCell;
00650 }
00651
00652
00653
00654
00655 Security->
DescriptorLength = DescriptorLength;
00656
DCmCheckRegistry((
PCMHIVE)(
Key->KeyHive));
00657
00658 }
else {
00659
00660
00661
00662
00663
00664 NOTHING;
00665 }
00666
00667 RtlMoveMemory( &(Security->
Descriptor),
00668 DescriptorCopy,
00669 DescriptorLength );
00670 }
00671
00672
00673
CMLOG(
CML_FLOW,
CMS_SEC) {
00674 KdPrint((
"\tObject's SD has been changed\n"));
00675
CmpDumpSecurityDescriptor(DescriptorCopy,
"NEW DESCRIPTOR\n");
00676 }
00677
00678
ExFreePool(DescriptorCopy);
00679
00680
00681
00682
00683
KeQuerySystemTime(&SystemTime);
00684 Node->
LastWriteTime = SystemTime;
00685
00686
00687
00688
00689
ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
00690
Key->Security = Node->
Security;
00691
00692
return(STATUS_SUCCESS);
00693 }
00694
00695
00696
NTSTATUS
00697 CmpAssignSecurityDescriptor(
00698 IN
PHHIVE Hive,
00699 IN HCELL_INDEX Cell,
00700 IN
PCM_KEY_NODE Node,
00701 IN PSECURITY_DESCRIPTOR SecurityDescriptor
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
HCELL_INDEX SecurityCell;
00737
PCM_KEY_SECURITY Security;
00738 ULONG DescriptorLength;
00739 ULONG Type;
00740
00741
PAGED_CODE();
00742
00743
00744
00745
if (!
HvMarkCellDirty(
Hive,
Cell)) {
00746
return STATUS_NO_LOG_SPACE;
00747 }
00748
ASSERT_NODE(Node);
00749
00750
CMLOG(
CML_FLOW,
CMS_SEC) {
00751
#if DBG
00752
UNICODE_STRING
Name;
00753
00754
Name.MaximumLength =
Name.Length = Node->NameLength;
00755
Name.Buffer = Node->Name;
00756 KdPrint((
"CmpAssignSecurityDescriptor: '%wZ' (H %lx C %lx)\n",&
Name,
Hive,
Cell ));
00757 KdPrint((
"\tSecurityCell = %lx\n",Node->Security));
00758
#endif
00759
}
00760
00761
ASSERT(Node->Security==
HCELL_NIL);
00762
00763
00764
00765
00766
00767
00768
CMLOG(
CML_FLOW,
CMS_SEC) {
00769
CmpDumpSecurityDescriptor(SecurityDescriptor,
"ASSIGN DESCRIPTOR\n");
00770 }
00771
00772
00773
00774
00775
00776
00777 Type =
HvGetCellType(
Cell);
00778
if (!
CmpFindMatchingDescriptorCell(
Hive,
00779 Node,
00780 SecurityDescriptor,
00781 Type,
00782 &SecurityCell )) {
00783
00784
00785
00786 SecurityCell =
HvAllocateCell(
Hive,
00787
SECURITY_CELL_LENGTH(SecurityDescriptor),
00788 Type);
00789
if (SecurityCell ==
HCELL_NIL) {
00790
return STATUS_INSUFFICIENT_RESOURCES;
00791 }
00792
00793
00794
00795
00796 Security = (
PCM_KEY_SECURITY)
HvGetCell(
Hive, SecurityCell);
00797
00798
00799
00800
00801 DescriptorLength =
RtlLengthSecurityDescriptor(SecurityDescriptor);
00802
00803 Security->
Signature =
CM_KEY_SECURITY_SIGNATURE;
00804 Security->
ReferenceCount = 1;
00805 Security->
DescriptorLength = DescriptorLength;
00806 RtlMoveMemory( &(Security->
Descriptor),
00807 SecurityDescriptor,
00808 DescriptorLength );
00809
00810
00811
00812
00813
00814
if (!
CmpInsertSecurityCellList(
Hive,
Cell,SecurityCell))
00815 {
00816
HvFreeCell(
Hive, SecurityCell);
00817
return STATUS_NO_LOG_SPACE;
00818 }
00819
00820 }
else {
00821
00822
00823
00824
00825
00826
if (!
HvMarkCellDirty(
Hive, SecurityCell)) {
00827
return STATUS_NO_LOG_SPACE;
00828 }
00829 Security = (
PCM_KEY_SECURITY)
HvGetCell(
Hive, SecurityCell);
00830 Security->
ReferenceCount += 1;
00831 }
00832
00833
00834
00835
00836 Node->Security = SecurityCell;
00837
00838
CMLOG(
CML_FLOW,
CMS_SEC) {
00839 KdPrint((
"\tSecurityCell = %lx\n",Node->Security));
00840 }
00841
00842
return(STATUS_SUCCESS);
00843 }
00844
00845
00846
NTSTATUS
00847 CmpQuerySecurityDescriptorInfo(
00848 IN
PCM_KEY_CONTROL_BLOCK kcb,
00849 IN PSECURITY_INFORMATION SecurityInformation,
00850 OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00851 IN OUT PULONG Length,
00852 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor
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
00887
00888
00889
00890
00891
00892
00893 {
00894
NTSTATUS Status;
00895
PCM_KEY_SECURITY Security;
00896 PSECURITY_DESCRIPTOR CellSecurityDescriptor;
00897
00898
PAGED_CODE();
00899
CMLOG(
CML_FLOW,
CMS_SEC) {
00900 KdPrint((
"CmpQuerySecurityDescriptorInfo:\n"));
00901 }
00902
00903 Security = (
PCM_KEY_SECURITY)
HvGetCell(
kcb->KeyHive,
kcb->Security);
00904
00905 CellSecurityDescriptor = &Security->
Descriptor;
00906
00907
Status =
SeQuerySecurityDescriptorInfo( SecurityInformation,
00908 SecurityDescriptor,
00909 Length,
00910 &CellSecurityDescriptor );
00911
00912
return(
Status);
00913 }
00914
00915
00916 BOOLEAN
00917 CmpCheckCreateAccess(
00918 IN PUNICODE_STRING RelativeName,
00919 IN PSECURITY_DESCRIPTOR Descriptor,
00920 IN
PACCESS_STATE AccessState,
00921 IN KPROCESSOR_MODE PreviousMode,
00922 IN ACCESS_MASK AdditionalAccess,
00923 OUT PNTSTATUS AccessStatus
00924 )
00925
00926
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
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 {
00967 BOOLEAN AccessAllowed;
00968 ACCESS_MASK GrantedAccess = 0;
00969 BOOLEAN AuditPerformed =
FALSE;
00970
00971
PAGED_CODE();
00972
CMLOG(
CML_FLOW,
CMS_SEC) {
00973 KdPrint((
"CmpCheckCreateAccess:\n"));
00974 }
00975
00976
SeLockSubjectContext( &AccessState->SubjectSecurityContext );
00977
00978 AccessAllowed =
SeAccessCheck(
00979 Descriptor,
00980 &AccessState->SubjectSecurityContext,
00981
TRUE,
00982 (KEY_CREATE_SUB_KEY | AdditionalAccess),
00983 0,
00984
NULL,
00985 &
CmpKeyObjectType->
TypeInfo.
GenericMapping,
00986 PreviousMode,
00987 &GrantedAccess,
00988 AccessStatus
00989 );
00990
00991
00992
00993
00994
00995
#if 0
00996
00997
00998
00999
01000
01001
01002
SeCreateObjectAuditAlarm(
01003 &AccessState->OperationID,
01004
NULL,
01005
NULL,
01006 Descriptor,
01007 &AccessState->SubjectSecurityContext,
01008 KEY_CREATE_SUB_KEY,
01009 AccessState->PrivilegesUsed,
01010 AccessAllowed,
01011 &AuditPerformed,
01012 PreviousMode
01013 );
01014
#endif
01015
01016
SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
01017
01018
CMLOG(
CML_FLOW,
CMS_SEC) {
01019 KdPrint((
"Create access %s\n",AccessAllowed ?
"granted" :
"denied"));
01020
#if DBG
01021
if (!AccessAllowed) {
01022
CmpDumpSecurityDescriptor(Descriptor,
"DENYING DESCRIPTOR");
01023 }
01024
#endif
01025
}
01026
01027
return(AccessAllowed);
01028 }
01029
01030
01031 BOOLEAN
01032 CmpCheckNotifyAccess(
01033 IN
PCM_NOTIFY_BLOCK NotifyBlock,
01034 IN
PHHIVE Hive,
01035 IN
PCM_KEY_NODE Node
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
01061 {
01062
PCM_KEY_SECURITY Security;
01063 PSECURITY_DESCRIPTOR SecurityDescriptor;
01064
NTSTATUS Status;
01065 BOOLEAN AccessAllowed;
01066 ACCESS_MASK GrantedAccess = 0;
01067
01068
ASSERT_CM_LOCK_OWNED();
01069
PAGED_CODE();
01070
01071
01072
CMLOG(
CML_FLOW,
CMS_SEC) {
01073 KdPrint((
"CmpCheckAccessForNotify:\n"));
01074 }
01075 Security =
CmpGetKeySecurity(
Hive,
01076 Node,
01077
NULL);
01078
01079
SeLockSubjectContext( &NotifyBlock->SubjectContext );
01080
01081 SecurityDescriptor = &Security->
Descriptor;
01082 AccessAllowed =
SeAccessCheck( SecurityDescriptor,
01083 &NotifyBlock->SubjectContext,
01084
TRUE,
01085 KEY_NOTIFY,
01086 0,
01087
NULL,
01088 &
CmpKeyObjectType->
TypeInfo.
GenericMapping,
01089
UserMode,
01090 &GrantedAccess,
01091 &
Status );
01092
01093
SeUnlockSubjectContext( &NotifyBlock->SubjectContext );
01094
01095
CMLOG(
CML_FLOW,
CMS_SEC) {
01096 KdPrint((
"Notify access %s\n",AccessAllowed ?
"granted" :
"denied"));
01097
#if DBG
01098
if (!AccessAllowed) {
01099
CmpDumpSecurityDescriptor(SecurityDescriptor,
"DENYING DESCRIPTOR");
01100 }
01101
#endif
01102
}
01103
01104
return AccessAllowed;
01105 }
01106
01107
01108
VOID
01109 CmpGetObjectSecurity(
01110 IN HCELL_INDEX Cell,
01111 IN
PHHIVE Hive,
01112 OUT
PCM_KEY_SECURITY *Security,
01113 OUT PHCELL_INDEX SecurityCell OPTIONAL
01114 )
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138 {
01139
HCELL_INDEX CellIndex;
01140
PCM_KEY_NODE Node;
01141
01142
PAGED_CODE();
01143
01144
01145
01146 Node = (
PCM_KEY_NODE)
HvGetCell(
Hive,
Cell);
01147
01148
CMLOG(
CML_FLOW,
CMS_SEC) {
01149
#if DBG
01150
UNICODE_STRING
Name;
01151
01152
Name.MaximumLength =
Name.Length = Node->
NameLength;
01153
Name.Buffer = Node->
Name;
01154 KdPrint((
"CmpGetObjectSecurity for: "));
01155 KdPrint((
"%wZ\n", &
Name));
01156
#endif
01157
}
01158
01159 *Security =
CmpGetKeySecurity(
Hive,Node,SecurityCell);
01160
01161
return;
01162 }
01163
01164
PCM_KEY_SECURITY
01165 CmpGetKeySecurity(
01166 IN
PHHIVE Hive,
01167 IN
PCM_KEY_NODE Key,
01168 OUT PHCELL_INDEX SecurityCell OPTIONAL
01169 )
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191 {
01192
HCELL_INDEX CellIndex;
01193
PCM_KEY_SECURITY Security;
01194
01195
PAGED_CODE();
01196
01197
ASSERT(
Key->Signature ==
CM_KEY_NODE_SIGNATURE);
01198
ASSERT_NODE(
Key);
01199
01200
CMLOG(
CML_FLOW,
CMS_SEC) {
01201
#if DBG
01202
UNICODE_STRING
Name;
01203
01204
Name.MaximumLength =
Name.Length =
Key->NameLength;
01205
Name.Buffer =
Key->Name;
01206 KdPrint((
"CmpGetObjectSecurity for: "));
01207 KdPrint((
"%wZ\n", &
Name));
01208
#endif
01209
}
01210
01211 CellIndex =
Key->Security;
01212
01213
01214
01215
01216 Security = (
PCM_KEY_SECURITY)
HvGetCell(
Hive, CellIndex);
01217
ASSERT_SECURITY(Security);
01218
01219
if (ARGUMENT_PRESENT(SecurityCell)) {
01220 *SecurityCell = CellIndex;
01221 }
01222
01223
return(Security);
01224 }
01225
01226 PSECURITY_DESCRIPTOR
01227 CmpHiveRootSecurityDescriptor(
01228 VOID
01229 )
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 {
01253
NTSTATUS Status;
01254 PSECURITY_DESCRIPTOR SecurityDescriptor=
NULL;
01255 PACL Acl=
NULL;
01256 PACL AclCopy;
01257 PSID
WorldSid=
NULL;
01258 PSID RestrictedSid=
NULL;
01259 PSID SystemSid=
NULL;
01260 PSID AdminSid=
NULL;
01261 SID_IDENTIFIER_AUTHORITY WorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
01262 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
01263 ULONG AceLength;
01264 ULONG AclLength;
01265 PACE_HEADER AceHeader;
01266
01267
PAGED_CODE();
01268
01269
01270
01271
01272
WorldSid =
ExAllocatePool(
PagedPool,
RtlLengthRequiredSid(1));
01273 RestrictedSid =
ExAllocatePool(
PagedPool,
RtlLengthRequiredSid(1));
01274 SystemSid =
ExAllocatePool(
PagedPool,
RtlLengthRequiredSid(1));
01275 AdminSid =
ExAllocatePool(
PagedPool,
RtlLengthRequiredSid(2));
01276
if ((
WorldSid ==
NULL) ||
01277 (RestrictedSid ==
NULL) ||
01278 (SystemSid ==
NULL) ||
01279 (AdminSid ==
NULL)) {
01280
01281
KeBugCheckEx(REGISTRY_ERROR, 10, 0, 0, 0);
01282 }
01283
01284
if ((!
NT_SUCCESS(
RtlInitializeSid(
WorldSid, &WorldAuthority, 1))) ||
01285 (!
NT_SUCCESS(
RtlInitializeSid(RestrictedSid, &NtAuthority, 1))) ||
01286 (!
NT_SUCCESS(
RtlInitializeSid(SystemSid, &NtAuthority, 1))) ||
01287 (!
NT_SUCCESS(
RtlInitializeSid(AdminSid, &NtAuthority, 2)))) {
01288
KeBugCheckEx(REGISTRY_ERROR, 10, 1, 0, 0);
01289 }
01290
01291 *(
RtlSubAuthoritySid(
WorldSid, 0)) = SECURITY_WORLD_RID;
01292
01293 *(
RtlSubAuthoritySid(RestrictedSid, 0)) = SECURITY_RESTRICTED_CODE_RID;
01294
01295 *(
RtlSubAuthoritySid(SystemSid, 0)) = SECURITY_LOCAL_SYSTEM_RID;
01296
01297 *(
RtlSubAuthoritySid(AdminSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
01298 *(
RtlSubAuthoritySid(AdminSid, 1)) = DOMAIN_ALIAS_RID_ADMINS;
01299
01300
ASSERT(
RtlValidSid(
WorldSid));
01301
ASSERT(
RtlValidSid(RestrictedSid));
01302
ASSERT(
RtlValidSid(SystemSid));
01303
ASSERT(
RtlValidSid(AdminSid));
01304
01305
01306
01307
01308
01309 AceLength = (
SeLengthSid(
WorldSid) -
01310
sizeof(ULONG) +
01311
sizeof(ACCESS_ALLOWED_ACE))
01312 + (
SeLengthSid(RestrictedSid) -
01313
sizeof(ULONG) +
01314
sizeof(ACCESS_ALLOWED_ACE))
01315 + (
SeLengthSid(SystemSid) -
01316
sizeof(ULONG) +
01317
sizeof(ACCESS_ALLOWED_ACE))
01318 + (
SeLengthSid(AdminSid) -
01319
sizeof(ULONG) +
01320
sizeof(ACCESS_ALLOWED_ACE));
01321
01322
01323
01324
01325
01326 AclLength = AceLength +
sizeof(ACL);
01327 Acl =
ExAllocatePool(
PagedPool, AclLength);
01328
if (Acl ==
NULL) {
01329
CMLOG(
CML_MAJOR,
CMS_SEC) {
01330 KdPrint((
"CmpHiveRootSecurityDescriptor: couldn't allocate ACL\n"));
01331 }
01332
01333
KeBugCheckEx(REGISTRY_ERROR, 10, 2, 0, 0);
01334 }
01335
01336
Status =
RtlCreateAcl(Acl, AclLength, ACL_REVISION);
01337
if (!
NT_SUCCESS(
Status)) {
01338
CMLOG(
CML_MAJOR,
CMS_SEC) {
01339 KdPrint((
"CmpHiveRootSecurityDescriptor: couldn't initialize ACL\n"));
01340 }
01341
KeBugCheckEx(REGISTRY_ERROR, 10, 3, 0, 0);
01342 }
01343
01344
01345
01346
01347
Status =
RtlAddAccessAllowedAce(Acl,
01348 ACL_REVISION,
01349 KEY_ALL_ACCESS,
01350 SystemSid);
01351
if (
NT_SUCCESS(
Status)) {
01352
Status =
RtlAddAccessAllowedAce(Acl,
01353 ACL_REVISION,
01354 KEY_ALL_ACCESS,
01355 AdminSid);
01356 }
01357
if (
NT_SUCCESS(
Status)) {
01358
Status =
RtlAddAccessAllowedAce(Acl,
01359 ACL_REVISION,
01360 KEY_READ,
01361
WorldSid);
01362 }
01363
if (
NT_SUCCESS(
Status)) {
01364
Status =
RtlAddAccessAllowedAce(Acl,
01365 ACL_REVISION,
01366 KEY_READ,
01367 RestrictedSid);
01368 }
01369
if (!
NT_SUCCESS(
Status)) {
01370
CMLOG(
CML_MAJOR,
CMS_SEC) {
01371 KdPrint((
"CmpHiveRootSecurityDescriptor: RtlAddAce failed status %08lx\n",
Status));
01372 }
01373
01374
KeBugCheckEx(REGISTRY_ERROR, 10, 4, 0, 0);
01375 }
01376
01377
01378
01379
01380
Status =
RtlGetAce(Acl,0,&AceHeader);
01381
ASSERT(
NT_SUCCESS(
Status));
01382 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
01383
01384
Status =
RtlGetAce(Acl,1,&AceHeader);
01385
ASSERT(
NT_SUCCESS(
Status));
01386 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
01387
01388
Status =
RtlGetAce(Acl,2,&AceHeader);
01389
ASSERT(
NT_SUCCESS(
Status));
01390 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
01391
01392
Status =
RtlGetAce(Acl,3,&AceHeader);
01393
ASSERT(
NT_SUCCESS(
Status));
01394 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
01395
01396
01397
01398
01399
01400
01401
01402 SecurityDescriptor =
ExAllocatePool(
01403
PagedPool,
01404
sizeof(SECURITY_DESCRIPTOR) + AclLength
01405 );
01406
01407
if (SecurityDescriptor ==
NULL) {
01408
CMLOG(
CML_MAJOR,
CMS_SEC) {
01409 KdPrint((
"CmpHiveRootSecurityDescriptor: Couldn't allocate Sec. Desc.\n"));
01410 }
01411
KeBugCheckEx(REGISTRY_ERROR, 10, 5, 0, 0);
01412 }
01413
01414 AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor+1);
01415 RtlMoveMemory(AclCopy, Acl, AclLength);
01416
01417
Status =
RtlCreateSecurityDescriptor( SecurityDescriptor,
01418 SECURITY_DESCRIPTOR_REVISION );
01419
if (!
NT_SUCCESS(
Status)) {
01420
CMLOG(
CML_MAJOR,
CMS_SEC) {
01421 KdPrint((
"CmpHiveRootSecurityDescriptor: CreateSecDesc failed %08lx\n",
Status));
01422 }
01423
ExFreePool(SecurityDescriptor);
01424 SecurityDescriptor=
NULL;
01425
KeBugCheckEx(REGISTRY_ERROR, 10, 6, 0, 0);
01426 }
01427
01428
Status =
RtlSetDaclSecurityDescriptor( SecurityDescriptor,
01429
TRUE,
01430 AclCopy,
01431
FALSE );
01432
if (!
NT_SUCCESS(
Status)) {
01433
CMLOG(
CML_MAJOR,
CMS_SEC) {
01434 KdPrint((
"CmpHiveRootSecurityDescriptor: SetDacl failed %08lx\n",
Status));
01435 }
01436
ExFreePool(SecurityDescriptor);
01437 SecurityDescriptor=
NULL;
01438
KeBugCheckEx(REGISTRY_ERROR, 10, 7, 0, 0);
01439 }
01440
01441
01442
01443
01444
if (
WorldSid!=
NULL) {
01445
ExFreePool(
WorldSid);
01446 }
01447
if (RestrictedSid!=
NULL) {
01448
ExFreePool(RestrictedSid);
01449 }
01450
if (SystemSid!=
NULL) {
01451
ExFreePool(SystemSid);
01452 }
01453
if (AdminSid!=
NULL) {
01454
ExFreePool(AdminSid);
01455 }
01456
if (Acl!=
NULL) {
01457
ExFreePool(Acl);
01458 }
01459
01460
return(SecurityDescriptor);
01461 }
01462
01463
VOID
01464 CmpFreeSecurityDescriptor(
01465 IN
PHHIVE Hive,
01466 IN HCELL_INDEX Cell
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
PCELL_DATA Node;
01493
PCELL_DATA Security;
01494
HCELL_INDEX SecurityCell;
01495
01496
PAGED_CODE();
01497
CMLOG(
CML_FLOW,
CMS_SEC) {
01498 KdPrint((
"CmpFreeSecurityDescriptor for cell %ld\n",
Cell));
01499 }
01500
01501
01502
01503
01504 Node =
HvGetCell(
Hive,
Cell);
01505
ASSERT_NODE(&(Node->
u.
KeyNode));
01506
01507
01508
01509
01510 SecurityCell = Node->
u.
KeyNode.
Security;
01511 Security =
HvGetCell(
Hive, SecurityCell);
01512
ASSERT_SECURITY(&(Security->
u.
KeySecurity));
01513
01514
01515
if (Security->
u.
KeySecurity.
ReferenceCount == 1) {
01516
01517
01518
01519
01520
01521
CmpRemoveSecurityCellList(
Hive, SecurityCell);
01522
HvFreeCell(
Hive, SecurityCell);
01523
CMLOG(
CML_FLOW,
CMS_SEC) {
01524 KdPrint((
"CmpFreeSecurityDescriptor: freeing security cell\n"));
01525 }
01526 }
else {
01527
01528
01529
01530
01531
01532 Security->
u.
KeySecurity.
ReferenceCount -= 1;
01533
CMLOG(
CML_FLOW,
CMS_SEC) {
01534 KdPrint((
"CmpFreeSecurityDescriptor: decrementing reference count\n"));
01535 }
01536 }
01537
01538
01539
01540
01541 Node->
u.
KeyNode.
Security =
HCELL_NIL;
01542 }
01543
01544 BOOLEAN
01545 CmpFindMatchingDescriptorCell(
01546 IN
PHHIVE Hive,
01547 IN
PCM_KEY_NODE Node,
01548 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
01549 IN ULONG Type,
01550 OUT PHCELL_INDEX MatchingCell
01551 )
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 {
01590
PCM_KEY_NODE ChildCheckNode;
01591
PCM_KEY_NODE SiblingNode;
01592
PCM_KEY_SECURITY Security;
01593
PCM_KEY_NODE ParentNode;
01594
HCELL_INDEX SiblingCell;
01595
NTSTATUS Status;
01596 ULONG DescriptorLength;
01597 ULONG index;
01598
01599
PAGED_CODE();
01600
01601 DescriptorLength =
RtlLengthSecurityDescriptor(SecurityDescriptor);
01602
01603
01604
01605
01606
if (Node->Flags &
KEY_HIVE_ENTRY) {
01607
01608
01609
01610
01611
01612 ChildCheckNode = Node;
01613
goto RetryMyChildren;
01614 }
01615
01616 ParentNode = (
PCM_KEY_NODE)
HvGetCell(
Hive,Node->Parent);
01617
01618 Security =
CmpGetKeySecurity(
Hive,
01619 ParentNode,
01620 MatchingCell);
01621
01622
if ((DescriptorLength==Security->
DescriptorLength) &&
01623 (Type ==
HvGetCellType(*MatchingCell)) &&
01624 (RtlEqualMemory(SecurityDescriptor,
01625 &(Security->
Descriptor),
01626 DescriptorLength))) {
01627
01628
01629
01630
CMLOG(
CML_FLOW,
CMS_SEC) {
01631 KdPrint((
"CmpFindMatchingDescriptor: Cell's descriptor matched parent\n"));
01632 }
01633
return(
TRUE);
01634 }
01635
01636
01637
01638
01639 ChildCheckNode = ParentNode;
01640
01641
01642
01643
01644
01645
01646 RetryMyChildren:
01647 index=0;
01648
while (
TRUE) {
01649 SiblingCell =
CmpFindSubKeyByNumber(
Hive,ChildCheckNode,index++);
01650
if (SiblingCell ==
HCELL_NIL) {
01651
01652
01653
01654
return(
FALSE);
01655 }
01656 SiblingNode = (
PCM_KEY_NODE)
HvGetCell(
Hive,SiblingCell);
01657
01658
if (SiblingNode != Node) {
01659
01660
01661
01662
01663 Security =
CmpGetKeySecurity(
Hive,
01664 SiblingNode,
01665 MatchingCell);
01666
01667
01668
01669
01670
01671
if ((DescriptorLength==Security->
DescriptorLength) &&
01672 (Type ==
HvGetCellType(*MatchingCell)) &&
01673 (RtlEqualMemory(SecurityDescriptor,
01674 &(Security->
Descriptor),
01675 DescriptorLength))) {
01676
01677
01678
01679
CMLOG(
CML_FLOW,
CMS_SEC) {
01680 KdPrint((
"CmpFindMatchingDescriptor: Cell's descriptor "));
01681 KdPrint((
"matched sibling %d\n",index));
01682 }
01683
return(
TRUE);
01684 }
01685 }
01686 }
01687
01688
if (ChildCheckNode == ParentNode) {
01689
01690
01691
01692 ChildCheckNode = Node;
01693
goto RetryMyChildren;
01694 }
01695
01696
CMLOG(
CML_FLOW,
CMS_SEC) {
01697 KdPrint((
"CmpFindMatchingDescriptor: no matching descriptor found\n"));
01698 }
01699
return(
FALSE);
01700 }
01701
01702
01703 BOOLEAN
01704 CmpInsertSecurityCellList(
01705 IN
PHHIVE Hive,
01706 IN HCELL_INDEX NodeCell,
01707 IN HCELL_INDEX SecurityCell
01708 )
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735 {
01736
PCM_KEY_SECURITY FlinkCell;
01737
PCM_KEY_SECURITY BlinkCell;
01738
PCM_KEY_SECURITY Cell;
01739
PCM_KEY_NODE Node;
01740
PCM_KEY_NODE ParentNode;
01741
01742
PAGED_CODE();
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
Cell = (
PCM_KEY_SECURITY)
HvGetCell(
Hive, SecurityCell);
01757
ASSERT_SECURITY(
Cell);
01758
01759
if (
HvGetCellType(SecurityCell) ==
Volatile) {
01760
01761
Cell->Flink =
Cell->Blink = SecurityCell;
01762
01763 }
else {
01764
01765 Node = (
PCM_KEY_NODE)
HvGetCell(
Hive, NodeCell);
01766
ASSERT_NODE(Node);
01767
01768
if (Node->
Flags &
KEY_HIVE_ENTRY) {
01769
01770
01771
01772
01773
CMLOG(
CML_FLOW,
CMS_SEC) {
01774 KdPrint((
"CmpInsertSecurityCellList: hive creation\n"));
01775 }
01776
Cell->Flink =
Cell->Blink = SecurityCell;
01777
01778 }
else {
01779
CMLOG(
CML_FLOW,
CMS_SEC) {
01780 KdPrint((
"CmpInsertSecurityCellList: insert at parent\n"));
01781 }
01782
01783
01784
01785
01786 ParentNode = (
PCM_KEY_NODE)
HvGetCell(
Hive, Node->
Parent);
01787
ASSERT_NODE(ParentNode);
01788 BlinkCell = (
PCM_KEY_SECURITY)
HvGetCell(
01789
Hive,
01790 ParentNode->
Security
01791 );
01792
ASSERT_SECURITY(BlinkCell);
01793
01794
01795
01796
01797 FlinkCell = (
PCM_KEY_SECURITY)
HvGetCell(
01798
Hive,
01799 BlinkCell->
Flink
01800 );
01801
ASSERT_SECURITY(FlinkCell);
01802
01803
if (! (
HvMarkCellDirty(
Hive, ParentNode->
Security) &&
01804
HvMarkCellDirty(
Hive, BlinkCell->
Flink)))
01805 {
01806
return FALSE;
01807 }
01808
01809
01810
01811
01812
Cell->Flink = BlinkCell->
Flink;
01813
Cell->Blink = FlinkCell->
Blink;
01814 BlinkCell->
Flink = SecurityCell;
01815 FlinkCell->
Blink = SecurityCell;
01816 }
01817 }
01818
return TRUE;
01819 }
01820
01821
01822
VOID
01823 CmpRemoveSecurityCellList(
01824 IN
PHHIVE Hive,
01825 IN HCELL_INDEX SecurityCell
01826 )
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849 {
01850
PCM_KEY_SECURITY FlinkCell;
01851
PCM_KEY_SECURITY BlinkCell;
01852
PCM_KEY_SECURITY Cell;
01853
01854
PAGED_CODE();
01855
CMLOG(
CML_FLOW,
CMS_SEC) {
01856 KdPrint((
"CmpRemoveSecurityCellList: index %ld\n",SecurityCell));
01857 }
01858
Cell = (
PCM_KEY_SECURITY)
HvGetCell(
Hive, SecurityCell);
01859 FlinkCell = (
PCM_KEY_SECURITY)
HvGetCell(
Hive,
Cell->Flink);
01860 BlinkCell = (
PCM_KEY_SECURITY)
HvGetCell(
Hive,
Cell->Blink);
01861
01862
ASSERT(FlinkCell->
Blink == SecurityCell);
01863
ASSERT(BlinkCell->
Flink == SecurityCell);
01864
01865 FlinkCell->
Blink =
Cell->Blink;
01866 BlinkCell->
Flink =
Cell->Flink;
01867 }
01868