00468 :
00469
00470 Open a token object associated with a thread and
return a handle that
00471 may be used to access that token.
00472
00473 Arguments:
00474
00475
ThreadHandle - Specifies
the thread whose token
is to be opened.
00476
00477 DesiredAccess - Is an access mask indicating which access types
00478 are desired to
the token. These access types are reconciled
00479 with
the Discretionary Access Control list of
the token to
00480 determine whether
the accesses will be granted or denied.
00481
00482 OpenAsSelf - Is a
boolean value indicating whether
the access should
00483 be
made using the calling thread's current security context, which
00484 may be that of a client
if impersonating, or
using the caller's
00485 process-level security context.
A value of
FALSE indicates
the
00486 caller's current context should be used un-modified.
A value of
00487
TRUE indicates
the request should be fulfilled
using the process
00488 level security context.
00489
00490 This parameter
is necessary to allow a server process to open
00491 a client's token when
the client specified IDENTIFICATION level
00492 impersonation. In
this case,
the caller would not be able to
00493 open
the client's token
using the client's context (because you
00494 can't create executive level objects
using IDENTIFICATION level
00495 impersonation).
00496
00497 TokenHandle - Receives
the handle of
the newly opened token.
00498
00499 Return Value:
00500
00501 STATUS_SUCCESS - Indicates
the operation was successful.
00502
00503 STATUS_NO_TOKEN - Indicates an attempt has been
made to open a
00504 token associated with a thread that
is not currently
00505 impersonating a client.
00506
00507 STATUS_CANT_OPEN_ANONYMOUS - Indicates
the client requested anonymous
00508 impersonation level. An anonymous token can not be openned.
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 0L,
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 }