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 "sep.h"
00030
#include "seopaque.h"
00031
#include "tokenp.h"
00032
00033
NTSTATUS
00034
SepCreateImpersonationTokenDacl(
00035 IN PTOKEN Token,
00036 IN PACCESS_TOKEN PrimaryToken,
00037 OUT PACL *Acl
00038 );
00039
00040
#ifdef ALLOC_PRAGMA
00041
#pragma alloc_text(PAGE,NtOpenProcessToken)
00042
#pragma alloc_text(PAGE,NtOpenThreadToken)
00043
#pragma alloc_text(PAGE,SepCreateImpersonationTokenDacl)
00044
#endif
00045
00046
00047
00048
NTSTATUS
00049 SepCreateImpersonationTokenDacl(
00050 IN PTOKEN Token,
00051 IN PACCESS_TOKEN PrimaryToken,
00052 OUT PACL *Acl
00053 )
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 PSID ServerUserSid;
00092 PSID ClientUserSid;
00093
NTSTATUS Status = STATUS_SUCCESS;
00094 ULONG AclLength;
00095 PACL NewDacl;
00096 PSECURITY_DESCRIPTOR OldDescriptor;
00097 BOOLEAN MemoryAllocated;
00098 PACL OldDacl;
00099 BOOLEAN DaclPresent;
00100 BOOLEAN DaclDefaulted;
00101
00102
PAGED_CODE();
00103
00104 ServerUserSid = ((
PTOKEN)
PrimaryToken)->UserAndGroups[0].Sid;
00105
00106 ClientUserSid =
Token->UserAndGroups[0].Sid;
00107
00108
00109
00110
00111
00112 AclLength = 5 *
sizeof( ACCESS_ALLOWED_ACE ) - 5 *
sizeof( ULONG ) +
00113
SeLengthSid( ServerUserSid ) +
SeLengthSid(
SeLocalSystemSid ) +
00114
SeLengthSid( ClientUserSid ) +
SeLengthSid(
SeAliasAdminsSid ) +
00115
SeLengthSid(
SeRestrictedSid ) +
sizeof( ACL );
00116
00117 NewDacl =
ExAllocatePool(
PagedPool, AclLength );
00118
00119
if (NewDacl ==
NULL) {
00120
00121 *Acl =
NULL;
00122
return STATUS_INSUFFICIENT_RESOURCES;
00123 }
00124
00125
Status =
RtlCreateAcl( NewDacl, AclLength, ACL_REVISION2 );
00126
ASSERT(
NT_SUCCESS(
Status ));
00127
00128
Status =
RtlAddAccessAllowedAce (
00129 NewDacl,
00130 ACL_REVISION2,
00131 TOKEN_ALL_ACCESS,
00132 ServerUserSid
00133 );
00134
ASSERT(
NT_SUCCESS(
Status ));
00135
00136
Status =
RtlAddAccessAllowedAce (
00137 NewDacl,
00138 ACL_REVISION2,
00139 TOKEN_ALL_ACCESS,
00140 ClientUserSid
00141 );
00142
ASSERT(
NT_SUCCESS(
Status ));
00143
00144
Status =
RtlAddAccessAllowedAce (
00145 NewDacl,
00146 ACL_REVISION2,
00147 TOKEN_ALL_ACCESS,
00148
SeAliasAdminsSid
00149 );
00150
ASSERT(
NT_SUCCESS(
Status ));
00151
00152
Status =
RtlAddAccessAllowedAce (
00153 NewDacl,
00154 ACL_REVISION2,
00155 TOKEN_ALL_ACCESS,
00156
SeLocalSystemSid
00157 );
00158
ASSERT(
NT_SUCCESS(
Status ));
00159
00160
if(ARGUMENT_PRESENT(((
PTOKEN)
PrimaryToken)->RestrictedSids) ||
00161 ARGUMENT_PRESENT(
Token->RestrictedSids)) {
00162
Status =
RtlAddAccessAllowedAce (
00163 NewDacl,
00164 ACL_REVISION2,
00165 TOKEN_ALL_ACCESS,
00166
SeRestrictedSid
00167 );
00168
ASSERT(
NT_SUCCESS(
Status ));
00169 }
00170
00171 *Acl = NewDacl;
00172
return STATUS_SUCCESS;
00173 }
00174
00175
00176
00177
NTSTATUS
00178 NtOpenProcessToken(
00179 IN HANDLE ProcessHandle,
00180 IN ACCESS_MASK DesiredAccess,
00181 OUT PHANDLE TokenHandle
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 PVOID
Token;
00211
KPROCESSOR_MODE PreviousMode;
00212
NTSTATUS Status;
00213
00214 HANDLE LocalHandle;
00215
00216
PAGED_CODE();
00217
00218 PreviousMode = KeGetPreviousMode();
00219
00220
00221
00222
00223
00224
if (PreviousMode !=
KernelMode) {
00225
00226
try {
00227
00228
ProbeForWriteHandle(TokenHandle);
00229
00230 } except(
EXCEPTION_EXECUTE_HANDLER) {
00231
return GetExceptionCode();
00232 }
00233
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
Status =
PsOpenTokenOfProcess( ProcessHandle, ((PACCESS_TOKEN *)&
Token));
00244
00245
if (!
NT_SUCCESS(
Status)) {
00246
return Status;
00247 }
00248
00249
00250
00251
00252
00253
Status =
ObOpenObjectByPointer(
00254 (PVOID)
Token,
00255 0,
00256
NULL,
00257 DesiredAccess,
00258
SepTokenObjectType,
00259 PreviousMode,
00260 &LocalHandle
00261 );
00262
00263
00264
00265
00266
00267
00268
00269
00270
ObDereferenceObject(
Token );
00271
00272
00273
00274
00275
00276
if (
NT_SUCCESS(
Status)) {
00277
00278
try {
00279
00280 *TokenHandle = LocalHandle;
00281
00282 } except(
EXCEPTION_EXECUTE_HANDLER) {
00283
00284
return GetExceptionCode();
00285
00286 }
00287 }
00288
00289
return Status;
00290
00291 }
00292
00293
NTSTATUS
00294 SepOpenTokenOfThread(
00295 IN HANDLE ThreadHandle,
00296 IN BOOLEAN OpenAsSelf,
00297 OUT PACCESS_TOKEN *Token,
00298 OUT
PETHREAD *Thread,
00299 OUT PBOOLEAN CopyOnOpen,
00300 OUT PBOOLEAN EffectiveOnly,
00301 OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
00302 )
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 {
00359
00360
NTSTATUS
00361
Status;
00362
00363
KPROCESSOR_MODE
00364 PreviousMode;
00365
00366 SE_IMPERSONATION_STATE
00367 DisabledImpersonationState;
00368
00369 BOOLEAN
00370 RestoreImpersonationState =
FALSE;
00371
00372 PreviousMode = KeGetPreviousMode();
00373
00374
00375
00376
00377
00378
00379
if (OpenAsSelf) {
00380 RestoreImpersonationState =
PsDisableImpersonation(
00381
PsGetCurrentThread(),
00382 &DisabledImpersonationState
00383 );
00384 }
00385
00386
00387
00388
00389
00390
00391
Status =
ObReferenceObjectByHandle(
00392
ThreadHandle,
00393 THREAD_QUERY_INFORMATION,
00394
PsThreadType,
00395 PreviousMode,
00396 (PVOID *)Thread,
00397
NULL
00398 );
00399
00400
00401
00402
00403
if (RestoreImpersonationState) {
00404
PsRestoreImpersonation(
00405
PsGetCurrentThread(),
00406 &DisabledImpersonationState
00407 );
00408 }
00409
00410
if (!
NT_SUCCESS(
Status)) {
00411
return Status;
00412 }
00413
00414
00415
00416
00417
00418 (*Token) =
PsReferenceImpersonationToken( *Thread,
00419 CopyOnOpen,
00420 EffectiveOnly,
00421 ImpersonationLevel
00422 );
00423
00424
00425
00426
00427
00428
00429
00430
00431
if ((*Token) ==
NULL) {
00432
ObDereferenceObject( *Thread );
00433 (*Thread) =
NULL;
00434
return STATUS_NO_TOKEN;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
if ((*ImpersonationLevel) <= SecurityAnonymous) {
00444
PsDereferenceImpersonationToken( (*
Token) );
00445
ObDereferenceObject( *Thread );
00446 (*Thread) =
NULL;
00447 (*Token) =
NULL;
00448
return STATUS_CANT_OPEN_ANONYMOUS;
00449 }
00450
00451
00452
return STATUS_SUCCESS;
00453
00454 }
00455
00456
00457
NTSTATUS
00458 NtOpenThreadToken(
00459 IN HANDLE ThreadHandle,
00460 IN ACCESS_MASK DesiredAccess,
00461 IN BOOLEAN OpenAsSelf,
00462 OUT PHANDLE TokenHandle
00463 )
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 {
00512
00513
KPROCESSOR_MODE PreviousMode;
00514
NTSTATUS Status;
00515
00516 PVOID
Token;
00517
PTOKEN NewToken =
NULL;
00518 BOOLEAN CopyOnOpen;
00519 BOOLEAN EffectiveOnly;
00520 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
00521 SE_IMPERSONATION_STATE DisabledImpersonationState;
00522 BOOLEAN RestoreImpersonationState =
FALSE;
00523
00524 HANDLE LocalHandle;
00525 SECURITY_DESCRIPTOR SecurityDescriptor;
00526 OBJECT_ATTRIBUTES
ObjectAttributes;
00527 PACL NewAcl =
NULL;
00528
PETHREAD Thread;
00529
PETHREAD OriginalThread =
NULL;
00530 PACCESS_TOKEN
PrimaryToken;
00531
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
00532
00533
PAGED_CODE();
00534
00535 PreviousMode = KeGetPreviousMode();
00536
00537
00538
00539
00540
00541
if (PreviousMode !=
KernelMode) {
00542
00543
try {
00544
00545
ProbeForWriteHandle(TokenHandle);
00546
00547 } except(
EXCEPTION_EXECUTE_HANDLER) {
00548
return GetExceptionCode();
00549 }
00550
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
Status =
SepOpenTokenOfThread(
ThreadHandle,
00563 OpenAsSelf,
00564 ((PACCESS_TOKEN *)&
Token),
00565 &OriginalThread,
00566 &CopyOnOpen,
00567 &EffectiveOnly,
00568 &ImpersonationLevel
00569 );
00570
00571
if (!
NT_SUCCESS(
Status)) {
00572
return Status;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
if (OpenAsSelf) {
00586 RestoreImpersonationState =
PsDisableImpersonation(
00587
PsGetCurrentThread(),
00588 &DisabledImpersonationState
00589 );
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
if (CopyOnOpen) {
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
Status =
ObReferenceObjectByHandle(
00611
ThreadHandle,
00612 THREAD_ALL_ACCESS,
00613
PsThreadType,
00614
KernelMode,
00615 (PVOID)&Thread,
00616
NULL
00617 );
00618
00619
00620
00621
00622
00623
00624
if (
NT_SUCCESS(
Status) && (Thread != OriginalThread)) {
00625
Status = STATUS_OBJECT_TYPE_MISMATCH;
00626 }
00627
00628
if (
NT_SUCCESS(
Status)) {
00629
00630
PrimaryToken =
PsReferencePrimaryToken(Thread->ThreadsProcess);
00631
00632
Status =
SepCreateImpersonationTokenDacl(
00633 (
PTOKEN)
Token,
00634
PrimaryToken,
00635 &NewAcl
00636 );
00637
00638
PsDereferencePrimaryToken(
PrimaryToken );
00639
00640
if (
NT_SUCCESS(
Status )) {
00641
00642
if (NewAcl !=
NULL) {
00643
00644
00645
00646
00647
00648
00649
00650
Status =
RtlCreateSecurityDescriptor ( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
00651
ASSERT(
NT_SUCCESS(
Status ));
00652
00653
Status =
RtlSetDaclSecurityDescriptor (
00654 &SecurityDescriptor,
00655
TRUE,
00656 NewAcl,
00657
FALSE
00658 );
00659
00660
ASSERT(
NT_SUCCESS(
Status ));
00661 }
00662
00663 InitializeObjectAttributes(
00664 &
ObjectAttributes,
00665
NULL,
00666 0
L,
00667
NULL,
00668 NewAcl ==
NULL ?
NULL : &SecurityDescriptor
00669 );
00670
00671
00672
00673
00674
00675
Status =
SepDuplicateToken(
00676 (
PTOKEN)
Token,
00677 &
ObjectAttributes,
00678 EffectiveOnly,
00679 TokenImpersonation,
00680 ImpersonationLevel,
00681
KernelMode,
00682 &NewToken
00683 );
00684
00685
if (
NT_SUCCESS(
Status )) {
00686
00687
00688
00689
00690
00691
ObReferenceObject(NewToken);
00692
00693
00694
00695
00696
00697
Status =
ObInsertObject( NewToken,
00698
NULL,
00699 DesiredAccess,
00700 0,
00701 (PVOID *)
NULL,
00702 &LocalHandle
00703 );
00704 }
00705 }
00706 }
00707
00708
00709 }
else {
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
Status =
ObOpenObjectByPointer(
00728 (PVOID)
Token,
00729 0,
00730
NULL,
00731 DesiredAccess,
00732
SepTokenObjectType,
00733 PreviousMode,
00734 &LocalHandle
00735 );
00736 }
00737
00738
if (NewAcl !=
NULL) {
00739
ExFreePool( NewAcl );
00740 }
00741
00742
if (RestoreImpersonationState) {
00743
PsRestoreImpersonation(
00744
PsGetCurrentThread(),
00745 &DisabledImpersonationState
00746 );
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
ObDereferenceObject(
Token );
00757
00758
if (
NT_SUCCESS(
Status ) && CopyOnOpen) {
00759
00760
00761
00762
00763
00764
PsImpersonateClient( Thread,
00765 NewToken,
00766
FALSE,
00767 EffectiveOnly,
00768 ImpersonationLevel
00769 );
00770
00771 }
00772
00773
00774
00775
00776
00777
if (NewToken !=
NULL) {
00778
ObDereferenceObject( NewToken );
00779 }
00780
00781
if (CopyOnOpen && (Thread !=
NULL)) {
00782
00783
ObDereferenceObject( Thread );
00784 }
00785
00786
if (OriginalThread !=
NULL) {
00787
ObDereferenceObject(OriginalThread);
00788 }
00789
00790
00791
00792
00793
00794
if (
NT_SUCCESS(
Status)) {
00795
try { *TokenHandle = LocalHandle; }
00796 except(
EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode(); }
00797 }
00798
00799
return Status;
00800
00801 }
00802