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
#include <nt.h>
00030
#include <ntos.h>
00031
#include <zwapi.h>
00032
#include "sep.h"
00033
#include "sertlp.h"
00034
#include "adt.h"
00035
#include "adtp.h"
00036
#include "rmp.h"
00037
00038
00039
00040
#ifdef ALLOC_PRAGMA
00041
00042
#pragma alloc_text(PAGE,SepAdtCopyToLsaSharedMemory)
00043
#pragma alloc_text(PAGE,SepAdtLogAuditRecord)
00044
#pragma alloc_text(PAGE,SepAdtMarshallAuditRecord)
00045
#pragma alloc_text(PAGE,SepAdtSetAuditLogInformation)
00046
#pragma alloc_text(PAGE,SepDequeueWorkItem)
00047
#pragma alloc_text(PAGE,SepQueueWorkItem)
00048
00049
#endif
00050
00051
VOID
00052 SepAdtLogAuditRecord(
00053 IN PSE_ADT_PARAMETER_ARRAY AuditParameters
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
NTSTATUS Status;
00086
PSEP_LSA_WORK_ITEM AuditWorkItem;
00087
00088
PAGED_CODE();
00089
00090 AuditWorkItem =
ExAllocatePoolWithTag(
PagedPool,
sizeof(
SEP_LSA_WORK_ITEM ), 'iAeS' );
00091
00092
if ( AuditWorkItem ==
NULL ) {
00093
00094
SepAuditFailed();
00095
return;
00096 }
00097
00098 AuditWorkItem->
Tag =
SepAuditRecord;
00099 AuditWorkItem->
CommandNumber = LsapWriteAuditMessageCommand;
00100 AuditWorkItem->
ReplyBuffer =
NULL;
00101 AuditWorkItem->
ReplyBufferLength = 0;
00102 AuditWorkItem->
CleanupFunction =
NULL;
00103
00104
00105
00106
00107
00108
00109
Status =
SepAdtMarshallAuditRecord(
00110 AuditParameters,
00111 (PSE_ADT_PARAMETER_ARRAY *) &AuditWorkItem->
CommandParams.BaseAddress,
00112 &AuditWorkItem->
CommandParamsMemoryType
00113 );
00114
00115
if (
NT_SUCCESS(
Status)) {
00116
00117
00118
00119
00120
00121
00122 AuditWorkItem->
CommandParamsLength =
00123 ((PSE_ADT_PARAMETER_ARRAY) AuditWorkItem->
CommandParams.BaseAddress)->Length;
00124
00125
00126
00127
00128
00129
00130
if (!
SepQueueWorkItem( AuditWorkItem, (BOOLEAN)(
SepCrashOnAuditFail ?
TRUE :
FALSE) )) {
00131
00132
ExFreePool( AuditWorkItem->
CommandParams.BaseAddress );
00133
ExFreePool( AuditWorkItem );
00134
00135
00136
00137
00138
00139
00140
SepAuditFailed();
00141 }
00142
00143 }
else {
00144
00145
ExFreePool( AuditWorkItem );
00146
SepAuditFailed();
00147 }
00148 }
00149
00150
00151
00152
VOID
00153 SepAuditFailed(
00154 VOID
00155 )
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 {
00175
NTSTATUS Status;
00176 OBJECT_ATTRIBUTES Obja;
00177 HANDLE KeyHandle;
00178 UNICODE_STRING
KeyName;
00179 UNICODE_STRING
ValueName;
00180 UCHAR NewValue;
00181
00182
ASSERT(
sizeof(UCHAR) ==
sizeof(BOOLEAN));
00183
00184
if (!
SepCrashOnAuditFail) {
00185
return;
00186 }
00187
00188
00189
00190
00191
00192
RtlInitUnicodeString( &
KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa");
00193
00194 InitializeObjectAttributes( &Obja,
00195 &
KeyName,
00196 OBJ_CASE_INSENSITIVE |
00197 OBJ_KERNEL_HANDLE,
00198
NULL,
00199
NULL
00200 );
00201
do {
00202
00203
Status = ZwOpenKey(
00204 &KeyHandle,
00205 KEY_SET_VALUE,
00206 &Obja
00207 );
00208
00209 }
while ((
Status == STATUS_INSUFFICIENT_RESOURCES) || (
Status == STATUS_NO_MEMORY));
00210
00211
00212
00213
00214
00215
if (
Status == STATUS_OBJECT_NAME_NOT_FOUND) {
00216
SepCrashOnAuditFail =
FALSE;
00217
return;
00218 }
00219
00220
if (!
NT_SUCCESS(
Status )) {
00221
goto bugcheck;
00222 }
00223
00224
RtlInitUnicodeString( &
ValueName, CRASH_ON_AUDIT_FAIL_VALUE );
00225
00226 NewValue = LSAP_ALLOW_ADIMIN_LOGONS_ONLY;
00227
00228
do {
00229
00230
Status = ZwSetValueKey( KeyHandle,
00231 &
ValueName,
00232 0,
00233 REG_NONE,
00234 &NewValue,
00235
sizeof(UCHAR)
00236 );
00237
00238 }
while ((
Status == STATUS_INSUFFICIENT_RESOURCES) || (
Status == STATUS_NO_MEMORY));
00239
ASSERT(
NT_SUCCESS(
Status));
00240
00241
if (!
NT_SUCCESS(
Status )) {
00242
goto bugcheck;
00243 }
00244
00245
do {
00246
00247
Status = ZwFlushKey( KeyHandle );
00248
00249 }
while ((
Status == STATUS_INSUFFICIENT_RESOURCES) || (
Status == STATUS_NO_MEMORY));
00250
ASSERT(
NT_SUCCESS(
Status));
00251
00252
00253
00254
00255
00256 bugcheck:
00257
00258
KeBugCheck(AUDIT_FAILURE);
00259 }
00260
00261
00262
00263
NTSTATUS
00264 SepAdtMarshallAuditRecord(
00265 IN PSE_ADT_PARAMETER_ARRAY AuditParameters,
00266 OUT PSE_ADT_PARAMETER_ARRAY *MarshalledAuditParameters,
00267 OUT PSEP_RM_LSA_MEMORY_TYPE RecordMemoryType
00268 )
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 {
00296 ULONG i;
00297 ULONG TotalSize =
sizeof( SE_ADT_PARAMETER_ARRAY );
00298 PUNICODE_STRING TargetString;
00299 PCHAR Base;
00300 ULONG BaseIncr;
00301
00302
PAGED_CODE();
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
for (i=0; i<AuditParameters->ParameterCount; i++) {
00315 TotalSize += (ULONG)LongAlignSize(AuditParameters->Parameters[i].Length);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324 *MarshalledAuditParameters =
ExAllocatePoolWithTag(
PagedPool, TotalSize, 'pAeS' );
00325
00326
if (*MarshalledAuditParameters ==
NULL) {
00327
00328 *RecordMemoryType = SepRmNoMemory;
00329
return(STATUS_INSUFFICIENT_RESOURCES);
00330 }
00331
00332 *RecordMemoryType = SepRmPagedPoolMemory;
00333
00334 RtlCopyMemory (
00335 *MarshalledAuditParameters,
00336 AuditParameters,
00337
sizeof( SE_ADT_PARAMETER_ARRAY )
00338 );
00339
00340 (*MarshalledAuditParameters)->Length = TotalSize;
00341 (*MarshalledAuditParameters)->Flags = SE_ADT_PARAMETERS_SELF_RELATIVE;
00342
00343
00344
00345
00346
00347
00348 Base = (PCHAR) ((PCHAR)(*MarshalledAuditParameters) +
sizeof( SE_ADT_PARAMETER_ARRAY ));
00349
00350
for (i=0; i<AuditParameters->ParameterCount; i++) {
00351
00352
00353
switch (AuditParameters->Parameters[i].Type) {
00354
case SeAdtParmTypeNone:
00355
case SeAdtParmTypeUlong:
00356
case SeAdtParmTypeLogonId:
00357
case SeAdtParmTypeNoLogonId:
00358
case SeAdtParmTypeAccessMask:
00359 {
00360
00361
00362
00363
00364
break;
00365
00366 }
00367
case SeAdtParmTypeString:
00368
case SeAdtParmTypeFileSpec:
00369 {
00370 PUNICODE_STRING
SourceString;
00371
00372
00373
00374
00375
00376 TargetString = (PUNICODE_STRING)Base;
00377
00378
SourceString = AuditParameters->Parameters[i].Address;
00379
00380 *TargetString = *
SourceString;
00381
00382
00383
00384
00385
00386
00387 (*MarshalledAuditParameters)->Parameters[i].Address = Base - (ULONG_PTR)(*MarshalledAuditParameters);
00388
00389 Base +=
sizeof( UNICODE_STRING );
00390
00391 RtlCopyMemory( Base,
SourceString->Buffer,
SourceString->Length );
00392
00393
00394
00395
00396
00397
00398 TargetString->Buffer = (PWSTR)(Base - (ULONG_PTR)(*MarshalledAuditParameters));
00399
00400 BaseIncr = (ULONG)LongAlignSize(
SourceString->Length);
00401
00402 Base += BaseIncr;
00403
00404
break;
00405 }
00406
00407
00408
00409
00410
case SeAdtParmTypeSid:
00411
case SeAdtParmTypePrivs:
00412
case SeAdtParmTypeObjectTypes:
00413 {
00414
00415
00416
00417
00418 RtlCopyMemory( Base,
00419 AuditParameters->Parameters[i].Address,
00420 AuditParameters->Parameters[i].Length );
00421
00422
00423
00424
00425
00426
00427 (*MarshalledAuditParameters)->Parameters[i].Address = Base - (ULONG_PTR)(*MarshalledAuditParameters);
00428
00429 Base += (ULONG)LongAlignSize( AuditParameters->Parameters[i].Length );
00430
00431
00432
break;
00433 }
00434
default:
00435 {
00436
00437
00438
00439
00440
ASSERT(
FALSE );
00441
break;
00442 }
00443 }
00444 }
00445
00446
return( STATUS_SUCCESS );
00447 }
00448
00449
00450
VOID
00451 SepAdtSetAuditLogInformation(
00452 IN PPOLICY_AUDIT_LOG_INFO AuditLogInformation
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
PAGED_CODE();
00481
00482
00483
00484
00485
00486
SepRmAcquireDbWriteLock();
00487
00488
00489
00490
00491
00492
SepAdtLogInformation = *AuditLogInformation;
00493
00494
00495
00496
00497
00498
SepRmReleaseDbWriteLock();
00499 }
00500
00501
00502
00503
NTSTATUS
00504 SepAdtCopyToLsaSharedMemory(
00505 IN HANDLE LsaProcessHandle,
00506 IN PVOID Buffer,
00507 IN ULONG BufferLength,
00508 OUT PVOID *LsaBufferAddress
00509 )
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 {
00537
NTSTATUS Status, SecondaryStatus;
00538 PVOID OutputLsaBufferAddress =
NULL;
00539 SIZE_T RegionSize = BufferLength;
00540
00541
PAGED_CODE();
00542
00543
Status = ZwAllocateVirtualMemory(
00544 LsaProcessHandle,
00545 &OutputLsaBufferAddress,
00546 0,
00547 &RegionSize,
00548 MEM_COMMIT,
00549 PAGE_READWRITE
00550 );
00551
00552
if (!
NT_SUCCESS(
Status)) {
00553
00554
goto CopyToLsaSharedMemoryError;
00555 }
00556
00557
Status = ZwWriteVirtualMemory(
00558 LsaProcessHandle,
00559 OutputLsaBufferAddress,
00560
Buffer,
00561 BufferLength,
00562
NULL
00563 );
00564
00565
if (!
NT_SUCCESS(
Status)) {
00566
00567
goto CopyToLsaSharedMemoryError;
00568 }
00569
00570 *LsaBufferAddress = OutputLsaBufferAddress;
00571
return(
Status);
00572
00573 CopyToLsaSharedMemoryError:
00574
00575
00576
00577
00578
00579
if (OutputLsaBufferAddress !=
NULL) {
00580
00581 RegionSize = 0;
00582
00583 SecondaryStatus = ZwFreeVirtualMemory(
00584 LsaProcessHandle,
00585 &OutputLsaBufferAddress,
00586 &RegionSize,
00587 MEM_RELEASE
00588 );
00589
00590
ASSERT(
NT_SUCCESS(SecondaryStatus));
00591
00592 OutputLsaBufferAddress =
NULL;
00593 }
00594
00595
return(
Status);
00596 }
00597
00598
00599 BOOLEAN
00600 SepQueueWorkItem(
00601 IN
PSEP_LSA_WORK_ITEM LsaWorkItem,
00602 IN BOOLEAN ForceQueue
00603 )
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 {
00628 BOOLEAN rc =
TRUE;
00629 BOOLEAN StartExThread =
FALSE ;
00630
00631
PAGED_CODE();
00632
00633
#if 0
00634
00635
DbgPrint(
"Queueing an audit\n");
00636
00637
#endif
00638
00639
SepLockLsaQueue();
00640
00641
if (
SepAdtDiscardingAudits && !ForceQueue) {
00642
00643
if (
SepAdtCurrentListLength <
SepAdtMinListLength) {
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
SepAdtDiscardingAudits =
FALSE;
00658
00659
SepAdtGenerateDiscardAudit();
00660
#if 0
00661
DbgPrint(
"Auditing resumed\n");
00662
#endif
00663
00664
00665
00666
00667
00668
SepAdtCountEventsDiscarded = 0;
00669
00670
00671
00672
00673
00674
00675 }
else {
00676
00677
00678
00679
00680
00681
00682
SepAdtCountEventsDiscarded++;
00683 rc =
FALSE;
00684
goto Exit;
00685 }
00686 }
00687
00688
if (
SepAdtCurrentListLength <
SepAdtMaxListLength || ForceQueue) {
00689
00690 InsertTailList(&
SepLsaQueue, &LsaWorkItem->List);
00691
00692
if (++
SepAdtCurrentListLength == 1) {
00693
00694
#if 0
00695
DbgPrint(
"Queueing a work item\n");
00696
#endif
00697
00698 StartExThread =
TRUE ;
00699 }
00700
00701 }
else {
00702
00703
00704
00705
00706
00707
00708
00709
SepAdtDiscardingAudits =
TRUE;
00710
00711
#if 0
00712
DbgPrint(
"Starting to discard audits\n");
00713
#endif
00714
00715 rc =
FALSE;
00716 }
00717
00718 Exit:
00719
00720
SepUnlockLsaQueue();
00721
00722
if ( StartExThread )
00723 {
00724
ExInitializeWorkItem( &
SepExWorkItem.
WorkItem,
00725 (
PWORKER_THREAD_ROUTINE)
SepRmCallLsa,
00726 &
SepExWorkItem
00727 );
00728
00729
ExQueueWorkItem( &
SepExWorkItem.
WorkItem,
DelayedWorkQueue );
00730 }
00731
00732
return( rc );
00733 }
00734
00735
00736
00737
PSEP_LSA_WORK_ITEM
00738 SepDequeueWorkItem(
00739 VOID
00740 )
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 {
00760
PSEP_LSA_WORK_ITEM OldWorkQueueItem;
00761
00762
PAGED_CODE();
00763
00764
SepLockLsaQueue();
00765
00766 OldWorkQueueItem = (
PSEP_LSA_WORK_ITEM)RemoveHeadList(&
SepLsaQueue);
00767 OldWorkQueueItem->
List.Flink =
NULL;
00768
ExFreePool( OldWorkQueueItem );
00769
00770
SepAdtCurrentListLength--;
00771
00772
#if 0
00773
DbgPrint(
"Removing item\n");
00774
#endif
00775
00776
if (IsListEmpty( &
SepLsaQueue )) {
00777
00778
SepUnlockLsaQueue();
00779
return(
NULL );
00780 }
00781
00782
00783
00784
00785
00786
00787
SepUnlockLsaQueue();
00788
return((
PSEP_LSA_WORK_ITEM)(&
SepLsaQueue)->Flink);
00789 }