00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
#include "rmp.h"
00034
#include <bugcodes.h>
00035
00036
00037
SEP_LOGON_SESSION_TERMINATED_NOTIFICATION
00038 SeFileSystemNotifyRoutinesHead = {0};
00039
00040
00042
00043
00044
00046
00047 typedef struct _SEP_FILE_SYSTEM_NOTIFY_CONTEXT {
00048 WORK_QUEUE_ITEM WorkItem;
00049 LUID
LogonId;
00050 }
SEP_FILE_SYSTEM_NOTIFY_CONTEXT, *
PSEP_FILE_SYSTEM_NOTIFY_CONTEXT;
00051
00052
00054
00055
00056
00058
00059
NTSTATUS
00060
SepGetLogonSessionTrack(
00061 IN PLUID LogonId
00062 );
00063
00064
00065
VOID
00066
SepInformLsaOfDeletedLogon(
00067 IN PLUID LogonId
00068 );
00069
00070
VOID
00071
SepInformFileSystemsOfDeletedLogon(
00072 IN PLUID LogonId
00073 );
00074
00075
VOID
00076
SepNotifyFileSystems(
00077 IN PVOID Context
00078 );
00079
00080
#ifdef ALLOC_PRAGMA
00081
#pragma alloc_text(PAGE,SeRegisterLogonSessionTerminatedRoutine)
00082
#pragma alloc_text(PAGE,SeUnregisterLogonSessionTerminatedRoutine)
00083
#pragma alloc_text(PAGE,SeMarkLogonSessionForTerminationNotification)
00084
#pragma alloc_text(PAGE,SepRmCreateLogonSessionWrkr)
00085
#pragma alloc_text(PAGE,SepRmDeleteLogonSessionWrkr)
00086
#pragma alloc_text(PAGE,SepReferenceLogonSession)
00087
#pragma alloc_text(PAGE,SepDeReferenceLogonSession)
00088
#pragma alloc_text(PAGE,SepCreateLogonSessionTrack)
00089
#pragma alloc_text(PAGE,SepDeleteLogonSessionTrack)
00090
#pragma alloc_text(PAGE,SepInformLsaOfDeletedLogon)
00091
#pragma alloc_text(PAGE,SepInformFileSystemsOfDeletedLogon)
00092
#pragma alloc_text(PAGE,SepNotifyFileSystems)
00093
#endif
00094
00095
00096
00098
00099
00100
00102
00103
00104
00105
00106
00107
00108
00109 #define SepLogonSessionIndex( PLogonId ) ( \
00110
(PLogonId)->LowPart & SEP_LOGON_TRACK_INDEX_MASK \
00111
)
00112
00113
00114
00116
00117
00118
00120
00121
VOID
00122 SepRmCreateLogonSessionWrkr(
00123 IN PRM_COMMAND_MESSAGE CommandMessage,
00124 OUT PRM_REPLY_MESSAGE ReplyMessage
00125 )
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 {
00158
00159
NTSTATUS Status;
00160 LUID LogonId;
00161
00162
PAGED_CODE();
00163
00164
00165
00166
00167
00168
ASSERT( CommandMessage->CommandNumber == RmCreateLogonSession );
00169
00170
00171
00172
00173
00174
00175 LogonId = *((LUID UNALIGNED *) CommandMessage->CommandParams);
00176
00177
00178
00179
00180
00181
00182
00183
Status =
SepCreateLogonSessionTrack( &LogonId );
00184
00185
00186
00187
00188
00189
00190
00191
ReplyMessage->ReturnedStatus =
Status;
00192
00193
00194
return;
00195 }
00196
00197
00198
00199
VOID
00200 SepRmDeleteLogonSessionWrkr(
00201 IN PRM_COMMAND_MESSAGE CommandMessage,
00202 OUT PRM_REPLY_MESSAGE ReplyMessage
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
NTSTATUS Status;
00238 LUID LogonId;
00239
00240
PAGED_CODE();
00241
00242
00243
00244
00245
00246
ASSERT( CommandMessage->CommandNumber == RmDeleteLogonSession );
00247
00248
00249
00250
00251
00252
00253 LogonId = *((LUID UNALIGNED *) CommandMessage->CommandParams);
00254
00255
00256
00257
00258
00259
00260
00261
Status =
SepDeleteLogonSessionTrack( &LogonId );
00262
00263
00264
00265
00266
00267
00268
00269
ReplyMessage->ReturnedStatus =
Status;
00270
00271
00272
return;
00273 }
00274
00275
00276
00277
NTSTATUS
00278 SepReferenceLogonSession(
00279 IN PLUID LogonId
00280 )
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 {
00306
00307 ULONG SessionArrayIndex;
00308
PSEP_LOGON_SESSION_REFERENCES Previous, Current;
00309
00310
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00311
ULONG Refs;
00312
#endif //SEP_TRACK_LOGON_SESSION_REFS
00313
00314
PAGED_CODE();
00315
00316 SessionArrayIndex =
SepLogonSessionIndex( LogonId );
00317
00318
00319
00320
00321
00322
SepRmAcquireDbWriteLock();
00323
00324
00325
00326
00327
00328
00329 Previous = (
PSEP_LOGON_SESSION_REFERENCES)
00330 ((PVOID)&
SepLogonSessions[ SessionArrayIndex ]);
00331 Current = Previous->
Next;
00332
00333
while (Current !=
NULL) {
00334
00335
00336
00337
00338
00339
if (
RtlEqualLuid( LogonId, &Current->
LogonId) ) {
00340
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00341
ULONG Refs;
00342
#endif //SEP_TRACK_LOGON_SESSION_REFS
00343
00344 Current->
ReferenceCount += 1;
00345
00346
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00347
Refs = Current->
ReferenceCount;
00348
#endif //SEP_TRACK_LOGON_SESSION_REFS
00349
00350
SepRmReleaseDbWriteLock();
00351
00352
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00353
DbgPrint(
"SE (rm): ++ logon session: (%d, %d) to %d by (%d, %d)\n",
00354 LogonId->HighPart, LogonId->LowPart, Refs,
00355
PsGetCurrentThread()->Cid.UniqueProcess,
00356
PsGetCurrentThread()->Cid.UniqueThread);
00357
00358
#endif //SEP_TRACK_LOGON_SESSION_REFS
00359
return STATUS_SUCCESS;
00360 }
00361
00362 Previous = Current;
00363 Current = Current->
Next;
00364 }
00365
00366
SepRmReleaseDbWriteLock();
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
return STATUS_NO_SUCH_LOGON_SESSION;
00377
00378
00379
00380 }
00381
00382
00383
VOID
00384 SepDeReferenceLogonSession(
00385 IN PLUID LogonId
00386 )
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 {
00414
00415 ULONG SessionArrayIndex;
00416
PSEP_LOGON_SESSION_REFERENCES Previous, Current;
00417
00418
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00419
ULONG Refs;
00420
#endif //SEP_TRACK_LOGON_SESSION_REFS
00421
00422
PAGED_CODE();
00423
00424 SessionArrayIndex =
SepLogonSessionIndex( LogonId );
00425
00426
00427
00428
00429
00430
SepRmAcquireDbWriteLock();
00431
00432
00433
00434
00435
00436
00437 Previous = (
PSEP_LOGON_SESSION_REFERENCES)
00438 ((PVOID)&
SepLogonSessions[ SessionArrayIndex ]);
00439 Current = Previous->
Next;
00440
00441
while (Current !=
NULL) {
00442
00443
00444
00445
00446
00447
if (
RtlEqualLuid( LogonId, &Current->
LogonId) ) {
00448 Current->
ReferenceCount -= 1;
00449
if (Current->
ReferenceCount == 0) {
00450
00451
00452
00453
00454
00455 Previous->
Next = Current->
Next;
00456
00457
00458
00459
00460
00461
00462
00463
SepRmReleaseDbWriteLock();
00464
00465
00466
00467
00468
00469
00470
00471
if (Current->
Flags &
SEP_TERMINATION_NOTIFY) {
00472
SepInformFileSystemsOfDeletedLogon( LogonId );
00473 }
00474
00475
00476
00477
00478
00479
ExFreePool( (PVOID)Current );
00480
00481
00482
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00483
DbgPrint(
"SE (rm): -- ** logon session: (%d, %d) to ZERO by (%d, %d)\n",
00484 LogonId->HighPart, LogonId->LowPart,
00485
PsGetCurrentThread()->Cid.UniqueProcess,
00486
PsGetCurrentThread()->Cid.UniqueThread);
00487
00488
#endif //SEP_TRACK_LOGON_SESSION_REFS
00489
00490
00491
00492
00493
00494
SepInformLsaOfDeletedLogon( LogonId );
00495
00496
00497
00498
return;
00499
00500 }
00501
00502
00503
00504
00505
00506
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00507
Refs = Current->
ReferenceCount;
00508
#endif //SEP_TRACK_LOGON_SESSION_REFS
00509
00510
SepRmReleaseDbWriteLock();
00511
00512
#ifdef SEP_TRACK_LOGON_SESSION_REFS
00513
DbgPrint(
"SE (rm): -- logon session: (%d, %d) to %d by (%d, %d)\n",
00514 LogonId->HighPart, LogonId->LowPart, Refs,
00515
PsGetCurrentThread()->Cid.UniqueProcess,
00516
PsGetCurrentThread()->Cid.UniqueThread);
00517
#endif //SEP_TRACK_LOGON_SESSION_REFS
00518
00519
return;
00520 }
00521
00522 Previous = Current;
00523 Current = Current->
Next;
00524 }
00525
00526
SepRmReleaseDbWriteLock();
00527
00528
00529
00530
00531
00532
00533
KeBugCheck( DEREF_UNKNOWN_LOGON_SESSION );
00534
00535
return;
00536
00537 }
00538
00539
00540
NTSTATUS
00541 SepCreateLogonSessionTrack(
00542 IN PLUID LogonId
00543 )
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 {
00573
00574 ULONG SessionArrayIndex;
00575
PSEP_LOGON_SESSION_REFERENCES Previous, Current;
00576
PSEP_LOGON_SESSION_REFERENCES LogonSessionTrack;
00577
00578
PAGED_CODE();
00579
00580
00581
00582
00583
00584 LogonSessionTrack = (
PSEP_LOGON_SESSION_REFERENCES)
00585
ExAllocatePoolWithTag(
00586
PagedPool,
00587
sizeof(
SEP_LOGON_SESSION_REFERENCES),
00588 'sLeS'
00589 );
00590
00591
if (LogonSessionTrack ==
NULL) {
00592
return STATUS_INSUFFICIENT_RESOURCES;
00593 }
00594
00595 LogonSessionTrack->
LogonId = (*LogonId);
00596 LogonSessionTrack->
ReferenceCount = 0;
00597
00598
00599
00600 SessionArrayIndex =
SepLogonSessionIndex( LogonId );
00601
00602
00603
00604
00605
00606
SepRmAcquireDbWriteLock();
00607
00608
00609
00610
00611
00612
00613
00614 Previous = (
PSEP_LOGON_SESSION_REFERENCES)
00615 ((PVOID)&
SepLogonSessions[ SessionArrayIndex ]);
00616 Current = Previous->
Next;
00617
00618
while (Current !=
NULL) {
00619
00620
if (
RtlEqualLuid( LogonId, &Current->
LogonId) ) {
00621
00622
00623
00624
00625
00626
SepRmReleaseDbWriteLock();
00627
ExFreePool(LogonSessionTrack);
00628
return STATUS_LOGON_SESSION_EXISTS;
00629
00630 }
00631
00632 Previous = Current;
00633 Current = Current->
Next;
00634 }
00635
00636
00637
00638
00639
00640
00641
00642 LogonSessionTrack->
Next =
SepLogonSessions[ SessionArrayIndex ];
00643
SepLogonSessions[ SessionArrayIndex ] = LogonSessionTrack;
00644
00645
00646
00647
00648
SepRmReleaseDbWriteLock();
00649
return STATUS_SUCCESS;
00650
00651 }
00652
00653
00654
NTSTATUS
00655 SepDeleteLogonSessionTrack(
00656 IN PLUID LogonId
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
00690 {
00691
00692 ULONG SessionArrayIndex;
00693
PSEP_LOGON_SESSION_REFERENCES Previous, Current;
00694
00695
PAGED_CODE();
00696
00697 SessionArrayIndex =
SepLogonSessionIndex( LogonId );
00698
00699
00700
00701
00702
00703
SepRmAcquireDbWriteLock();
00704
00705
00706
00707
00708
00709
00710 Previous = (
PSEP_LOGON_SESSION_REFERENCES)
00711 ((PVOID)&
SepLogonSessions[ SessionArrayIndex ]);
00712 Current = Previous->
Next;
00713
00714
while (Current !=
NULL) {
00715
00716
00717
00718
00719
00720
if (
RtlEqualLuid( LogonId, &Current->
LogonId) ) {
00721
00722
if (Current->
ReferenceCount == 0) {
00723
00724
00725
00726
00727
00728 Previous->
Next = Current->
Next;
00729
00730
00731
00732
00733
00734
00735
00736
SepRmReleaseDbWriteLock();
00737
00738
00739
00740
00741
00742
00743
ExFreePool( (PVOID)Current );
00744
00745
00746
return STATUS_SUCCESS;
00747
00748 }
00749
00750
00751
00752
00753
00754
00755
00756
SepRmReleaseDbWriteLock();
00757
return STATUS_BAD_LOGON_SESSION_STATE;
00758 }
00759
00760 Previous = Current;
00761 Current = Current->
Next;
00762 }
00763
00764
SepRmReleaseDbWriteLock();
00765
00766
00767
00768
00769
00770
00771
return STATUS_NO_SUCH_LOGON_SESSION;
00772
00773 }
00774
00775
00776
VOID
00777 SepInformLsaOfDeletedLogon(
00778 IN PLUID LogonId
00779 )
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 {
00806
PSEP_LSA_WORK_ITEM DeleteLogonItem;
00807
00808
PAGED_CODE();
00809
00810
00811
00812
00813
00814
00815
00816 DeleteLogonItem =
ExAllocatePoolWithTag(
PagedPool,
sizeof(
SEP_LSA_WORK_ITEM), 'wLeS' );
00817
if (DeleteLogonItem ==
NULL) {
00818
00819
00820
00821
00822
00823
00824
return;
00825
00826 }
00827
00828 DeleteLogonItem->
CommandParams.LogonId = (*LogonId);
00829 DeleteLogonItem->
CommandNumber = LsapLogonSessionDeletedCommand;
00830 DeleteLogonItem->
CommandParamsLength =
sizeof( LUID );
00831 DeleteLogonItem->
ReplyBuffer =
NULL;
00832 DeleteLogonItem->
ReplyBufferLength = 0;
00833 DeleteLogonItem->
CleanupFunction =
NULL;
00834 DeleteLogonItem->
CleanupParameter = 0;
00835 DeleteLogonItem->
Tag =
SepDeleteLogon;
00836 DeleteLogonItem->
CommandParamsMemoryType = SepRmImmediateMemory;
00837
00838
if (!
SepQueueWorkItem( DeleteLogonItem,
TRUE )) {
00839
00840
ExFreePool( DeleteLogonItem );
00841 }
00842
00843
return;
00844
00845 }
00846
00847
00848
NTSTATUS
00849 SeRegisterLogonSessionTerminatedRoutine(
00850 IN
PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine
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
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION NewCallback;
00877
00878
PAGED_CODE();
00879
00880
if (CallbackRoutine ==
NULL) {
00881
return( STATUS_INVALID_PARAMETER );
00882 }
00883
00884 NewCallback =
ExAllocatePoolWithTag(
00885
PagedPool,
00886
sizeof(
SEP_LOGON_SESSION_TERMINATED_NOTIFICATION),
00887 'SFeS');
00888
00889
if (NewCallback ==
NULL) {
00890
return( STATUS_INSUFFICIENT_RESOURCES );
00891 }
00892
00893
SepRmAcquireDbWriteLock();
00894
00895 NewCallback->
Next =
SeFileSystemNotifyRoutinesHead.
Next;
00896
00897 NewCallback->
CallbackRoutine = CallbackRoutine;
00898
00899
SeFileSystemNotifyRoutinesHead.
Next = NewCallback;
00900
00901
SepRmReleaseDbWriteLock();
00902
00903
return( STATUS_SUCCESS );
00904 }
00905
00906
00907
NTSTATUS
00908 SeUnregisterLogonSessionTerminatedRoutine(
00909 IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine
00910 )
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933 {
00934
NTSTATUS Status;
00935
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION PreviousEntry;
00936
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION NotifyEntry;
00937
00938
PAGED_CODE();
00939
00940
if (CallbackRoutine ==
NULL) {
00941
return( STATUS_INVALID_PARAMETER );
00942 }
00943
00944
SepRmAcquireDbWriteLock();
00945
00946
for (PreviousEntry = &
SeFileSystemNotifyRoutinesHead,
00947 NotifyEntry =
SeFileSystemNotifyRoutinesHead.
Next;
00948 NotifyEntry !=
NULL;
00949 PreviousEntry = NotifyEntry,
00950 NotifyEntry = NotifyEntry->
Next) {
00951
00952
if (NotifyEntry->CallbackRoutine == CallbackRoutine)
00953
break;
00954
00955 }
00956
00957
if (NotifyEntry !=
NULL) {
00958
00959 PreviousEntry->
Next = NotifyEntry->
Next;
00960
00961
ExFreePool( NotifyEntry );
00962
00963
Status = STATUS_SUCCESS;
00964
00965 }
else {
00966
00967
Status = STATUS_NOT_FOUND;
00968
00969 }
00970
00971
SepRmReleaseDbWriteLock();
00972
00973
return(
Status );
00974
00975 }
00976
00977
00978
NTSTATUS
00979 SeMarkLogonSessionForTerminationNotification(
00980 IN PLUID LogonId
00981 )
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 {
01003
01004 ULONG SessionArrayIndex;
01005
PSEP_LOGON_SESSION_REFERENCES Previous, Current;
01006
01007
PAGED_CODE();
01008
01009 SessionArrayIndex =
SepLogonSessionIndex( LogonId );
01010
01011
01012
01013
01014
01015
SepRmAcquireDbWriteLock();
01016
01017
01018
01019
01020
01021
01022 Previous = (
PSEP_LOGON_SESSION_REFERENCES)
01023 ((PVOID)&
SepLogonSessions[ SessionArrayIndex ]);
01024 Current = Previous->
Next;
01025
01026
while (Current !=
NULL) {
01027
01028
01029
01030
01031
01032
if (
RtlEqualLuid( LogonId, &Current->
LogonId) ) {
01033 Current->
Flags |=
SEP_TERMINATION_NOTIFY;
01034
break;
01035 }
01036
01037 Previous = Current;
01038 Current = Current->
Next;
01039 }
01040
01041
SepRmReleaseDbWriteLock();
01042
01043
return( (Current !=
NULL) ? STATUS_SUCCESS : STATUS_NOT_FOUND );
01044
01045 }
01046
01047
01048
VOID
01049 SepInformFileSystemsOfDeletedLogon(
01050 IN PLUID LogonId
01051 )
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 {
01075
PSEP_FILE_SYSTEM_NOTIFY_CONTEXT FSNotifyContext;
01076
01077
PAGED_CODE();
01078
01079 FSNotifyContext =
ExAllocatePoolWithTag(
01080
NonPagedPool,
01081
sizeof(
SEP_FILE_SYSTEM_NOTIFY_CONTEXT),
01082 'SFeS');
01083
01084
if (FSNotifyContext ==
NULL) {
01085
01086
01087
01088
01089
01090
01091
return;
01092
01093 }
01094
01095 FSNotifyContext->
LogonId = *LogonId;
01096
01097
ExInitializeWorkItem( &FSNotifyContext->
WorkItem,
01098 (
PWORKER_THREAD_ROUTINE)
SepNotifyFileSystems,
01099 (PVOID) FSNotifyContext);
01100
01101
ExQueueWorkItem( &FSNotifyContext->WorkItem,
DelayedWorkQueue );
01102
01103 }
01104
01105
01106
VOID
01107 SepNotifyFileSystems(
01108 IN PVOID Context
01109 )
01110 {
01111
PSEP_FILE_SYSTEM_NOTIFY_CONTEXT FSNotifyContext =
01112 (
PSEP_FILE_SYSTEM_NOTIFY_CONTEXT) Context;
01113
01114
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION NextCallback;
01115
01116
PAGED_CODE();
01117
01118
01119
01120
01121
01122
SepRmAcquireDbReadLock();
01123
01124 NextCallback =
SeFileSystemNotifyRoutinesHead.
Next;
01125
01126
while (NextCallback !=
NULL) {
01127
01128 NextCallback->
CallbackRoutine( &FSNotifyContext->
LogonId );
01129
01130 NextCallback = NextCallback->
Next;
01131 }
01132
01133
SepRmReleaseDbReadLock();
01134
01135
ExFreePool( FSNotifyContext );
01136 }
01137