3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/se/token.c
6 * PURPOSE: Security manager
8 * PROGRAMMERS: David Welch <welch@cwcom.net>
11 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
18 /* GLOBALS *******************************************************************/
20 POBJECT_TYPE SepTokenObjectType
= NULL
;
22 static GENERIC_MAPPING SepTokenMapping
= {TOKEN_READ
,
27 /* FUNCTIONS *****************************************************************/
29 VOID
SepFreeProxyData(PVOID ProxyData
)
34 NTSTATUS
SepCopyProxyData(PVOID
* Dest
, PVOID Src
)
37 return(STATUS_NOT_IMPLEMENTED
);
40 NTSTATUS
SeExchangePrimaryToken(PEPROCESS Process
,
41 PACCESS_TOKEN NewTokenP
,
42 PACCESS_TOKEN
* OldTokenP
)
45 PTOKEN NewToken
= (PTOKEN
)NewTokenP
;
49 if (NewToken
->TokenType
!= TokenPrimary
)
51 return(STATUS_UNSUCCESSFUL
);
53 if (NewToken
->TokenInUse
!= 0)
55 return(STATUS_UNSUCCESSFUL
);
57 OldToken
= Process
->Token
;
58 Process
->Token
= NewToken
;
59 NewToken
->TokenInUse
= 1;
60 ObReferenceObjectByPointer(NewToken
,
64 OldToken
->TokenInUse
= 0;
65 *OldTokenP
= (PACCESS_TOKEN
)OldToken
;
66 return(STATUS_SUCCESS
);
70 RtlLengthSidAndAttributes(ULONG Count
,
71 PSID_AND_ATTRIBUTES Src
)
78 uLength
= Count
* sizeof(SID_AND_ATTRIBUTES
);
79 for (i
= 0; i
< Count
; i
++)
80 uLength
+= RtlLengthSid(Src
[i
].Sid
);
87 SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token
,
93 Token
->PrimaryGroup
= 0;
97 Token
->DefaultOwnerIndex
= Token
->UserAndGroupCount
;
100 /* Validate and set the primary group and user pointers */
101 for (i
= 0; i
< Token
->UserAndGroupCount
; i
++)
104 RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, DefaultOwner
))
106 Token
->DefaultOwnerIndex
= i
;
109 if (RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, PrimaryGroup
))
111 Token
->PrimaryGroup
= Token
->UserAndGroups
[i
].Sid
;
115 if (Token
->DefaultOwnerIndex
== Token
->UserAndGroupCount
)
117 return(STATUS_INVALID_OWNER
);
120 if (Token
->PrimaryGroup
== 0)
122 return(STATUS_INVALID_PRIMARY_GROUP
);
125 return(STATUS_SUCCESS
);
130 SepDuplicateToken(PTOKEN Token
,
131 POBJECT_ATTRIBUTES ObjectAttributes
,
132 BOOLEAN EffectiveOnly
,
133 TOKEN_TYPE TokenType
,
134 SECURITY_IMPERSONATION_LEVEL Level
,
135 KPROCESSOR_MODE PreviousMode
,
136 PTOKEN
* NewAccessToken
)
144 Status
= ObCreateObject(PreviousMode
,
152 (PVOID
*)&AccessToken
);
153 if (!NT_SUCCESS(Status
))
155 DPRINT1("ObCreateObject() failed (Status %lx)\n");
159 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->TokenId
);
160 if (!NT_SUCCESS(Status
))
162 ObDereferenceObject(AccessToken
);
166 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
167 if (!NT_SUCCESS(Status
))
169 ObDereferenceObject(AccessToken
);
173 AccessToken
->TokenInUse
= 0;
174 AccessToken
->TokenType
= TokenType
;
175 AccessToken
->ImpersonationLevel
= Level
;
176 RtlCopyLuid(&AccessToken
->AuthenticationId
, &Token
->AuthenticationId
);
178 AccessToken
->TokenSource
.SourceIdentifier
.LowPart
= Token
->TokenSource
.SourceIdentifier
.LowPart
;
179 AccessToken
->TokenSource
.SourceIdentifier
.HighPart
= Token
->TokenSource
.SourceIdentifier
.HighPart
;
180 memcpy(AccessToken
->TokenSource
.SourceName
,
181 Token
->TokenSource
.SourceName
,
182 sizeof(Token
->TokenSource
.SourceName
));
183 AccessToken
->ExpirationTime
.QuadPart
= Token
->ExpirationTime
.QuadPart
;
184 AccessToken
->UserAndGroupCount
= Token
->UserAndGroupCount
;
185 AccessToken
->DefaultOwnerIndex
= Token
->DefaultOwnerIndex
;
187 uLength
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
188 for (i
= 0; i
< Token
->UserAndGroupCount
; i
++)
189 uLength
+= RtlLengthSid(Token
->UserAndGroups
[i
].Sid
);
191 AccessToken
->UserAndGroups
=
192 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
194 TAG('T', 'O', 'K', 'u'));
196 EndMem
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
198 Status
= RtlCopySidAndAttributesArray(AccessToken
->UserAndGroupCount
,
199 Token
->UserAndGroups
,
201 AccessToken
->UserAndGroups
,
205 if (NT_SUCCESS(Status
))
207 Status
= SepFindPrimaryGroupAndDefaultOwner(
213 if (NT_SUCCESS(Status
))
215 AccessToken
->PrivilegeCount
= Token
->PrivilegeCount
;
217 uLength
= AccessToken
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
218 AccessToken
->Privileges
=
219 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
221 TAG('T', 'O', 'K', 'p'));
223 for (i
= 0; i
< AccessToken
->PrivilegeCount
; i
++)
225 RtlCopyLuid(&AccessToken
->Privileges
[i
].Luid
,
226 &Token
->Privileges
[i
].Luid
);
227 AccessToken
->Privileges
[i
].Attributes
=
228 Token
->Privileges
[i
].Attributes
;
231 if ( Token
->DefaultDacl
)
233 AccessToken
->DefaultDacl
=
234 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
235 Token
->DefaultDacl
->AclSize
,
236 TAG('T', 'O', 'K', 'd'));
237 memcpy(AccessToken
->DefaultDacl
,
239 Token
->DefaultDacl
->AclSize
);
243 AccessToken
->DefaultDacl
= 0;
247 if ( NT_SUCCESS(Status
) )
249 *NewAccessToken
= AccessToken
;
250 return(STATUS_SUCCESS
);
253 ObDereferenceObject(AccessToken
);
259 SepInitializeNewProcess(struct _EPROCESS
* NewProcess
,
260 struct _EPROCESS
* ParentProcess
)
266 OBJECT_ATTRIBUTES ObjectAttributes
;
268 pParentToken
= (PACCESS_TOKEN
) ParentProcess
->Token
;
270 InitializeObjectAttributes(&ObjectAttributes
,
276 Status
= SepDuplicateToken(pParentToken
,
280 pParentToken
->ImpersonationLevel
,
283 if ( ! NT_SUCCESS(Status
) )
286 NewProcess
->Token
= pNewToken
;
287 return(STATUS_SUCCESS
);
296 PACCESS_STATE AccessState
,
297 PPRIVILEGE_SET Privileges
301 return STATUS_NOT_IMPLEMENTED
;
306 SeCopyClientToken(PACCESS_TOKEN Token
,
307 SECURITY_IMPERSONATION_LEVEL Level
,
308 KPROCESSOR_MODE PreviousMode
,
309 PACCESS_TOKEN
* NewToken
)
312 OBJECT_ATTRIBUTES ObjectAttributes
;
316 InitializeObjectAttributes(&ObjectAttributes
,
321 Status
= SepDuplicateToken(Token
,
337 SeCreateClientSecurity(IN
struct _ETHREAD
*Thread
,
338 IN PSECURITY_QUALITY_OF_SERVICE Qos
,
339 IN BOOLEAN RemoteClient
,
340 OUT PSECURITY_CLIENT_CONTEXT ClientContext
)
342 TOKEN_TYPE TokenType
;
344 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
347 PACCESS_TOKEN NewToken
;
351 Token
= PsReferenceEffectiveToken(Thread
,
354 &ImpersonationLevel
);
355 if (TokenType
!= TokenImpersonation
)
357 ClientContext
->DirectAccessEffectiveOnly
= Qos
->EffectiveOnly
;
361 if (Qos
->ImpersonationLevel
> ImpersonationLevel
)
365 ObDereferenceObject(Token
);
367 return(STATUS_UNSUCCESSFUL
);
369 if (ImpersonationLevel
== SecurityAnonymous
||
370 ImpersonationLevel
== SecurityIdentification
||
371 (RemoteClient
!= FALSE
&& ImpersonationLevel
!= SecurityDelegation
))
375 ObDereferenceObject(Token
);
377 return(STATUS_UNSUCCESSFUL
);
380 Qos
->EffectiveOnly
!= 0)
382 ClientContext
->DirectAccessEffectiveOnly
= TRUE
;
386 ClientContext
->DirectAccessEffectiveOnly
= FALSE
;
390 if (Qos
->ContextTrackingMode
== 0)
392 ClientContext
->DirectlyAccessClientToken
= FALSE
;
393 g
= SeCopyClientToken(Token
, ImpersonationLevel
, 0, &NewToken
);
396 // ObDeleteCapturedInsertInfo(NewToken);
398 if (TokenType
== TokenPrimary
|| Token
!= NULL
)
400 ObDereferenceObject(Token
);
409 ClientContext
->DirectlyAccessClientToken
= TRUE
;
410 if (RemoteClient
!= FALSE
)
412 // SeGetTokenControlInformation(Token, &ClientContext->Unknown11);
416 ClientContext
->SecurityQos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
417 ClientContext
->SecurityQos
.ImpersonationLevel
= Qos
->ImpersonationLevel
;
418 ClientContext
->SecurityQos
.ContextTrackingMode
= Qos
->ContextTrackingMode
;
419 ClientContext
->SecurityQos
.EffectiveOnly
= Qos
->EffectiveOnly
;
420 ClientContext
->ServerIsRemote
= RemoteClient
;
421 ClientContext
->ClientToken
= NewToken
;
423 return(STATUS_SUCCESS
);
431 SeCreateClientSecurityFromSubjectContext(
432 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
433 IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos
,
434 IN BOOLEAN ServerIsRemote
,
435 OUT PSECURITY_CLIENT_CONTEXT ClientContext
439 return STATUS_NOT_IMPLEMENTED
;
448 IN PACCESS_TOKEN ExistingToken
,
450 IN PTOKEN_GROUPS SidsToDisable OPTIONAL
,
451 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL
,
452 IN PTOKEN_GROUPS RestrictedSids OPTIONAL
,
453 OUT PACCESS_TOKEN
* FilteredToken
457 return STATUS_NOT_IMPLEMENTED
;
466 IN PPRIVILEGE_SET Privileges
478 SeImpersonateClientEx(
479 IN PSECURITY_CLIENT_CONTEXT ClientContext
,
480 IN PETHREAD ServerThread OPTIONAL
484 return STATUS_NOT_IMPLEMENTED
;
491 SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext
,
492 IN PETHREAD ServerThread OPTIONAL
)
498 if (ClientContext
->DirectlyAccessClientToken
== FALSE
)
500 b
= ClientContext
->SecurityQos
.EffectiveOnly
;
504 b
= ClientContext
->DirectAccessEffectiveOnly
;
506 if (ServerThread
== NULL
)
508 ServerThread
= PsGetCurrentThread();
510 PsImpersonateClient(ServerThread
,
511 ClientContext
->ClientToken
,
514 ClientContext
->SecurityQos
.ImpersonationLevel
);
519 SepDeleteToken(PVOID ObjectBody
)
521 PTOKEN AccessToken
= (PTOKEN
)ObjectBody
;
523 if (AccessToken
->UserAndGroups
)
524 ExFreePool(AccessToken
->UserAndGroups
);
526 if (AccessToken
->Privileges
)
527 ExFreePool(AccessToken
->Privileges
);
529 if (AccessToken
->DefaultDacl
)
530 ExFreePool(AccessToken
->DefaultDacl
);
535 SepInitializeTokenImplementation(VOID
)
537 SepTokenObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
539 SepTokenObjectType
->Tag
= TAG('T', 'O', 'K', 'T');
540 SepTokenObjectType
->PeakObjects
= 0;
541 SepTokenObjectType
->PeakHandles
= 0;
542 SepTokenObjectType
->TotalObjects
= 0;
543 SepTokenObjectType
->TotalHandles
= 0;
544 SepTokenObjectType
->PagedPoolCharge
= 0;
545 SepTokenObjectType
->NonpagedPoolCharge
= sizeof(TOKEN
);
546 SepTokenObjectType
->Mapping
= &SepTokenMapping
;
547 SepTokenObjectType
->Dump
= NULL
;
548 SepTokenObjectType
->Open
= NULL
;
549 SepTokenObjectType
->Close
= NULL
;
550 SepTokenObjectType
->Delete
= SepDeleteToken
;
551 SepTokenObjectType
->Parse
= NULL
;
552 SepTokenObjectType
->Security
= NULL
;
553 SepTokenObjectType
->QueryName
= NULL
;
554 SepTokenObjectType
->OkayToClose
= NULL
;
555 SepTokenObjectType
->Create
= NULL
;
556 SepTokenObjectType
->DuplicationNotify
= NULL
;
558 RtlpCreateUnicodeString(&SepTokenObjectType
->TypeName
,
559 L
"Token", NonPagedPool
);
560 ObpCreateTypeObject (SepTokenObjectType
);
568 NtQueryInformationToken(IN HANDLE TokenHandle
,
569 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
570 OUT PVOID TokenInformation
,
571 IN ULONG TokenInformationLength
,
572 OUT PULONG ReturnLength
)
574 NTSTATUS Status
, LengthStatus
;
579 PTOKEN_GROUPS PtrTokenGroups
;
580 PTOKEN_DEFAULT_DACL PtrDefaultDacl
;
581 PTOKEN_STATISTICS PtrTokenStatistics
;
585 Status
= ObReferenceObjectByHandle(TokenHandle
,
586 (TokenInformationClass
== TokenSource
) ? TOKEN_QUERY_SOURCE
: TOKEN_QUERY
,
591 if (!NT_SUCCESS(Status
))
596 switch (TokenInformationClass
)
599 DPRINT("NtQueryInformationToken(TokenUser)\n");
600 Length
= RtlLengthSidAndAttributes(1, Token
->UserAndGroups
);
601 if (TokenInformationLength
< Length
)
603 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
604 if (NT_SUCCESS(Status
))
605 Status
= STATUS_BUFFER_TOO_SMALL
;
609 Status
= RtlCopySidAndAttributesArray(1,
610 Token
->UserAndGroups
,
611 TokenInformationLength
,
613 (char*)TokenInformation
+ 8,
616 if (NT_SUCCESS(Status
))
618 Length
= TokenInformationLength
- Length
;
619 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
625 DPRINT("NtQueryInformationToken(TokenGroups)\n");
626 Length
= RtlLengthSidAndAttributes(Token
->UserAndGroupCount
- 1, &Token
->UserAndGroups
[1]) + sizeof(ULONG
);
627 if (TokenInformationLength
< Length
)
629 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
630 if (NT_SUCCESS(Status
))
631 Status
= STATUS_BUFFER_TOO_SMALL
;
635 EndMem
= (char*)TokenInformation
+ Token
->UserAndGroupCount
* sizeof(SID_AND_ATTRIBUTES
);
636 PtrTokenGroups
= (PTOKEN_GROUPS
)TokenInformation
;
637 PtrTokenGroups
->GroupCount
= Token
->UserAndGroupCount
- 1;
638 Status
= RtlCopySidAndAttributesArray(Token
->UserAndGroupCount
- 1,
639 &Token
->UserAndGroups
[1],
640 TokenInformationLength
,
641 PtrTokenGroups
->Groups
,
645 if (NT_SUCCESS(Status
))
647 Length
= TokenInformationLength
- Length
;
648 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
653 case TokenPrivileges
:
654 DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
655 Length
= sizeof(ULONG
) + Token
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
656 if (TokenInformationLength
< Length
)
658 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
659 if (NT_SUCCESS(Status
))
660 Status
= STATUS_BUFFER_TOO_SMALL
;
665 TOKEN_PRIVILEGES
* pPriv
= (TOKEN_PRIVILEGES
*)TokenInformation
;
667 pPriv
->PrivilegeCount
= Token
->PrivilegeCount
;
668 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
670 RtlCopyLuid(&pPriv
->Privileges
[i
].Luid
, &Token
->Privileges
[i
].Luid
);
671 pPriv
->Privileges
[i
].Attributes
= Token
->Privileges
[i
].Attributes
;
673 Status
= STATUS_SUCCESS
;
678 DPRINT("NtQueryInformationToken(TokenOwner)\n");
679 Length
= RtlLengthSid(Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
) + sizeof(TOKEN_OWNER
);
680 if (TokenInformationLength
< Length
)
682 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
683 if (NT_SUCCESS(Status
))
684 Status
= STATUS_BUFFER_TOO_SMALL
;
688 ((PTOKEN_OWNER
)TokenInformation
)->Owner
=
689 (PSID
)(((PTOKEN_OWNER
)TokenInformation
) + 1);
690 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
691 ((PTOKEN_OWNER
)TokenInformation
)->Owner
,
692 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
);
693 Status
= STATUS_SUCCESS
;
697 case TokenPrimaryGroup
:
698 DPRINT("NtQueryInformationToken(TokenPrimaryGroup),"
699 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
700 Length
= RtlLengthSid(Token
->PrimaryGroup
) + sizeof(TOKEN_PRIMARY_GROUP
);
701 if (TokenInformationLength
< Length
)
703 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
704 if (NT_SUCCESS(Status
))
705 Status
= STATUS_BUFFER_TOO_SMALL
;
709 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
=
710 (PSID
)(((PTOKEN_PRIMARY_GROUP
)TokenInformation
) + 1);
711 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
712 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
,
713 Token
->PrimaryGroup
);
714 Status
= STATUS_SUCCESS
;
718 case TokenDefaultDacl
:
719 DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
720 PtrDefaultDacl
= (PTOKEN_DEFAULT_DACL
) TokenInformation
;
721 Length
= (Token
->DefaultDacl
? Token
->DefaultDacl
->AclSize
: 0) + sizeof(TOKEN_DEFAULT_DACL
);
722 if (TokenInformationLength
< Length
)
724 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
725 if (NT_SUCCESS(Status
))
726 Status
= STATUS_BUFFER_TOO_SMALL
;
728 else if (!Token
->DefaultDacl
)
730 PtrDefaultDacl
->DefaultDacl
= 0;
731 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
735 PtrDefaultDacl
->DefaultDacl
= (PACL
) (PtrDefaultDacl
+ 1);
736 memmove(PtrDefaultDacl
->DefaultDacl
,
738 Token
->DefaultDacl
->AclSize
);
739 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
744 DPRINT("NtQueryInformationToken(TokenSource)\n");
745 if (TokenInformationLength
< sizeof(TOKEN_SOURCE
))
747 Length
= sizeof(TOKEN_SOURCE
);
748 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
749 if (NT_SUCCESS(Status
))
750 Status
= STATUS_BUFFER_TOO_SMALL
;
754 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenSource
, sizeof(TOKEN_SOURCE
));
759 DPRINT("NtQueryInformationToken(TokenType)\n");
760 if (TokenInformationLength
< sizeof(TOKEN_TYPE
))
762 Length
= sizeof(TOKEN_TYPE
);
763 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
764 if (NT_SUCCESS(Status
))
765 Status
= STATUS_BUFFER_TOO_SMALL
;
769 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenType
, sizeof(TOKEN_TYPE
));
773 case TokenImpersonationLevel
:
774 DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
775 if (TokenInformationLength
< sizeof(SECURITY_IMPERSONATION_LEVEL
))
777 Length
= sizeof(SECURITY_IMPERSONATION_LEVEL
);
778 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
779 if (NT_SUCCESS(Status
))
780 Status
= STATUS_BUFFER_TOO_SMALL
;
784 Status
= MmCopyToCaller(TokenInformation
, &Token
->ImpersonationLevel
, sizeof(SECURITY_IMPERSONATION_LEVEL
));
788 case TokenStatistics
:
789 DPRINT("NtQueryInformationToken(TokenStatistics)\n");
790 if (TokenInformationLength
< sizeof(TOKEN_STATISTICS
))
792 Length
= sizeof(TOKEN_STATISTICS
);
793 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
794 if (NT_SUCCESS(Status
))
795 Status
= STATUS_BUFFER_TOO_SMALL
;
799 PtrTokenStatistics
= (PTOKEN_STATISTICS
)TokenInformation
;
800 PtrTokenStatistics
->TokenId
= Token
->TokenId
;
801 PtrTokenStatistics
->AuthenticationId
= Token
->AuthenticationId
;
802 PtrTokenStatistics
->ExpirationTime
= Token
->ExpirationTime
;
803 PtrTokenStatistics
->TokenType
= Token
->TokenType
;
804 PtrTokenStatistics
->ImpersonationLevel
= Token
->ImpersonationLevel
;
805 PtrTokenStatistics
->DynamicCharged
= Token
->DynamicCharged
;
806 PtrTokenStatistics
->DynamicAvailable
= Token
->DynamicAvailable
;
807 PtrTokenStatistics
->GroupCount
= Token
->UserAndGroupCount
- 1;
808 PtrTokenStatistics
->PrivilegeCount
= Token
->PrivilegeCount
;
809 PtrTokenStatistics
->ModifiedId
= Token
->ModifiedId
;
811 Status
= STATUS_SUCCESS
;
816 DPRINT("NtQueryInformationToken(TokenOrigin)\n");
817 if (TokenInformationLength
< sizeof(TOKEN_ORIGIN
))
819 Status
= STATUS_BUFFER_TOO_SMALL
;
823 Status
= MmCopyToCaller(&((PTOKEN_ORIGIN
)TokenInformation
)->OriginatingLogonSession
,
824 &Token
->AuthenticationId
, sizeof(LUID
));
826 Length
= sizeof(TOKEN_ORIGIN
);
827 LengthStatus
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
828 if (NT_SUCCESS(Status
))
830 Status
= LengthStatus
;
834 case TokenGroupsAndPrivileges
:
835 DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
836 Status
= STATUS_NOT_IMPLEMENTED
;
839 case TokenRestrictedSids
:
840 DPRINT1("NtQueryInformationToken(TokenRestrictedSids) not implemented\n");
841 Status
= STATUS_NOT_IMPLEMENTED
;
844 case TokenSandBoxInert
:
845 DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n");
846 Status
= STATUS_NOT_IMPLEMENTED
;
850 DPRINT("NtQueryInformationToken(TokenSessionId)\n");
851 if (TokenInformationLength
< sizeof(ULONG
))
853 Length
= sizeof(ULONG
);
854 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
855 if (NT_SUCCESS(Status
))
856 Status
= STATUS_BUFFER_TOO_SMALL
;
860 Status
= MmCopyToCaller(TokenInformation
, &Token
->SessionId
, sizeof(ULONG
));
865 DPRINT1("NtQueryInformationToken(%d) invalid parameter\n");
866 Status
= STATUS_INVALID_PARAMETER
;
870 ObDereferenceObject(Token
);
880 SeQueryInformationToken(
881 IN PACCESS_TOKEN Token
,
882 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
883 OUT PVOID
*TokenInformation
887 return STATUS_NOT_IMPLEMENTED
;
895 SeQuerySessionIdToken(
896 IN PACCESS_TOKEN Token
,
901 return STATUS_NOT_IMPLEMENTED
;
905 * NtSetTokenInformation: Partly implemented.
907 * TokenOrigin, TokenDefaultDacl, TokenSessionId
911 NtSetInformationToken(IN HANDLE TokenHandle
,
912 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
913 OUT PVOID TokenInformation
,
914 IN ULONG TokenInformationLength
)
918 TOKEN_OWNER TokenOwnerSet
= { 0 };
919 TOKEN_PRIMARY_GROUP TokenPrimaryGroupSet
= { 0 };
920 DWORD NeededAccess
= 0;
924 switch (TokenInformationClass
)
927 case TokenPrimaryGroup
:
928 NeededAccess
= TOKEN_ADJUST_DEFAULT
;
931 case TokenDefaultDacl
:
932 if (TokenInformationLength
< sizeof(TOKEN_DEFAULT_DACL
))
933 return STATUS_BUFFER_TOO_SMALL
;
934 NeededAccess
= TOKEN_ADJUST_DEFAULT
;
938 DPRINT1("NtSetInformationToken: lying about success (stub) - %x\n", TokenInformationClass
);
939 return STATUS_SUCCESS
;
943 Status
= ObReferenceObjectByHandle(TokenHandle
,
949 if (!NT_SUCCESS(Status
))
954 switch (TokenInformationClass
)
957 MmCopyFromCaller( &TokenOwnerSet
, TokenInformation
,
958 min(sizeof(TokenOwnerSet
),TokenInformationLength
) );
959 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
960 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
,
961 TokenOwnerSet
.Owner
);
962 Status
= STATUS_SUCCESS
;
963 DPRINT("NtSetInformationToken(TokenOwner)\n");
966 case TokenPrimaryGroup
:
967 MmCopyFromCaller( &TokenPrimaryGroupSet
, TokenInformation
,
968 min(sizeof(TokenPrimaryGroupSet
),
969 TokenInformationLength
) );
970 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
972 TokenPrimaryGroupSet
.PrimaryGroup
);
973 Status
= STATUS_SUCCESS
;
974 DPRINT("NtSetInformationToken(TokenPrimaryGroup),"
975 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
978 case TokenDefaultDacl
:
980 TOKEN_DEFAULT_DACL TokenDefaultDacl
= { 0 };
984 Status
= MmCopyFromCaller( &TokenDefaultDacl
, TokenInformation
,
985 sizeof(TOKEN_DEFAULT_DACL
) );
986 if (!NT_SUCCESS(Status
))
988 Status
= STATUS_INVALID_PARAMETER
;
992 Status
= MmCopyFromCaller( &OldAcl
, TokenDefaultDacl
.DefaultDacl
,
994 if (!NT_SUCCESS(Status
))
996 Status
= STATUS_INVALID_PARAMETER
;
1000 NewAcl
= ExAllocatePool(NonPagedPool
, sizeof(ACL
));
1003 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1007 Status
= MmCopyFromCaller( NewAcl
, TokenDefaultDacl
.DefaultDacl
,
1009 if (!NT_SUCCESS(Status
))
1011 Status
= STATUS_INVALID_PARAMETER
;
1016 if (Token
->DefaultDacl
)
1018 ExFreePool(Token
->DefaultDacl
);
1021 Token
->DefaultDacl
= NewAcl
;
1023 Status
= STATUS_SUCCESS
;
1028 Status
= STATUS_NOT_IMPLEMENTED
;
1032 ObDereferenceObject(Token
);
1041 * NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
1042 * this is certainly NOT true, thou i can't say for sure that EffectiveOnly
1043 * is correct either. -Gunnar
1044 * This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
1047 NtDuplicateToken(IN HANDLE ExistingTokenHandle
,
1048 IN ACCESS_MASK DesiredAccess
,
1049 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
/*is it really optional?*/,
1050 IN BOOLEAN EffectiveOnly
,
1051 IN TOKEN_TYPE TokenType
,
1052 OUT PHANDLE NewTokenHandle
)
1054 KPROCESSOR_MODE PreviousMode
;
1058 NTSTATUS Status
= STATUS_SUCCESS
;
1062 PreviousMode
= KeGetPreviousMode();
1064 if(PreviousMode
!= KernelMode
)
1068 ProbeForWrite(NewTokenHandle
,
1074 Status
= _SEH_GetExceptionCode();
1078 if(!NT_SUCCESS(Status
))
1084 Status
= ObReferenceObjectByHandle(ExistingTokenHandle
,
1090 if (!NT_SUCCESS(Status
))
1092 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
1096 Status
= SepDuplicateToken(Token
,
1100 ObjectAttributes
->SecurityQualityOfService
?
1101 ((PSECURITY_QUALITY_OF_SERVICE
)(ObjectAttributes
->SecurityQualityOfService
))->ImpersonationLevel
:
1102 0 /*SecurityAnonymous*/,
1106 ObDereferenceObject(Token
);
1108 if (!NT_SUCCESS(Status
))
1110 DPRINT1("Failed to duplicate token (Status %lx)\n", Status
);
1114 Status
= ObInsertObject((PVOID
)NewToken
,
1121 ObDereferenceObject(NewToken
);
1123 if (NT_SUCCESS(Status
))
1127 *NewTokenHandle
= hToken
;
1131 Status
= _SEH_GetExceptionCode();
1140 VOID
SepAdjustGroups(PACCESS_TOKEN Token
,
1142 BOOLEAN ResetToDefault
,
1143 PSID_AND_ATTRIBUTES Groups
,
1145 KPROCESSOR_MODE PreviousMode
,
1156 NtAdjustGroupsToken(IN HANDLE TokenHandle
,
1157 IN BOOLEAN ResetToDefault
,
1158 IN PTOKEN_GROUPS NewState
,
1159 IN ULONG BufferLength
,
1160 OUT PTOKEN_GROUPS PreviousState OPTIONAL
,
1161 OUT PULONG ReturnLength
)
1165 PACCESS_TOKEN Token
;
1172 Status
= ObReferenceObjectByHandle(TokenHandle
,
1180 SepAdjustGroups(Token
,
1192 return(STATUS_NOT_IMPLEMENTED
);
1199 SepAdjustPrivileges(PACCESS_TOKEN Token
,
1201 KPROCESSOR_MODE PreviousMode
,
1202 ULONG PrivilegeCount
,
1203 PLUID_AND_ATTRIBUTES Privileges
,
1204 PTOKEN_PRIVILEGES
* PreviousState
,
1213 if (Token
->PrivilegeCount
> 0)
1215 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1217 if (PreviousMode
!= KernelMode
)
1219 if (Token
->Privileges
[i
]->Attributes
& SE_PRIVILEGE_ENABLED
== 0)
1223 if (PreviousState
!= NULL
)
1225 memcpy(&PreviousState
[i
],
1226 &Token
->Privileges
[i
],
1227 sizeof(LUID_AND_ATTRIBUTES
));
1229 Token
->Privileges
[i
].Attributes
&= (~SE_PRIVILEGE_ENABLED
);
1236 if (PreviousMode
!= KernelMode
)
1238 Token
->TokenFlags
= Token
->TokenFlags
& (~1);
1242 if (PrivilegeCount
<= ?)
1255 NtAdjustPrivilegesToken (IN HANDLE TokenHandle
,
1256 IN BOOLEAN DisableAllPrivileges
,
1257 IN PTOKEN_PRIVILEGES NewState
,
1258 IN ULONG BufferLength
,
1259 OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL
,
1260 OUT PULONG ReturnLength OPTIONAL
)
1262 // PLUID_AND_ATTRIBUTES Privileges;
1263 KPROCESSOR_MODE PreviousMode
;
1264 // ULONG PrivilegeCount;
1280 DPRINT ("NtAdjustPrivilegesToken() called\n");
1282 // PrivilegeCount = NewState->PrivilegeCount;
1283 PreviousMode
= KeGetPreviousMode ();
1284 // SeCaptureLuidAndAttributesArray(NewState->Privileges,
1294 Status
= ObReferenceObjectByHandle (TokenHandle
,
1295 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1300 if (!NT_SUCCESS(Status
))
1302 DPRINT1 ("Failed to reference token (Status %lx)\n", Status
);
1303 // SeReleaseLuidAndAttributesArray(Privileges,
1311 SepAdjustPrivileges(Token
,
1323 if (DisableAllPrivileges
== TRUE
)
1325 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1327 if (Token
->Privileges
[i
].Attributes
!= 0)
1329 DPRINT ("Attributes differ\n");
1331 /* Save current privilege */
1332 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1334 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1335 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1339 /* Update current privlege */
1340 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1343 Status
= STATUS_SUCCESS
;
1348 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1350 for (j
= 0; j
< NewState
->PrivilegeCount
; j
++)
1352 if (Token
->Privileges
[i
].Luid
.LowPart
== NewState
->Privileges
[j
].Luid
.LowPart
&&
1353 Token
->Privileges
[i
].Luid
.HighPart
== NewState
->Privileges
[j
].Luid
.HighPart
)
1355 DPRINT ("Found privilege\n");
1357 if ((Token
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
) !=
1358 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
))
1360 DPRINT ("Attributes differ\n");
1361 DPRINT ("Current attributes %lx desired attributes %lx\n",
1362 Token
->Privileges
[i
].Attributes
,
1363 NewState
->Privileges
[j
].Attributes
);
1365 /* Save current privilege */
1366 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1368 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1369 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1373 /* Update current privlege */
1374 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1375 Token
->Privileges
[i
].Attributes
|=
1376 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
);
1377 DPRINT ("New attributes %lx\n",
1378 Token
->Privileges
[i
].Attributes
);
1384 Status
= Count
< NewState
->PrivilegeCount
? STATUS_NOT_ALL_ASSIGNED
: STATUS_SUCCESS
;
1387 if (ReturnLength
!= NULL
)
1389 *ReturnLength
= sizeof(TOKEN_PRIVILEGES
) +
1390 (sizeof(LUID_AND_ATTRIBUTES
) * (k
- 1));
1393 ObDereferenceObject (Token
);
1395 // SeReleaseLuidAndAttributesArray(Privileges,
1399 DPRINT ("NtAdjustPrivilegesToken() done\n");
1406 SepCreateSystemProcessToken(struct _EPROCESS
* Process
)
1412 ULONG uLocalSystemLength
= RtlLengthSid(SeLocalSystemSid
);
1413 ULONG uWorldLength
= RtlLengthSid(SeWorldSid
);
1414 ULONG uAuthUserLength
= RtlLengthSid(SeAuthenticatedUserSid
);
1415 ULONG uAdminsLength
= RtlLengthSid(SeAliasAdminsSid
);
1422 * Initialize the token
1424 Status
= ObCreateObject(KernelMode
,
1432 (PVOID
*)&AccessToken
);
1433 if (!NT_SUCCESS(Status
))
1438 Status
= ExpAllocateLocallyUniqueId(&AccessToken
->TokenId
);
1439 if (!NT_SUCCESS(Status
))
1441 ObDereferenceObject(AccessToken
);
1445 Status
= ExpAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
1446 if (!NT_SUCCESS(Status
))
1448 ObDereferenceObject(AccessToken
);
1452 Status
= ExpAllocateLocallyUniqueId(&AccessToken
->AuthenticationId
);
1453 if (!NT_SUCCESS(Status
))
1455 ObDereferenceObject(AccessToken
);
1459 AccessToken
->TokenType
= TokenPrimary
;
1460 AccessToken
->ImpersonationLevel
= SecurityDelegation
;
1461 AccessToken
->TokenSource
.SourceIdentifier
.LowPart
= 0;
1462 AccessToken
->TokenSource
.SourceIdentifier
.HighPart
= 0;
1463 memcpy(AccessToken
->TokenSource
.SourceName
, "SeMgr\0\0\0", 8);
1464 AccessToken
->ExpirationTime
.QuadPart
= -1;
1465 AccessToken
->UserAndGroupCount
= 4;
1467 uSize
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1468 uSize
+= uLocalSystemLength
;
1469 uSize
+= uWorldLength
;
1470 uSize
+= uAuthUserLength
;
1471 uSize
+= uAdminsLength
;
1473 AccessToken
->UserAndGroups
=
1474 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1476 TAG('T', 'O', 'K', 'u'));
1477 SidArea
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1480 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1481 AccessToken
->UserAndGroups
[i
++].Attributes
= 0;
1482 RtlCopySid(uLocalSystemLength
, SidArea
, SeLocalSystemSid
);
1483 SidArea
= (char*)SidArea
+ uLocalSystemLength
;
1485 AccessToken
->DefaultOwnerIndex
= i
;
1486 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1487 AccessToken
->PrimaryGroup
= (PSID
) SidArea
;
1488 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
;
1489 Status
= RtlCopySid(uAdminsLength
, SidArea
, SeAliasAdminsSid
);
1490 SidArea
= (char*)SidArea
+ uAdminsLength
;
1492 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1493 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1494 RtlCopySid(uWorldLength
, SidArea
, SeWorldSid
);
1495 SidArea
= (char*)SidArea
+ uWorldLength
;
1497 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1498 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1499 RtlCopySid(uAuthUserLength
, SidArea
, SeAuthenticatedUserSid
);
1500 SidArea
= (char*)SidArea
+ uAuthUserLength
;
1502 AccessToken
->PrivilegeCount
= 20;
1504 uSize
= AccessToken
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1505 AccessToken
->Privileges
=
1506 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1508 TAG('T', 'O', 'K', 'p'));
1511 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1512 AccessToken
->Privileges
[i
++].Luid
= SeTcbPrivilege
;
1514 AccessToken
->Privileges
[i
].Attributes
= 0;
1515 AccessToken
->Privileges
[i
++].Luid
= SeCreateTokenPrivilege
;
1517 AccessToken
->Privileges
[i
].Attributes
= 0;
1518 AccessToken
->Privileges
[i
++].Luid
= SeTakeOwnershipPrivilege
;
1520 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1521 AccessToken
->Privileges
[i
++].Luid
= SeCreatePagefilePrivilege
;
1523 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1524 AccessToken
->Privileges
[i
++].Luid
= SeLockMemoryPrivilege
;
1526 AccessToken
->Privileges
[i
].Attributes
= 0;
1527 AccessToken
->Privileges
[i
++].Luid
= SeAssignPrimaryTokenPrivilege
;
1529 AccessToken
->Privileges
[i
].Attributes
= 0;
1530 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseQuotaPrivilege
;
1532 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1533 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseBasePriorityPrivilege
;
1535 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1536 AccessToken
->Privileges
[i
++].Luid
= SeCreatePermanentPrivilege
;
1538 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1539 AccessToken
->Privileges
[i
++].Luid
= SeDebugPrivilege
;
1541 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1542 AccessToken
->Privileges
[i
++].Luid
= SeAuditPrivilege
;
1544 AccessToken
->Privileges
[i
].Attributes
= 0;
1545 AccessToken
->Privileges
[i
++].Luid
= SeSecurityPrivilege
;
1547 AccessToken
->Privileges
[i
].Attributes
= 0;
1548 AccessToken
->Privileges
[i
++].Luid
= SeSystemEnvironmentPrivilege
;
1550 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1551 AccessToken
->Privileges
[i
++].Luid
= SeChangeNotifyPrivilege
;
1553 AccessToken
->Privileges
[i
].Attributes
= 0;
1554 AccessToken
->Privileges
[i
++].Luid
= SeBackupPrivilege
;
1556 AccessToken
->Privileges
[i
].Attributes
= 0;
1557 AccessToken
->Privileges
[i
++].Luid
= SeRestorePrivilege
;
1559 AccessToken
->Privileges
[i
].Attributes
= 0;
1560 AccessToken
->Privileges
[i
++].Luid
= SeShutdownPrivilege
;
1562 AccessToken
->Privileges
[i
].Attributes
= 0;
1563 AccessToken
->Privileges
[i
++].Luid
= SeLoadDriverPrivilege
;
1565 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1566 AccessToken
->Privileges
[i
++].Luid
= SeProfileSingleProcessPrivilege
;
1568 AccessToken
->Privileges
[i
].Attributes
= 0;
1569 AccessToken
->Privileges
[i
++].Luid
= SeSystemtimePrivilege
;
1571 AccessToken
->Privileges
[i
].Attributes
= 0;
1572 AccessToken
->Privileges
[i
++].Luid
= SeUndockPrivilege
;
1574 AccessToken
->Privileges
[i
].Attributes
= 0;
1575 AccessToken
->Privileges
[i
++].Luid
= SeManageVolumePrivilege
;
1580 uSize
= sizeof(ACL
);
1581 uSize
+= sizeof(ACE
) + uLocalSystemLength
;
1582 uSize
+= sizeof(ACE
) + uAdminsLength
;
1583 uSize
= (uSize
& (~3)) + 8;
1584 AccessToken
->DefaultDacl
=
1585 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1587 TAG('T', 'O', 'K', 'd'));
1588 Status
= RtlCreateAcl(AccessToken
->DefaultDacl
, uSize
, ACL_REVISION
);
1589 if ( NT_SUCCESS(Status
) )
1591 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_ALL
, SeLocalSystemSid
);
1594 if ( NT_SUCCESS(Status
) )
1596 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_READ
|GENERIC_EXECUTE
|READ_CONTROL
, SeAliasAdminsSid
);
1599 if ( ! NT_SUCCESS(Status
) )
1601 ObDereferenceObject(AccessToken
);
1605 Process
->Token
= AccessToken
;
1606 return(STATUS_SUCCESS
);
1611 NtCreateToken(OUT PHANDLE TokenHandle
,
1612 IN ACCESS_MASK DesiredAccess
,
1613 IN POBJECT_ATTRIBUTES ObjectAttributes
,
1614 IN TOKEN_TYPE TokenType
,
1615 IN PLUID AuthenticationId
,
1616 IN PLARGE_INTEGER ExpirationTime
,
1617 IN PTOKEN_USER TokenUser
,
1618 IN PTOKEN_GROUPS TokenGroups
,
1619 IN PTOKEN_PRIVILEGES TokenPrivileges
,
1620 IN PTOKEN_OWNER TokenOwner
,
1621 IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup
,
1622 IN PTOKEN_DEFAULT_DACL TokenDefaultDacl
,
1623 IN PTOKEN_SOURCE TokenSource
)
1632 KPROCESSOR_MODE PreviousMode
;
1633 NTSTATUS Status
= STATUS_SUCCESS
;
1637 PreviousMode
= ExGetPreviousMode();
1639 if(PreviousMode
!= KernelMode
)
1643 ProbeForWrite(TokenHandle
,
1646 ProbeForRead(AuthenticationId
,
1649 ProbeForRead(ExpirationTime
,
1650 sizeof(LARGE_INTEGER
),
1652 ProbeForRead(TokenUser
,
1655 ProbeForRead(TokenGroups
,
1656 sizeof(TOKEN_GROUPS
),
1658 ProbeForRead(TokenPrivileges
,
1659 sizeof(TOKEN_PRIVILEGES
),
1661 ProbeForRead(TokenOwner
,
1662 sizeof(TOKEN_OWNER
),
1664 ProbeForRead(TokenPrimaryGroup
,
1665 sizeof(TOKEN_PRIMARY_GROUP
),
1667 ProbeForRead(TokenDefaultDacl
,
1668 sizeof(TOKEN_DEFAULT_DACL
),
1670 ProbeForRead(TokenSource
,
1671 sizeof(TOKEN_SOURCE
),
1676 Status
= _SEH_GetExceptionCode();
1680 if(!NT_SUCCESS(Status
))
1686 Status
= ZwAllocateLocallyUniqueId(&TokenId
);
1687 if (!NT_SUCCESS(Status
))
1690 Status
= ZwAllocateLocallyUniqueId(&ModifiedId
);
1691 if (!NT_SUCCESS(Status
))
1694 Status
= ObCreateObject(PreviousMode
,
1702 (PVOID
*)&AccessToken
);
1703 if (!NT_SUCCESS(Status
))
1705 DPRINT1("ObCreateObject() failed (Status %lx)\n");
1709 RtlCopyLuid(&AccessToken
->TokenSource
.SourceIdentifier
,
1710 &TokenSource
->SourceIdentifier
);
1711 memcpy(AccessToken
->TokenSource
.SourceName
,
1712 TokenSource
->SourceName
,
1713 sizeof(TokenSource
->SourceName
));
1715 RtlCopyLuid(&AccessToken
->TokenId
, &TokenId
);
1716 RtlCopyLuid(&AccessToken
->AuthenticationId
, AuthenticationId
);
1717 AccessToken
->ExpirationTime
= *ExpirationTime
;
1718 RtlCopyLuid(&AccessToken
->ModifiedId
, &ModifiedId
);
1720 AccessToken
->UserAndGroupCount
= TokenGroups
->GroupCount
+ 1;
1721 AccessToken
->PrivilegeCount
= TokenPrivileges
->PrivilegeCount
;
1722 AccessToken
->UserAndGroups
= 0;
1723 AccessToken
->Privileges
= 0;
1725 AccessToken
->TokenType
= TokenType
;
1726 AccessToken
->ImpersonationLevel
= ((PSECURITY_QUALITY_OF_SERVICE
)
1727 (ObjectAttributes
->SecurityQualityOfService
))->ImpersonationLevel
;
1730 * Normally we would just point these members into the variable information
1731 * area; however, our ObCreateObject() call can't allocate a variable information
1732 * area, so we allocate them seperately and provide a destroy function.
1735 uLength
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1736 uLength
+= RtlLengthSid(TokenUser
->User
.Sid
);
1737 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
1738 uLength
+= RtlLengthSid(TokenGroups
->Groups
[i
].Sid
);
1740 AccessToken
->UserAndGroups
=
1741 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1743 TAG('T', 'O', 'K', 'u'));
1745 EndMem
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1747 Status
= RtlCopySidAndAttributesArray(1,
1750 AccessToken
->UserAndGroups
,
1754 if (NT_SUCCESS(Status
))
1756 Status
= RtlCopySidAndAttributesArray(TokenGroups
->GroupCount
,
1757 TokenGroups
->Groups
,
1759 &AccessToken
->UserAndGroups
[1],
1765 if (NT_SUCCESS(Status
))
1767 Status
= SepFindPrimaryGroupAndDefaultOwner(
1769 TokenPrimaryGroup
->PrimaryGroup
,
1773 if (NT_SUCCESS(Status
))
1775 uLength
= TokenPrivileges
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1776 AccessToken
->Privileges
=
1777 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1779 TAG('T', 'O', 'K', 'p'));
1781 for (i
= 0; i
< TokenPrivileges
->PrivilegeCount
; i
++)
1783 Status
= MmCopyFromCaller(&AccessToken
->Privileges
[i
],
1784 &TokenPrivileges
->Privileges
[i
],
1785 sizeof(LUID_AND_ATTRIBUTES
));
1786 if (!NT_SUCCESS(Status
))
1791 if (NT_SUCCESS(Status
))
1793 AccessToken
->DefaultDacl
=
1794 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1795 TokenDefaultDacl
->DefaultDacl
->AclSize
,
1796 TAG('T', 'O', 'K', 'd'));
1797 memcpy(AccessToken
->DefaultDacl
,
1798 TokenDefaultDacl
->DefaultDacl
,
1799 TokenDefaultDacl
->DefaultDacl
->AclSize
);
1802 Status
= ObInsertObject ((PVOID
)AccessToken
,
1808 if (!NT_SUCCESS(Status
))
1810 DPRINT1("ObInsertObject() failed (Status %lx)\n", Status
);
1813 ObDereferenceObject(AccessToken
);
1815 if (NT_SUCCESS(Status
))
1819 *TokenHandle
= hToken
;
1823 Status
= _SEH_GetExceptionCode();
1836 SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token
,
1841 *LogonId
= ((PTOKEN
)Token
)->AuthenticationId
;
1843 return STATUS_SUCCESS
;
1850 SECURITY_IMPERSONATION_LEVEL
1852 SeTokenImpersonationLevel(IN PACCESS_TOKEN Token
)
1856 return ((PTOKEN
)Token
)->ImpersonationLevel
;
1864 SeTokenType(IN PACCESS_TOKEN Token
)
1868 return ((PTOKEN
)Token
)->TokenType
;
1878 IN PACCESS_TOKEN Token
1890 SeTokenIsRestricted(
1891 IN PACCESS_TOKEN Token
1903 SeTokenIsWriteRestricted(
1904 IN PACCESS_TOKEN Token
1917 NtOpenThreadTokenEx(IN HANDLE ThreadHandle
,
1918 IN ACCESS_MASK DesiredAccess
,
1919 IN BOOLEAN OpenAsSelf
,
1920 IN ULONG HandleAttributes
,
1921 OUT PHANDLE TokenHandle
)
1925 PTOKEN Token
, NewToken
, PrimaryToken
;
1926 BOOLEAN CopyOnOpen
, EffectiveOnly
;
1927 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
1928 SE_IMPERSONATION_STATE ImpersonationState
;
1929 OBJECT_ATTRIBUTES ObjectAttributes
;
1930 SECURITY_DESCRIPTOR SecurityDescriptor
;
1932 KPROCESSOR_MODE PreviousMode
;
1933 NTSTATUS Status
= STATUS_SUCCESS
;
1937 PreviousMode
= ExGetPreviousMode();
1939 if(PreviousMode
!= KernelMode
)
1943 ProbeForWrite(TokenHandle
,
1949 Status
= _SEH_GetExceptionCode();
1953 if(!NT_SUCCESS(Status
))
1960 * At first open the thread token for information access and verify
1961 * that the token associated with thread is valid.
1964 Status
= ObReferenceObjectByHandle(ThreadHandle
, THREAD_QUERY_INFORMATION
,
1965 PsThreadType
, PreviousMode
, (PVOID
*)&Thread
,
1967 if (!NT_SUCCESS(Status
))
1972 Token
= PsReferenceImpersonationToken(Thread
, &CopyOnOpen
, &EffectiveOnly
,
1973 &ImpersonationLevel
);
1976 ObfDereferenceObject(Thread
);
1977 return STATUS_NO_TOKEN
;
1980 ObDereferenceObject(Thread
);
1982 if (ImpersonationLevel
== SecurityAnonymous
)
1984 ObfDereferenceObject(Token
);
1985 return STATUS_CANT_OPEN_ANONYMOUS
;
1989 * Revert to self if OpenAsSelf is specified.
1994 PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1999 Status
= ObReferenceObjectByHandle(ThreadHandle
, THREAD_ALL_ACCESS
,
2000 PsThreadType
, PreviousMode
,
2001 (PVOID
*)&Thread
, NULL
);
2002 if (!NT_SUCCESS(Status
))
2004 ObfDereferenceObject(Token
);
2007 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
2012 PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
2013 Status
= SepCreateImpersonationTokenDacl(Token
, PrimaryToken
, &Dacl
);
2014 ObfDereferenceObject(PrimaryToken
);
2015 ObfDereferenceObject(Thread
);
2016 if (!NT_SUCCESS(Status
))
2018 ObfDereferenceObject(Token
);
2021 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
2026 RtlCreateSecurityDescriptor(&SecurityDescriptor
,
2027 SECURITY_DESCRIPTOR_REVISION
);
2028 RtlSetDaclSecurityDescriptor(&SecurityDescriptor
, TRUE
, Dacl
,
2031 InitializeObjectAttributes(&ObjectAttributes
, NULL
, HandleAttributes
,
2032 NULL
, &SecurityDescriptor
);
2034 Status
= SepDuplicateToken(Token
, &ObjectAttributes
, EffectiveOnly
,
2035 TokenImpersonation
, ImpersonationLevel
,
2036 KernelMode
, &NewToken
);
2038 if (!NT_SUCCESS(Status
))
2040 ObfDereferenceObject(Token
);
2043 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
2048 Status
= ObInsertObject(NewToken
, NULL
, DesiredAccess
, 0, NULL
,
2051 ObfDereferenceObject(NewToken
);
2055 Status
= ObOpenObjectByPointer(Token
, HandleAttributes
,
2056 NULL
, DesiredAccess
, SepTokenObjectType
,
2057 PreviousMode
, &hToken
);
2060 ObfDereferenceObject(Token
);
2064 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
2067 if(NT_SUCCESS(Status
))
2071 *TokenHandle
= hToken
;
2075 Status
= _SEH_GetExceptionCode();
2087 NtOpenThreadToken(IN HANDLE ThreadHandle
,
2088 IN ACCESS_MASK DesiredAccess
,
2089 IN BOOLEAN OpenAsSelf
,
2090 OUT PHANDLE TokenHandle
)
2092 return NtOpenThreadTokenEx(ThreadHandle
, DesiredAccess
, OpenAsSelf
, 0,