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
;
47 if (NewToken
->TokenType
!= TokenPrimary
)
49 return(STATUS_UNSUCCESSFUL
);
51 if (NewToken
->TokenInUse
!= 0)
53 return(STATUS_UNSUCCESSFUL
);
55 OldToken
= Process
->Token
;
56 Process
->Token
= NewToken
;
57 NewToken
->TokenInUse
= 1;
58 ObReferenceObjectByPointer(NewToken
,
62 OldToken
->TokenInUse
= 0;
63 *OldTokenP
= (PACCESS_TOKEN
)OldToken
;
64 return(STATUS_SUCCESS
);
68 RtlLengthSidAndAttributes(ULONG Count
,
69 PSID_AND_ATTRIBUTES Src
)
74 uLength
= Count
* sizeof(SID_AND_ATTRIBUTES
);
75 for (i
= 0; i
< Count
; i
++)
76 uLength
+= RtlLengthSid(Src
[i
].Sid
);
83 SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token
,
89 Token
->PrimaryGroup
= 0;
93 Token
->DefaultOwnerIndex
= Token
->UserAndGroupCount
;
96 /* Validate and set the primary group and user pointers */
97 for (i
= 0; i
< Token
->UserAndGroupCount
; i
++)
100 RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, DefaultOwner
))
102 Token
->DefaultOwnerIndex
= i
;
105 if (RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, PrimaryGroup
))
107 Token
->PrimaryGroup
= Token
->UserAndGroups
[i
].Sid
;
111 if (Token
->DefaultOwnerIndex
== Token
->UserAndGroupCount
)
113 return(STATUS_INVALID_OWNER
);
116 if (Token
->PrimaryGroup
== 0)
118 return(STATUS_INVALID_PRIMARY_GROUP
);
121 return(STATUS_SUCCESS
);
126 SepDuplicateToken(PTOKEN Token
,
127 POBJECT_ATTRIBUTES ObjectAttributes
,
128 BOOLEAN EffectiveOnly
,
129 TOKEN_TYPE TokenType
,
130 SECURITY_IMPERSONATION_LEVEL Level
,
131 KPROCESSOR_MODE PreviousMode
,
132 PTOKEN
* NewAccessToken
)
140 if(PreviousMode
!= KernelMode
)
142 Status
= STATUS_SUCCESS
;
145 ProbeForWrite(NewAccessToken
,
151 Status
= _SEH_GetExceptionCode();
155 if(!NT_SUCCESS(Status
))
161 Status
= ObCreateObject(PreviousMode
,
169 (PVOID
*)&AccessToken
);
170 if (!NT_SUCCESS(Status
))
172 DPRINT1("ObCreateObject() failed (Status %lx)\n");
176 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->TokenId
);
177 if (!NT_SUCCESS(Status
))
179 ObDereferenceObject(AccessToken
);
183 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
184 if (!NT_SUCCESS(Status
))
186 ObDereferenceObject(AccessToken
);
190 AccessToken
->TokenInUse
= 0;
191 AccessToken
->TokenType
= TokenType
;
192 AccessToken
->ImpersonationLevel
= Level
;
193 RtlCopyLuid(&AccessToken
->AuthenticationId
, &Token
->AuthenticationId
);
195 AccessToken
->TokenSource
.SourceIdentifier
.LowPart
= Token
->TokenSource
.SourceIdentifier
.LowPart
;
196 AccessToken
->TokenSource
.SourceIdentifier
.HighPart
= Token
->TokenSource
.SourceIdentifier
.HighPart
;
197 memcpy(AccessToken
->TokenSource
.SourceName
,
198 Token
->TokenSource
.SourceName
,
199 sizeof(Token
->TokenSource
.SourceName
));
200 AccessToken
->ExpirationTime
.QuadPart
= Token
->ExpirationTime
.QuadPart
;
201 AccessToken
->UserAndGroupCount
= Token
->UserAndGroupCount
;
202 AccessToken
->DefaultOwnerIndex
= Token
->DefaultOwnerIndex
;
204 uLength
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
205 for (i
= 0; i
< Token
->UserAndGroupCount
; i
++)
206 uLength
+= RtlLengthSid(Token
->UserAndGroups
[i
].Sid
);
208 AccessToken
->UserAndGroups
=
209 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
211 TAG('T', 'O', 'K', 'u'));
213 EndMem
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
215 Status
= RtlCopySidAndAttributesArray(AccessToken
->UserAndGroupCount
,
216 Token
->UserAndGroups
,
218 AccessToken
->UserAndGroups
,
222 if (NT_SUCCESS(Status
))
224 Status
= SepFindPrimaryGroupAndDefaultOwner(
230 if (NT_SUCCESS(Status
))
232 AccessToken
->PrivilegeCount
= Token
->PrivilegeCount
;
234 uLength
= AccessToken
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
235 AccessToken
->Privileges
=
236 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
238 TAG('T', 'O', 'K', 'p'));
240 for (i
= 0; i
< AccessToken
->PrivilegeCount
; i
++)
242 RtlCopyLuid(&AccessToken
->Privileges
[i
].Luid
,
243 &Token
->Privileges
[i
].Luid
);
244 AccessToken
->Privileges
[i
].Attributes
=
245 Token
->Privileges
[i
].Attributes
;
248 if ( Token
->DefaultDacl
)
250 AccessToken
->DefaultDacl
=
251 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
252 Token
->DefaultDacl
->AclSize
,
253 TAG('T', 'O', 'K', 'd'));
254 memcpy(AccessToken
->DefaultDacl
,
256 Token
->DefaultDacl
->AclSize
);
260 AccessToken
->DefaultDacl
= 0;
264 if ( NT_SUCCESS(Status
) )
268 *NewAccessToken
= AccessToken
;
269 Status
= STATUS_SUCCESS
;
273 Status
= _SEH_GetExceptionCode();
279 ObDereferenceObject(AccessToken
);
285 SepInitializeNewProcess(struct _EPROCESS
* NewProcess
,
286 struct _EPROCESS
* ParentProcess
)
292 OBJECT_ATTRIBUTES ObjectAttributes
;
294 pParentToken
= (PACCESS_TOKEN
) ParentProcess
->Token
;
296 InitializeObjectAttributes(&ObjectAttributes
,
302 Status
= SepDuplicateToken(pParentToken
,
306 pParentToken
->ImpersonationLevel
,
309 if ( ! NT_SUCCESS(Status
) )
312 NewProcess
->Token
= pNewToken
;
313 return(STATUS_SUCCESS
);
322 PACCESS_STATE AccessState
,
323 PPRIVILEGE_SET Privileges
327 return STATUS_NOT_IMPLEMENTED
;
332 SeCopyClientToken(PACCESS_TOKEN Token
,
333 SECURITY_IMPERSONATION_LEVEL Level
,
334 KPROCESSOR_MODE PreviousMode
,
335 PACCESS_TOKEN
* NewToken
)
338 OBJECT_ATTRIBUTES ObjectAttributes
;
340 InitializeObjectAttributes(&ObjectAttributes
,
345 Status
= SepDuplicateToken(Token
,
361 SeCreateClientSecurity(IN
struct _ETHREAD
*Thread
,
362 IN PSECURITY_QUALITY_OF_SERVICE Qos
,
363 IN BOOLEAN RemoteClient
,
364 OUT PSECURITY_CLIENT_CONTEXT ClientContext
)
366 TOKEN_TYPE TokenType
;
368 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
371 PACCESS_TOKEN NewToken
;
373 Token
= PsReferenceEffectiveToken(Thread
,
376 &ImpersonationLevel
);
377 if (TokenType
!= TokenImpersonation
)
379 ClientContext
->DirectAccessEffectiveOnly
= Qos
->EffectiveOnly
;
383 if (Qos
->ImpersonationLevel
> ImpersonationLevel
)
387 ObDereferenceObject(Token
);
389 return(STATUS_UNSUCCESSFUL
);
391 if (ImpersonationLevel
== SecurityAnonymous
||
392 ImpersonationLevel
== SecurityIdentification
||
393 (RemoteClient
!= FALSE
&& ImpersonationLevel
!= SecurityDelegation
))
397 ObDereferenceObject(Token
);
399 return(STATUS_UNSUCCESSFUL
);
402 Qos
->EffectiveOnly
!= 0)
404 ClientContext
->DirectAccessEffectiveOnly
= TRUE
;
408 ClientContext
->DirectAccessEffectiveOnly
= FALSE
;
412 if (Qos
->ContextTrackingMode
== 0)
414 ClientContext
->DirectlyAccessClientToken
= FALSE
;
415 g
= SeCopyClientToken(Token
, ImpersonationLevel
, 0, &NewToken
);
418 // ObDeleteCapturedInsertInfo(NewToken);
420 if (TokenType
== TokenPrimary
|| Token
!= NULL
)
422 ObDereferenceObject(Token
);
431 ClientContext
->DirectlyAccessClientToken
= TRUE
;
432 if (RemoteClient
!= FALSE
)
434 // SeGetTokenControlInformation(Token, &ClientContext->Unknown11);
438 ClientContext
->SecurityQos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
439 ClientContext
->SecurityQos
.ImpersonationLevel
= Qos
->ImpersonationLevel
;
440 ClientContext
->SecurityQos
.ContextTrackingMode
= Qos
->ContextTrackingMode
;
441 ClientContext
->SecurityQos
.EffectiveOnly
= Qos
->EffectiveOnly
;
442 ClientContext
->ServerIsRemote
= RemoteClient
;
443 ClientContext
->ClientToken
= NewToken
;
445 return(STATUS_SUCCESS
);
453 SeCreateClientSecurityFromSubjectContext(
454 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
455 IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos
,
456 IN BOOLEAN ServerIsRemote
,
457 OUT PSECURITY_CLIENT_CONTEXT ClientContext
461 return STATUS_NOT_IMPLEMENTED
;
470 IN PACCESS_TOKEN ExistingToken
,
472 IN PTOKEN_GROUPS SidsToDisable OPTIONAL
,
473 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL
,
474 IN PTOKEN_GROUPS RestrictedSids OPTIONAL
,
475 OUT PACCESS_TOKEN
* FilteredToken
479 return STATUS_NOT_IMPLEMENTED
;
488 IN PPRIVILEGE_SET Privileges
500 SeImpersonateClientEx(
501 IN PSECURITY_CLIENT_CONTEXT ClientContext
,
502 IN PETHREAD ServerThread OPTIONAL
506 return STATUS_NOT_IMPLEMENTED
;
513 SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext
,
514 IN PETHREAD ServerThread OPTIONAL
)
518 if (ClientContext
->DirectlyAccessClientToken
== FALSE
)
520 b
= ClientContext
->SecurityQos
.EffectiveOnly
;
524 b
= ClientContext
->DirectAccessEffectiveOnly
;
526 if (ServerThread
== NULL
)
528 ServerThread
= PsGetCurrentThread();
530 PsImpersonateClient(ServerThread
,
531 ClientContext
->ClientToken
,
534 ClientContext
->SecurityQos
.ImpersonationLevel
);
539 SepDeleteToken(PVOID ObjectBody
)
541 PTOKEN AccessToken
= (PTOKEN
)ObjectBody
;
543 if (AccessToken
->UserAndGroups
)
544 ExFreePool(AccessToken
->UserAndGroups
);
546 if (AccessToken
->Privileges
)
547 ExFreePool(AccessToken
->Privileges
);
549 if (AccessToken
->DefaultDacl
)
550 ExFreePool(AccessToken
->DefaultDacl
);
555 SepInitializeTokenImplementation(VOID
)
557 SepTokenObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
559 SepTokenObjectType
->Tag
= TAG('T', 'O', 'K', 'T');
560 SepTokenObjectType
->PeakObjects
= 0;
561 SepTokenObjectType
->PeakHandles
= 0;
562 SepTokenObjectType
->TotalObjects
= 0;
563 SepTokenObjectType
->TotalHandles
= 0;
564 SepTokenObjectType
->PagedPoolCharge
= 0;
565 SepTokenObjectType
->NonpagedPoolCharge
= sizeof(TOKEN
);
566 SepTokenObjectType
->Mapping
= &SepTokenMapping
;
567 SepTokenObjectType
->Dump
= NULL
;
568 SepTokenObjectType
->Open
= NULL
;
569 SepTokenObjectType
->Close
= NULL
;
570 SepTokenObjectType
->Delete
= SepDeleteToken
;
571 SepTokenObjectType
->Parse
= NULL
;
572 SepTokenObjectType
->Security
= NULL
;
573 SepTokenObjectType
->QueryName
= NULL
;
574 SepTokenObjectType
->OkayToClose
= NULL
;
575 SepTokenObjectType
->Create
= NULL
;
576 SepTokenObjectType
->DuplicationNotify
= NULL
;
578 RtlpCreateUnicodeString(&SepTokenObjectType
->TypeName
,
579 L
"Token", NonPagedPool
);
580 ObpCreateTypeObject (SepTokenObjectType
);
588 NtQueryInformationToken(IN HANDLE TokenHandle
,
589 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
590 OUT PVOID TokenInformation
,
591 IN ULONG TokenInformationLength
,
592 OUT PULONG ReturnLength
)
594 NTSTATUS Status
, LengthStatus
;
599 PTOKEN_GROUPS PtrTokenGroups
;
600 PTOKEN_DEFAULT_DACL PtrDefaultDacl
;
601 PTOKEN_STATISTICS PtrTokenStatistics
;
603 Status
= ObReferenceObjectByHandle(TokenHandle
,
604 (TokenInformationClass
== TokenSource
) ? TOKEN_QUERY_SOURCE
: TOKEN_QUERY
,
609 if (!NT_SUCCESS(Status
))
614 switch (TokenInformationClass
)
617 DPRINT("NtQueryInformationToken(TokenUser)\n");
618 Length
= RtlLengthSidAndAttributes(1, Token
->UserAndGroups
);
619 if (TokenInformationLength
< Length
)
621 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
622 if (NT_SUCCESS(Status
))
623 Status
= STATUS_BUFFER_TOO_SMALL
;
627 Status
= RtlCopySidAndAttributesArray(1,
628 Token
->UserAndGroups
,
629 TokenInformationLength
,
631 (char*)TokenInformation
+ 8,
634 if (NT_SUCCESS(Status
))
636 Length
= TokenInformationLength
- Length
;
637 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
643 DPRINT("NtQueryInformationToken(TokenGroups)\n");
644 Length
= RtlLengthSidAndAttributes(Token
->UserAndGroupCount
- 1, &Token
->UserAndGroups
[1]) + sizeof(ULONG
);
645 if (TokenInformationLength
< Length
)
647 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
648 if (NT_SUCCESS(Status
))
649 Status
= STATUS_BUFFER_TOO_SMALL
;
653 EndMem
= (char*)TokenInformation
+ Token
->UserAndGroupCount
* sizeof(SID_AND_ATTRIBUTES
);
654 PtrTokenGroups
= (PTOKEN_GROUPS
)TokenInformation
;
655 PtrTokenGroups
->GroupCount
= Token
->UserAndGroupCount
- 1;
656 Status
= RtlCopySidAndAttributesArray(Token
->UserAndGroupCount
- 1,
657 &Token
->UserAndGroups
[1],
658 TokenInformationLength
,
659 PtrTokenGroups
->Groups
,
663 if (NT_SUCCESS(Status
))
665 Length
= TokenInformationLength
- Length
;
666 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
671 case TokenPrivileges
:
672 DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
673 Length
= sizeof(ULONG
) + Token
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
674 if (TokenInformationLength
< Length
)
676 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
677 if (NT_SUCCESS(Status
))
678 Status
= STATUS_BUFFER_TOO_SMALL
;
683 TOKEN_PRIVILEGES
* pPriv
= (TOKEN_PRIVILEGES
*)TokenInformation
;
685 pPriv
->PrivilegeCount
= Token
->PrivilegeCount
;
686 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
688 RtlCopyLuid(&pPriv
->Privileges
[i
].Luid
, &Token
->Privileges
[i
].Luid
);
689 pPriv
->Privileges
[i
].Attributes
= Token
->Privileges
[i
].Attributes
;
691 Status
= STATUS_SUCCESS
;
696 DPRINT("NtQueryInformationToken(TokenOwner)\n");
697 Length
= RtlLengthSid(Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
) + sizeof(TOKEN_OWNER
);
698 if (TokenInformationLength
< Length
)
700 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
701 if (NT_SUCCESS(Status
))
702 Status
= STATUS_BUFFER_TOO_SMALL
;
706 ((PTOKEN_OWNER
)TokenInformation
)->Owner
=
707 (PSID
)(((PTOKEN_OWNER
)TokenInformation
) + 1);
708 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
709 ((PTOKEN_OWNER
)TokenInformation
)->Owner
,
710 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
);
711 Status
= STATUS_SUCCESS
;
715 case TokenPrimaryGroup
:
716 DPRINT("NtQueryInformationToken(TokenPrimaryGroup),"
717 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
718 Length
= RtlLengthSid(Token
->PrimaryGroup
) + sizeof(TOKEN_PRIMARY_GROUP
);
719 if (TokenInformationLength
< Length
)
721 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
722 if (NT_SUCCESS(Status
))
723 Status
= STATUS_BUFFER_TOO_SMALL
;
727 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
=
728 (PSID
)(((PTOKEN_PRIMARY_GROUP
)TokenInformation
) + 1);
729 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
730 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
,
731 Token
->PrimaryGroup
);
732 Status
= STATUS_SUCCESS
;
736 case TokenDefaultDacl
:
737 DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
738 PtrDefaultDacl
= (PTOKEN_DEFAULT_DACL
) TokenInformation
;
739 Length
= (Token
->DefaultDacl
? Token
->DefaultDacl
->AclSize
: 0) + sizeof(TOKEN_DEFAULT_DACL
);
740 if (TokenInformationLength
< Length
)
742 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
743 if (NT_SUCCESS(Status
))
744 Status
= STATUS_BUFFER_TOO_SMALL
;
746 else if (!Token
->DefaultDacl
)
748 PtrDefaultDacl
->DefaultDacl
= 0;
749 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
753 PtrDefaultDacl
->DefaultDacl
= (PACL
) (PtrDefaultDacl
+ 1);
754 memmove(PtrDefaultDacl
->DefaultDacl
,
756 Token
->DefaultDacl
->AclSize
);
757 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
762 DPRINT("NtQueryInformationToken(TokenSource)\n");
763 if (TokenInformationLength
< sizeof(TOKEN_SOURCE
))
765 Length
= sizeof(TOKEN_SOURCE
);
766 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
767 if (NT_SUCCESS(Status
))
768 Status
= STATUS_BUFFER_TOO_SMALL
;
772 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenSource
, sizeof(TOKEN_SOURCE
));
777 DPRINT("NtQueryInformationToken(TokenType)\n");
778 if (TokenInformationLength
< sizeof(TOKEN_TYPE
))
780 Length
= sizeof(TOKEN_TYPE
);
781 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
782 if (NT_SUCCESS(Status
))
783 Status
= STATUS_BUFFER_TOO_SMALL
;
787 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenType
, sizeof(TOKEN_TYPE
));
791 case TokenImpersonationLevel
:
792 DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
793 if (TokenInformationLength
< sizeof(SECURITY_IMPERSONATION_LEVEL
))
795 Length
= sizeof(SECURITY_IMPERSONATION_LEVEL
);
796 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
797 if (NT_SUCCESS(Status
))
798 Status
= STATUS_BUFFER_TOO_SMALL
;
802 Status
= MmCopyToCaller(TokenInformation
, &Token
->ImpersonationLevel
, sizeof(SECURITY_IMPERSONATION_LEVEL
));
806 case TokenStatistics
:
807 DPRINT("NtQueryInformationToken(TokenStatistics)\n");
808 if (TokenInformationLength
< sizeof(TOKEN_STATISTICS
))
810 Length
= sizeof(TOKEN_STATISTICS
);
811 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
812 if (NT_SUCCESS(Status
))
813 Status
= STATUS_BUFFER_TOO_SMALL
;
817 PtrTokenStatistics
= (PTOKEN_STATISTICS
)TokenInformation
;
818 PtrTokenStatistics
->TokenId
= Token
->TokenId
;
819 PtrTokenStatistics
->AuthenticationId
= Token
->AuthenticationId
;
820 PtrTokenStatistics
->ExpirationTime
= Token
->ExpirationTime
;
821 PtrTokenStatistics
->TokenType
= Token
->TokenType
;
822 PtrTokenStatistics
->ImpersonationLevel
= Token
->ImpersonationLevel
;
823 PtrTokenStatistics
->DynamicCharged
= Token
->DynamicCharged
;
824 PtrTokenStatistics
->DynamicAvailable
= Token
->DynamicAvailable
;
825 PtrTokenStatistics
->GroupCount
= Token
->UserAndGroupCount
- 1;
826 PtrTokenStatistics
->PrivilegeCount
= Token
->PrivilegeCount
;
827 PtrTokenStatistics
->ModifiedId
= Token
->ModifiedId
;
829 Status
= STATUS_SUCCESS
;
834 DPRINT("NtQueryInformationToken(TokenOrigin)\n");
835 if (TokenInformationLength
< sizeof(TOKEN_ORIGIN
))
837 Status
= STATUS_BUFFER_TOO_SMALL
;
841 Status
= MmCopyToCaller(&((PTOKEN_ORIGIN
)TokenInformation
)->OriginatingLogonSession
,
842 &Token
->AuthenticationId
, sizeof(LUID
));
844 Length
= sizeof(TOKEN_ORIGIN
);
845 LengthStatus
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
846 if (NT_SUCCESS(Status
))
848 Status
= LengthStatus
;
852 case TokenGroupsAndPrivileges
:
853 DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
854 Status
= STATUS_NOT_IMPLEMENTED
;
857 case TokenRestrictedSids
:
858 DPRINT1("NtQueryInformationToken(TokenRestrictedSids) not implemented\n");
859 Status
= STATUS_NOT_IMPLEMENTED
;
862 case TokenSandBoxInert
:
863 DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n");
864 Status
= STATUS_NOT_IMPLEMENTED
;
868 DPRINT("NtQueryInformationToken(TokenSessionId)\n");
869 if (TokenInformationLength
< sizeof(ULONG
))
871 Length
= sizeof(ULONG
);
872 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
873 if (NT_SUCCESS(Status
))
874 Status
= STATUS_BUFFER_TOO_SMALL
;
878 Status
= MmCopyToCaller(TokenInformation
, &Token
->SessionId
, sizeof(ULONG
));
883 DPRINT1("NtQueryInformationToken(%d) invalid parameter\n");
884 Status
= STATUS_INVALID_PARAMETER
;
888 ObDereferenceObject(Token
);
898 SeQueryInformationToken(
899 IN PACCESS_TOKEN Token
,
900 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
901 OUT PVOID
*TokenInformation
905 return STATUS_NOT_IMPLEMENTED
;
913 SeQuerySessionIdToken(
914 IN PACCESS_TOKEN Token
,
919 return STATUS_NOT_IMPLEMENTED
;
923 * NtSetTokenInformation: Partly implemented.
925 * TokenOrigin, TokenDefaultDacl, TokenSessionId
929 NtSetInformationToken(IN HANDLE TokenHandle
,
930 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
931 OUT PVOID TokenInformation
,
932 IN ULONG TokenInformationLength
)
936 TOKEN_OWNER TokenOwnerSet
= { 0 };
937 TOKEN_PRIMARY_GROUP TokenPrimaryGroupSet
= { 0 };
938 DWORD NeededAccess
= 0;
940 switch (TokenInformationClass
)
943 case TokenPrimaryGroup
:
944 NeededAccess
= TOKEN_ADJUST_DEFAULT
;
947 case TokenDefaultDacl
:
948 if (TokenInformationLength
< sizeof(TOKEN_DEFAULT_DACL
))
949 return STATUS_BUFFER_TOO_SMALL
;
950 NeededAccess
= TOKEN_ADJUST_DEFAULT
;
954 DPRINT1("NtSetInformationToken: lying about success (stub) - %x\n", TokenInformationClass
);
955 return STATUS_SUCCESS
;
959 Status
= ObReferenceObjectByHandle(TokenHandle
,
965 if (!NT_SUCCESS(Status
))
970 switch (TokenInformationClass
)
973 MmCopyFromCaller( &TokenOwnerSet
, TokenInformation
,
974 min(sizeof(TokenOwnerSet
),TokenInformationLength
) );
975 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
976 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
,
977 TokenOwnerSet
.Owner
);
978 Status
= STATUS_SUCCESS
;
979 DPRINT("NtSetInformationToken(TokenOwner)\n");
982 case TokenPrimaryGroup
:
983 MmCopyFromCaller( &TokenPrimaryGroupSet
, TokenInformation
,
984 min(sizeof(TokenPrimaryGroupSet
),
985 TokenInformationLength
) );
986 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
988 TokenPrimaryGroupSet
.PrimaryGroup
);
989 Status
= STATUS_SUCCESS
;
990 DPRINT("NtSetInformationToken(TokenPrimaryGroup),"
991 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
994 case TokenDefaultDacl
:
996 TOKEN_DEFAULT_DACL TokenDefaultDacl
= { 0 };
1000 Status
= MmCopyFromCaller( &TokenDefaultDacl
, TokenInformation
,
1001 sizeof(TOKEN_DEFAULT_DACL
) );
1002 if (!NT_SUCCESS(Status
))
1004 Status
= STATUS_INVALID_PARAMETER
;
1008 Status
= MmCopyFromCaller( &OldAcl
, TokenDefaultDacl
.DefaultDacl
,
1010 if (!NT_SUCCESS(Status
))
1012 Status
= STATUS_INVALID_PARAMETER
;
1016 NewAcl
= ExAllocatePool(NonPagedPool
, sizeof(ACL
));
1019 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1023 Status
= MmCopyFromCaller( NewAcl
, TokenDefaultDacl
.DefaultDacl
,
1025 if (!NT_SUCCESS(Status
))
1027 Status
= STATUS_INVALID_PARAMETER
;
1032 if (Token
->DefaultDacl
)
1034 ExFreePool(Token
->DefaultDacl
);
1037 Token
->DefaultDacl
= NewAcl
;
1039 Status
= STATUS_SUCCESS
;
1044 Status
= STATUS_NOT_IMPLEMENTED
;
1048 ObDereferenceObject(Token
);
1057 * NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
1058 * this is certainly NOT true, thou i can't say for sure that EffectiveOnly
1059 * is correct either. -Gunnar
1060 * This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
1063 NtDuplicateToken(IN HANDLE ExistingTokenHandle
,
1064 IN ACCESS_MASK DesiredAccess
,
1065 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
/*is it really optional?*/,
1066 IN BOOLEAN EffectiveOnly
,
1067 IN TOKEN_TYPE TokenType
,
1068 OUT PHANDLE NewTokenHandle
)
1070 KPROCESSOR_MODE PreviousMode
;
1075 PreviousMode
= KeGetPreviousMode();
1076 Status
= ObReferenceObjectByHandle(ExistingTokenHandle
,
1082 if (!NT_SUCCESS(Status
))
1084 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
1088 Status
= SepDuplicateToken(Token
,
1092 ObjectAttributes
->SecurityQualityOfService
?
1093 ((PSECURITY_QUALITY_OF_SERVICE
)(ObjectAttributes
->SecurityQualityOfService
))->ImpersonationLevel
:
1094 0 /*SecurityAnonymous*/,
1098 ObDereferenceObject(Token
);
1100 if (!NT_SUCCESS(Status
))
1102 DPRINT1("Failed to duplicate token (Status %lx)\n", Status
);
1106 Status
= ObInsertObject((PVOID
)NewToken
,
1113 ObDereferenceObject(NewToken
);
1115 if (!NT_SUCCESS(Status
))
1117 DPRINT1("Failed to create token handle (Status %lx)\n");
1121 return STATUS_SUCCESS
;
1125 VOID
SepAdjustGroups(PACCESS_TOKEN Token
,
1127 BOOLEAN ResetToDefault
,
1128 PSID_AND_ATTRIBUTES Groups
,
1130 KPROCESSOR_MODE PreviousMode
,
1141 NtAdjustGroupsToken(IN HANDLE TokenHandle
,
1142 IN BOOLEAN ResetToDefault
,
1143 IN PTOKEN_GROUPS NewState
,
1144 IN ULONG BufferLength
,
1145 OUT PTOKEN_GROUPS PreviousState OPTIONAL
,
1146 OUT PULONG ReturnLength
)
1150 PACCESS_TOKEN Token
;
1155 Status
= ObReferenceObjectByHandle(TokenHandle
,
1163 SepAdjustGroups(Token
,
1175 return(STATUS_NOT_IMPLEMENTED
);
1182 SepAdjustPrivileges(PACCESS_TOKEN Token
,
1184 KPROCESSOR_MODE PreviousMode
,
1185 ULONG PrivilegeCount
,
1186 PLUID_AND_ATTRIBUTES Privileges
,
1187 PTOKEN_PRIVILEGES
* PreviousState
,
1196 if (Token
->PrivilegeCount
> 0)
1198 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1200 if (PreviousMode
!= KernelMode
)
1202 if (Token
->Privileges
[i
]->Attributes
& SE_PRIVILEGE_ENABLED
== 0)
1206 if (PreviousState
!= NULL
)
1208 memcpy(&PreviousState
[i
],
1209 &Token
->Privileges
[i
],
1210 sizeof(LUID_AND_ATTRIBUTES
));
1212 Token
->Privileges
[i
].Attributes
&= (~SE_PRIVILEGE_ENABLED
);
1219 if (PreviousMode
!= KernelMode
)
1221 Token
->TokenFlags
= Token
->TokenFlags
& (~1);
1225 if (PrivilegeCount
<= ?)
1238 NtAdjustPrivilegesToken (IN HANDLE TokenHandle
,
1239 IN BOOLEAN DisableAllPrivileges
,
1240 IN PTOKEN_PRIVILEGES NewState
,
1241 IN ULONG BufferLength
,
1242 OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL
,
1243 OUT PULONG ReturnLength OPTIONAL
)
1245 // PLUID_AND_ATTRIBUTES Privileges;
1246 KPROCESSOR_MODE PreviousMode
;
1247 // ULONG PrivilegeCount;
1261 DPRINT ("NtAdjustPrivilegesToken() called\n");
1263 // PrivilegeCount = NewState->PrivilegeCount;
1264 PreviousMode
= KeGetPreviousMode ();
1265 // SeCaptureLuidAndAttributesArray(NewState->Privileges,
1275 Status
= ObReferenceObjectByHandle (TokenHandle
,
1276 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1281 if (!NT_SUCCESS(Status
))
1283 DPRINT1 ("Failed to reference token (Status %lx)\n", Status
);
1284 // SeReleaseLuidAndAttributesArray(Privileges,
1292 SepAdjustPrivileges(Token
,
1304 if (DisableAllPrivileges
== TRUE
)
1306 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1308 if (Token
->Privileges
[i
].Attributes
!= 0)
1310 DPRINT ("Attributes differ\n");
1312 /* Save current privilege */
1313 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1315 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1316 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1320 /* Update current privlege */
1321 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1324 Status
= STATUS_SUCCESS
;
1329 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1331 for (j
= 0; j
< NewState
->PrivilegeCount
; j
++)
1333 if (Token
->Privileges
[i
].Luid
.LowPart
== NewState
->Privileges
[j
].Luid
.LowPart
&&
1334 Token
->Privileges
[i
].Luid
.HighPart
== NewState
->Privileges
[j
].Luid
.HighPart
)
1336 DPRINT ("Found privilege\n");
1338 if ((Token
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
) !=
1339 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
))
1341 DPRINT ("Attributes differ\n");
1342 DPRINT ("Current attributes %lx desired attributes %lx\n",
1343 Token
->Privileges
[i
].Attributes
,
1344 NewState
->Privileges
[j
].Attributes
);
1346 /* Save current privilege */
1347 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1349 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1350 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1354 /* Update current privlege */
1355 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1356 Token
->Privileges
[i
].Attributes
|=
1357 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
);
1358 DPRINT ("New attributes %lx\n",
1359 Token
->Privileges
[i
].Attributes
);
1365 Status
= Count
< NewState
->PrivilegeCount
? STATUS_NOT_ALL_ASSIGNED
: STATUS_SUCCESS
;
1368 if (ReturnLength
!= NULL
)
1370 *ReturnLength
= sizeof(TOKEN_PRIVILEGES
) +
1371 (sizeof(LUID_AND_ATTRIBUTES
) * (k
- 1));
1374 ObDereferenceObject (Token
);
1376 // SeReleaseLuidAndAttributesArray(Privileges,
1380 DPRINT ("NtAdjustPrivilegesToken() done\n");
1387 SepCreateSystemProcessToken(struct _EPROCESS
* Process
)
1393 ULONG uLocalSystemLength
= RtlLengthSid(SeLocalSystemSid
);
1394 ULONG uWorldLength
= RtlLengthSid(SeWorldSid
);
1395 ULONG uAuthUserLength
= RtlLengthSid(SeAuthenticatedUserSid
);
1396 ULONG uAdminsLength
= RtlLengthSid(SeAliasAdminsSid
);
1403 * Initialize the token
1405 Status
= ObCreateObject(KernelMode
,
1413 (PVOID
*)&AccessToken
);
1414 if (!NT_SUCCESS(Status
))
1419 Status
= NtAllocateLocallyUniqueId(&AccessToken
->TokenId
);
1420 if (!NT_SUCCESS(Status
))
1422 ObDereferenceObject(AccessToken
);
1426 Status
= NtAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
1427 if (!NT_SUCCESS(Status
))
1429 ObDereferenceObject(AccessToken
);
1433 Status
= NtAllocateLocallyUniqueId(&AccessToken
->AuthenticationId
);
1434 if (!NT_SUCCESS(Status
))
1436 ObDereferenceObject(AccessToken
);
1440 AccessToken
->TokenType
= TokenPrimary
;
1441 AccessToken
->ImpersonationLevel
= SecurityDelegation
;
1442 AccessToken
->TokenSource
.SourceIdentifier
.LowPart
= 0;
1443 AccessToken
->TokenSource
.SourceIdentifier
.HighPart
= 0;
1444 memcpy(AccessToken
->TokenSource
.SourceName
, "SeMgr\0\0\0", 8);
1445 AccessToken
->ExpirationTime
.QuadPart
= -1;
1446 AccessToken
->UserAndGroupCount
= 4;
1448 uSize
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1449 uSize
+= uLocalSystemLength
;
1450 uSize
+= uWorldLength
;
1451 uSize
+= uAuthUserLength
;
1452 uSize
+= uAdminsLength
;
1454 AccessToken
->UserAndGroups
=
1455 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1457 TAG('T', 'O', 'K', 'u'));
1458 SidArea
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1461 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1462 AccessToken
->UserAndGroups
[i
++].Attributes
= 0;
1463 RtlCopySid(uLocalSystemLength
, SidArea
, SeLocalSystemSid
);
1464 SidArea
= (char*)SidArea
+ uLocalSystemLength
;
1466 AccessToken
->DefaultOwnerIndex
= i
;
1467 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1468 AccessToken
->PrimaryGroup
= (PSID
) SidArea
;
1469 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
;
1470 Status
= RtlCopySid(uAdminsLength
, SidArea
, SeAliasAdminsSid
);
1471 SidArea
= (char*)SidArea
+ uAdminsLength
;
1473 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1474 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1475 RtlCopySid(uWorldLength
, SidArea
, SeWorldSid
);
1476 SidArea
= (char*)SidArea
+ uWorldLength
;
1478 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1479 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1480 RtlCopySid(uAuthUserLength
, SidArea
, SeAuthenticatedUserSid
);
1481 SidArea
= (char*)SidArea
+ uAuthUserLength
;
1483 AccessToken
->PrivilegeCount
= 20;
1485 uSize
= AccessToken
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1486 AccessToken
->Privileges
=
1487 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1489 TAG('T', 'O', 'K', 'p'));
1492 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1493 AccessToken
->Privileges
[i
++].Luid
= SeTcbPrivilege
;
1495 AccessToken
->Privileges
[i
].Attributes
= 0;
1496 AccessToken
->Privileges
[i
++].Luid
= SeCreateTokenPrivilege
;
1498 AccessToken
->Privileges
[i
].Attributes
= 0;
1499 AccessToken
->Privileges
[i
++].Luid
= SeTakeOwnershipPrivilege
;
1501 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1502 AccessToken
->Privileges
[i
++].Luid
= SeCreatePagefilePrivilege
;
1504 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1505 AccessToken
->Privileges
[i
++].Luid
= SeLockMemoryPrivilege
;
1507 AccessToken
->Privileges
[i
].Attributes
= 0;
1508 AccessToken
->Privileges
[i
++].Luid
= SeAssignPrimaryTokenPrivilege
;
1510 AccessToken
->Privileges
[i
].Attributes
= 0;
1511 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseQuotaPrivilege
;
1513 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1514 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseBasePriorityPrivilege
;
1516 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1517 AccessToken
->Privileges
[i
++].Luid
= SeCreatePermanentPrivilege
;
1519 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1520 AccessToken
->Privileges
[i
++].Luid
= SeDebugPrivilege
;
1522 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1523 AccessToken
->Privileges
[i
++].Luid
= SeAuditPrivilege
;
1525 AccessToken
->Privileges
[i
].Attributes
= 0;
1526 AccessToken
->Privileges
[i
++].Luid
= SeSecurityPrivilege
;
1528 AccessToken
->Privileges
[i
].Attributes
= 0;
1529 AccessToken
->Privileges
[i
++].Luid
= SeSystemEnvironmentPrivilege
;
1531 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1532 AccessToken
->Privileges
[i
++].Luid
= SeChangeNotifyPrivilege
;
1534 AccessToken
->Privileges
[i
].Attributes
= 0;
1535 AccessToken
->Privileges
[i
++].Luid
= SeBackupPrivilege
;
1537 AccessToken
->Privileges
[i
].Attributes
= 0;
1538 AccessToken
->Privileges
[i
++].Luid
= SeRestorePrivilege
;
1540 AccessToken
->Privileges
[i
].Attributes
= 0;
1541 AccessToken
->Privileges
[i
++].Luid
= SeShutdownPrivilege
;
1543 AccessToken
->Privileges
[i
].Attributes
= 0;
1544 AccessToken
->Privileges
[i
++].Luid
= SeLoadDriverPrivilege
;
1546 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1547 AccessToken
->Privileges
[i
++].Luid
= SeProfileSingleProcessPrivilege
;
1549 AccessToken
->Privileges
[i
].Attributes
= 0;
1550 AccessToken
->Privileges
[i
++].Luid
= SeSystemtimePrivilege
;
1552 AccessToken
->Privileges
[i
].Attributes
= 0;
1553 AccessToken
->Privileges
[i
++].Luid
= SeUndockPrivilege
;
1555 AccessToken
->Privileges
[i
].Attributes
= 0;
1556 AccessToken
->Privileges
[i
++].Luid
= SeManageVolumePrivilege
;
1561 uSize
= sizeof(ACL
);
1562 uSize
+= sizeof(ACE
) + uLocalSystemLength
;
1563 uSize
+= sizeof(ACE
) + uAdminsLength
;
1564 uSize
= (uSize
& (~3)) + 8;
1565 AccessToken
->DefaultDacl
=
1566 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1568 TAG('T', 'O', 'K', 'd'));
1569 Status
= RtlCreateAcl(AccessToken
->DefaultDacl
, uSize
, ACL_REVISION
);
1570 if ( NT_SUCCESS(Status
) )
1572 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_ALL
, SeLocalSystemSid
);
1575 if ( NT_SUCCESS(Status
) )
1577 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_READ
|GENERIC_EXECUTE
|READ_CONTROL
, SeAliasAdminsSid
);
1580 if ( ! NT_SUCCESS(Status
) )
1582 ObDereferenceObject(AccessToken
);
1586 Process
->Token
= AccessToken
;
1587 return(STATUS_SUCCESS
);
1592 NtCreateToken(OUT PHANDLE UnsafeTokenHandle
,
1593 IN ACCESS_MASK DesiredAccess
,
1594 IN POBJECT_ATTRIBUTES ObjectAttributes
,
1595 IN TOKEN_TYPE TokenType
,
1596 IN PLUID AuthenticationId
,
1597 IN PLARGE_INTEGER ExpirationTime
,
1598 IN PTOKEN_USER TokenUser
,
1599 IN PTOKEN_GROUPS TokenGroups
,
1600 IN PTOKEN_PRIVILEGES TokenPrivileges
,
1601 IN PTOKEN_OWNER TokenOwner
,
1602 IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup
,
1603 IN PTOKEN_DEFAULT_DACL TokenDefaultDacl
,
1604 IN PTOKEN_SOURCE TokenSource
)
1615 Status
= ZwAllocateLocallyUniqueId(&TokenId
);
1616 if (!NT_SUCCESS(Status
))
1619 Status
= ZwAllocateLocallyUniqueId(&ModifiedId
);
1620 if (!NT_SUCCESS(Status
))
1623 Status
= ObCreateObject(ExGetPreviousMode(),
1626 ExGetPreviousMode(),
1631 (PVOID
*)&AccessToken
);
1632 if (!NT_SUCCESS(Status
))
1634 DPRINT1("ObCreateObject() failed (Status %lx)\n");
1638 Status
= ObInsertObject ((PVOID
)AccessToken
,
1644 if (!NT_SUCCESS(Status
))
1646 DPRINT1("ObInsertObject() failed (Status %lx)\n");
1647 ObDereferenceObject (AccessToken
);
1651 RtlCopyLuid(&AccessToken
->TokenSource
.SourceIdentifier
,
1652 &TokenSource
->SourceIdentifier
);
1653 memcpy(AccessToken
->TokenSource
.SourceName
,
1654 TokenSource
->SourceName
,
1655 sizeof(TokenSource
->SourceName
));
1657 RtlCopyLuid(&AccessToken
->TokenId
, &TokenId
);
1658 RtlCopyLuid(&AccessToken
->AuthenticationId
, AuthenticationId
);
1659 AccessToken
->ExpirationTime
= *ExpirationTime
;
1660 RtlCopyLuid(&AccessToken
->ModifiedId
, &ModifiedId
);
1662 AccessToken
->UserAndGroupCount
= TokenGroups
->GroupCount
+ 1;
1663 AccessToken
->PrivilegeCount
= TokenPrivileges
->PrivilegeCount
;
1664 AccessToken
->UserAndGroups
= 0;
1665 AccessToken
->Privileges
= 0;
1667 AccessToken
->TokenType
= TokenType
;
1668 AccessToken
->ImpersonationLevel
= ((PSECURITY_QUALITY_OF_SERVICE
)
1669 (ObjectAttributes
->SecurityQualityOfService
))->ImpersonationLevel
;
1672 * Normally we would just point these members into the variable information
1673 * area; however, our ObCreateObject() call can't allocate a variable information
1674 * area, so we allocate them seperately and provide a destroy function.
1677 uLength
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1678 uLength
+= RtlLengthSid(TokenUser
->User
.Sid
);
1679 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
1680 uLength
+= RtlLengthSid(TokenGroups
->Groups
[i
].Sid
);
1682 AccessToken
->UserAndGroups
=
1683 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1685 TAG('T', 'O', 'K', 'u'));
1687 EndMem
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1689 Status
= RtlCopySidAndAttributesArray(1,
1692 AccessToken
->UserAndGroups
,
1696 if (NT_SUCCESS(Status
))
1698 Status
= RtlCopySidAndAttributesArray(TokenGroups
->GroupCount
,
1699 TokenGroups
->Groups
,
1701 &AccessToken
->UserAndGroups
[1],
1707 if (NT_SUCCESS(Status
))
1709 Status
= SepFindPrimaryGroupAndDefaultOwner(
1711 TokenPrimaryGroup
->PrimaryGroup
,
1715 if (NT_SUCCESS(Status
))
1717 uLength
= TokenPrivileges
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1718 AccessToken
->Privileges
=
1719 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1721 TAG('T', 'O', 'K', 'p'));
1723 for (i
= 0; i
< TokenPrivileges
->PrivilegeCount
; i
++)
1725 Status
= MmCopyFromCaller(&AccessToken
->Privileges
[i
],
1726 &TokenPrivileges
->Privileges
[i
],
1727 sizeof(LUID_AND_ATTRIBUTES
));
1728 if (!NT_SUCCESS(Status
))
1733 if (NT_SUCCESS(Status
))
1735 AccessToken
->DefaultDacl
=
1736 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1737 TokenDefaultDacl
->DefaultDacl
->AclSize
,
1738 TAG('T', 'O', 'K', 'd'));
1739 memcpy(AccessToken
->DefaultDacl
,
1740 TokenDefaultDacl
->DefaultDacl
,
1741 TokenDefaultDacl
->DefaultDacl
->AclSize
);
1744 ObDereferenceObject(AccessToken
);
1746 if (NT_SUCCESS(Status
))
1748 Status
= MmCopyToCaller(UnsafeTokenHandle
,
1753 if (!NT_SUCCESS(Status
))
1755 ZwClose(TokenHandle
);
1759 return(STATUS_SUCCESS
);
1767 SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token
,
1770 *LogonId
= ((PTOKEN
)Token
)->AuthenticationId
;
1772 return STATUS_SUCCESS
;
1779 SECURITY_IMPERSONATION_LEVEL
1781 SeTokenImpersonationLevel(IN PACCESS_TOKEN Token
)
1783 return ((PTOKEN
)Token
)->ImpersonationLevel
;
1791 SeTokenType(IN PACCESS_TOKEN Token
)
1793 return ((PTOKEN
)Token
)->TokenType
;
1803 IN PACCESS_TOKEN Token
1815 SeTokenIsRestricted(
1816 IN PACCESS_TOKEN Token
1828 SeTokenIsWriteRestricted(
1829 IN PACCESS_TOKEN Token
1842 NtOpenThreadTokenEx(IN HANDLE ThreadHandle
,
1843 IN ACCESS_MASK DesiredAccess
,
1844 IN BOOLEAN OpenAsSelf
,
1845 IN ULONG HandleAttributes
,
1846 OUT PHANDLE TokenHandle
)
1849 PTOKEN Token
, NewToken
, PrimaryToken
;
1850 BOOLEAN CopyOnOpen
, EffectiveOnly
;
1851 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
1852 SE_IMPERSONATION_STATE ImpersonationState
;
1853 OBJECT_ATTRIBUTES ObjectAttributes
;
1854 SECURITY_DESCRIPTOR SecurityDescriptor
;
1859 * At first open the thread token for information access and verify
1860 * that the token associated with thread is valid.
1863 Status
= ObReferenceObjectByHandle(ThreadHandle
, THREAD_QUERY_INFORMATION
,
1864 PsThreadType
, UserMode
, (PVOID
*)&Thread
,
1866 if (!NT_SUCCESS(Status
))
1871 Token
= PsReferenceImpersonationToken(Thread
, &CopyOnOpen
, &EffectiveOnly
,
1872 &ImpersonationLevel
);
1875 ObfDereferenceObject(Thread
);
1876 return STATUS_NO_TOKEN
;
1879 ObDereferenceObject(Thread
);
1881 if (ImpersonationLevel
== SecurityAnonymous
)
1883 ObfDereferenceObject(Token
);
1884 return STATUS_CANT_OPEN_ANONYMOUS
;
1888 * Revert to self if OpenAsSelf is specified.
1893 PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1898 Status
= ObReferenceObjectByHandle(ThreadHandle
, THREAD_ALL_ACCESS
,
1899 PsThreadType
, UserMode
,
1900 (PVOID
*)&Thread
, NULL
);
1901 if (!NT_SUCCESS(Status
))
1903 ObfDereferenceObject(Token
);
1906 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1911 PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
1912 Status
= SepCreateImpersonationTokenDacl(Token
, PrimaryToken
, &Dacl
);
1913 ObfDereferenceObject(PrimaryToken
);
1914 ObfDereferenceObject(Thread
);
1915 if (!NT_SUCCESS(Status
))
1917 ObfDereferenceObject(Token
);
1920 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1925 RtlCreateSecurityDescriptor(&SecurityDescriptor
,
1926 SECURITY_DESCRIPTOR_REVISION
);
1927 RtlSetDaclSecurityDescriptor(&SecurityDescriptor
, TRUE
, Dacl
,
1930 InitializeObjectAttributes(&ObjectAttributes
, NULL
, HandleAttributes
,
1931 NULL
, &SecurityDescriptor
);
1933 Status
= SepDuplicateToken(Token
, &ObjectAttributes
, EffectiveOnly
,
1934 TokenImpersonation
, ImpersonationLevel
,
1935 KernelMode
, &NewToken
);
1937 if (!NT_SUCCESS(Status
))
1939 ObfDereferenceObject(Token
);
1942 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1947 Status
= ObInsertObject(NewToken
, NULL
, DesiredAccess
, 0, NULL
,
1950 ObfDereferenceObject(NewToken
);
1954 Status
= ObOpenObjectByPointer(Token
, HandleAttributes
,
1955 NULL
, DesiredAccess
, SepTokenObjectType
,
1956 ExGetPreviousMode(), TokenHandle
);
1959 ObfDereferenceObject(Token
);
1963 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1973 NtOpenThreadToken(IN HANDLE ThreadHandle
,
1974 IN ACCESS_MASK DesiredAccess
,
1975 IN BOOLEAN OpenAsSelf
,
1976 OUT PHANDLE TokenHandle
)
1978 return NtOpenThreadTokenEx(ThreadHandle
, DesiredAccess
, OpenAsSelf
, 0,