3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/token.c
7 * PROGRAMER: David Welch <welch@cwcom.net>
9 * 26/07/98: Added stubs for security functions
12 /* INCLUDES *****************************************************************/
15 #define NTOS_MODE_KERNEL
17 #include <internal/ob.h>
18 #include <internal/ps.h>
19 #include <internal/se.h>
20 #include <internal/safe.h>
23 #include <internal/debug.h>
25 /* GLOBALS *******************************************************************/
27 POBJECT_TYPE SepTokenObjectType
= NULL
;
29 static GENERIC_MAPPING SepTokenMapping
= {TOKEN_READ
,
34 //#define SYSTEM_LUID 0x3E7;
36 /* FUNCTIONS *****************************************************************/
38 VOID
SepFreeProxyData(PVOID ProxyData
)
43 NTSTATUS
SepCopyProxyData(PVOID
* Dest
, PVOID Src
)
46 return(STATUS_NOT_IMPLEMENTED
);
49 NTSTATUS
SeExchangePrimaryToken(PEPROCESS Process
,
50 PACCESS_TOKEN NewTokenP
,
51 PACCESS_TOKEN
* OldTokenP
)
54 PTOKEN NewToken
= (PTOKEN
)NewTokenP
;
56 if (NewToken
->TokenType
!= TokenPrimary
)
58 return(STATUS_UNSUCCESSFUL
);
60 if (NewToken
->TokenInUse
!= 0)
62 return(STATUS_UNSUCCESSFUL
);
64 OldToken
= Process
->Token
;
65 Process
->Token
= NewToken
;
66 NewToken
->TokenInUse
= 1;
67 ObReferenceObjectByPointer(NewToken
,
71 OldToken
->TokenInUse
= 0;
72 *OldTokenP
= (PACCESS_TOKEN
)OldToken
;
73 return(STATUS_SUCCESS
);
77 RtlLengthSidAndAttributes(ULONG Count
,
78 PSID_AND_ATTRIBUTES Src
)
83 uLength
= Count
* sizeof(SID_AND_ATTRIBUTES
);
84 for (i
= 0; i
< Count
; i
++)
85 uLength
+= RtlLengthSid(Src
[i
].Sid
);
92 SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token
,
98 Token
->PrimaryGroup
= 0;
102 Token
->DefaultOwnerIndex
= Token
->UserAndGroupCount
;
105 /* Validate and set the primary group and user pointers */
106 for (i
= 0; i
< Token
->UserAndGroupCount
; i
++)
109 RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, DefaultOwner
))
111 Token
->DefaultOwnerIndex
= i
;
114 if (RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, PrimaryGroup
))
116 Token
->PrimaryGroup
= Token
->UserAndGroups
[i
].Sid
;
120 if (Token
->DefaultOwnerIndex
== Token
->UserAndGroupCount
)
122 return(STATUS_INVALID_OWNER
);
125 if (Token
->PrimaryGroup
== 0)
127 return(STATUS_INVALID_PRIMARY_GROUP
);
130 return(STATUS_SUCCESS
);
135 SepDuplicateToken(PTOKEN Token
,
136 POBJECT_ATTRIBUTES ObjectAttributes
,
137 BOOLEAN EffectiveOnly
,
138 TOKEN_TYPE TokenType
,
139 SECURITY_IMPERSONATION_LEVEL Level
,
140 KPROCESSOR_MODE PreviousMode
,
141 PTOKEN
* NewAccessToken
)
151 Status
= ObCreateObject(PreviousMode
,
159 (PVOID
*)&AccessToken
);
160 if (!NT_SUCCESS(Status
))
162 DPRINT1("ObCreateObject() failed (Status %lx)\n");
166 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->TokenId
);
167 if (!NT_SUCCESS(Status
))
169 ObDereferenceObject(AccessToken
);
173 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
174 if (!NT_SUCCESS(Status
))
176 ObDereferenceObject(AccessToken
);
180 AccessToken
->TokenInUse
= 0;
181 AccessToken
->TokenType
= TokenType
;
182 AccessToken
->ImpersonationLevel
= Level
;
183 RtlCopyLuid(&AccessToken
->AuthenticationId
, &Token
->AuthenticationId
);
185 AccessToken
->TokenSource
.SourceIdentifier
.LowPart
= Token
->TokenSource
.SourceIdentifier
.LowPart
;
186 AccessToken
->TokenSource
.SourceIdentifier
.HighPart
= Token
->TokenSource
.SourceIdentifier
.HighPart
;
187 memcpy(AccessToken
->TokenSource
.SourceName
,
188 Token
->TokenSource
.SourceName
,
189 sizeof(Token
->TokenSource
.SourceName
));
190 AccessToken
->ExpirationTime
.QuadPart
= Token
->ExpirationTime
.QuadPart
;
191 AccessToken
->UserAndGroupCount
= Token
->UserAndGroupCount
;
192 AccessToken
->DefaultOwnerIndex
= Token
->DefaultOwnerIndex
;
194 uLength
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
195 for (i
= 0; i
< Token
->UserAndGroupCount
; i
++)
196 uLength
+= RtlLengthSid(Token
->UserAndGroups
[i
].Sid
);
198 AccessToken
->UserAndGroups
=
199 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
201 TAG('T', 'O', 'K', 'u'));
203 EndMem
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
205 Status
= RtlCopySidAndAttributesArray(AccessToken
->UserAndGroupCount
,
206 Token
->UserAndGroups
,
208 AccessToken
->UserAndGroups
,
212 if (NT_SUCCESS(Status
))
214 Status
= SepFindPrimaryGroupAndDefaultOwner(
220 if (NT_SUCCESS(Status
))
222 AccessToken
->PrivilegeCount
= Token
->PrivilegeCount
;
224 uLength
= AccessToken
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
225 AccessToken
->Privileges
=
226 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
228 TAG('T', 'O', 'K', 'p'));
230 for (i
= 0; i
< AccessToken
->PrivilegeCount
; i
++)
232 RtlCopyLuid(&AccessToken
->Privileges
[i
].Luid
,
233 &Token
->Privileges
[i
].Luid
);
234 AccessToken
->Privileges
[i
].Attributes
=
235 Token
->Privileges
[i
].Attributes
;
238 if ( Token
->DefaultDacl
)
240 AccessToken
->DefaultDacl
=
241 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
242 Token
->DefaultDacl
->AclSize
,
243 TAG('T', 'O', 'K', 'd'));
244 memcpy(AccessToken
->DefaultDacl
,
246 Token
->DefaultDacl
->AclSize
);
250 AccessToken
->DefaultDacl
= 0;
254 if ( NT_SUCCESS(Status
) )
256 *NewAccessToken
= AccessToken
;
257 return(STATUS_SUCCESS
);
260 ObDereferenceObject(AccessToken
);
266 SepInitializeNewProcess(struct _EPROCESS
* NewProcess
,
267 struct _EPROCESS
* ParentProcess
)
273 OBJECT_ATTRIBUTES ObjectAttributes
;
275 pParentToken
= (PACCESS_TOKEN
) ParentProcess
->Token
;
277 InitializeObjectAttributes(&ObjectAttributes
,
283 Status
= SepDuplicateToken(pParentToken
,
287 pParentToken
->ImpersonationLevel
,
290 if ( ! NT_SUCCESS(Status
) )
293 NewProcess
->Token
= pNewToken
;
294 return(STATUS_SUCCESS
);
303 PACCESS_STATE AccessState
,
304 PPRIVILEGE_SET Privileges
308 return STATUS_NOT_IMPLEMENTED
;
313 SeCopyClientToken(PACCESS_TOKEN Token
,
314 SECURITY_IMPERSONATION_LEVEL Level
,
315 KPROCESSOR_MODE PreviousMode
,
316 PACCESS_TOKEN
* NewToken
)
319 OBJECT_ATTRIBUTES ObjectAttributes
;
321 InitializeObjectAttributes(&ObjectAttributes
,
326 Status
= SepDuplicateToken(Token
,
342 SeCreateClientSecurity(IN
struct _ETHREAD
*Thread
,
343 IN PSECURITY_QUALITY_OF_SERVICE Qos
,
344 IN BOOLEAN RemoteClient
,
345 OUT PSECURITY_CLIENT_CONTEXT ClientContext
)
347 TOKEN_TYPE TokenType
;
349 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
352 PACCESS_TOKEN NewToken
;
354 Token
= PsReferenceEffectiveToken(Thread
,
357 &ImpersonationLevel
);
358 if (TokenType
!= TokenImpersonation
)
360 ClientContext
->DirectAccessEffectiveOnly
= Qos
->EffectiveOnly
;
364 if (Qos
->ImpersonationLevel
> ImpersonationLevel
)
368 ObDereferenceObject(Token
);
370 return(STATUS_UNSUCCESSFUL
);
372 if (ImpersonationLevel
== SecurityAnonymous
||
373 ImpersonationLevel
== SecurityIdentification
||
374 (RemoteClient
!= FALSE
&& ImpersonationLevel
!= SecurityDelegation
))
378 ObDereferenceObject(Token
);
380 return(STATUS_UNSUCCESSFUL
);
383 Qos
->EffectiveOnly
!= 0)
385 ClientContext
->DirectAccessEffectiveOnly
= TRUE
;
389 ClientContext
->DirectAccessEffectiveOnly
= FALSE
;
393 if (Qos
->ContextTrackingMode
== 0)
395 ClientContext
->DirectlyAccessClientToken
= FALSE
;
396 g
= SeCopyClientToken(Token
, ImpersonationLevel
, 0, &NewToken
);
399 // ObDeleteCapturedInsertInfo(NewToken);
401 if (TokenType
== TokenPrimary
|| Token
!= NULL
)
403 ObDereferenceObject(Token
);
412 ClientContext
->DirectlyAccessClientToken
= TRUE
;
413 if (RemoteClient
!= FALSE
)
415 // SeGetTokenControlInformation(Token, &ClientContext->Unknown11);
419 ClientContext
->SecurityQos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
420 ClientContext
->SecurityQos
.ImpersonationLevel
= Qos
->ImpersonationLevel
;
421 ClientContext
->SecurityQos
.ContextTrackingMode
= Qos
->ContextTrackingMode
;
422 ClientContext
->SecurityQos
.EffectiveOnly
= Qos
->EffectiveOnly
;
423 ClientContext
->ServerIsRemote
= RemoteClient
;
424 ClientContext
->ClientToken
= NewToken
;
426 return(STATUS_SUCCESS
);
434 SeCreateClientSecurityFromSubjectContext(
435 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
436 IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos
,
437 IN BOOLEAN ServerIsRemote
,
438 OUT PSECURITY_CLIENT_CONTEXT ClientContext
442 return STATUS_NOT_IMPLEMENTED
;
451 IN PACCESS_TOKEN ExistingToken
,
453 IN PTOKEN_GROUPS SidsToDisable OPTIONAL
,
454 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL
,
455 IN PTOKEN_GROUPS RestrictedSids OPTIONAL
,
456 OUT PACCESS_TOKEN
* FilteredToken
460 return STATUS_NOT_IMPLEMENTED
;
469 IN PPRIVILEGE_SET Privileges
481 SeImpersonateClientEx(
482 IN PSECURITY_CLIENT_CONTEXT ClientContext
,
483 IN PETHREAD ServerThread OPTIONAL
487 return STATUS_NOT_IMPLEMENTED
;
494 SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext
,
495 IN PETHREAD ServerThread OPTIONAL
)
499 if (ClientContext
->DirectlyAccessClientToken
== FALSE
)
501 b
= ClientContext
->SecurityQos
.EffectiveOnly
;
505 b
= ClientContext
->DirectAccessEffectiveOnly
;
507 if (ServerThread
== NULL
)
509 ServerThread
= PsGetCurrentThread();
511 PsImpersonateClient(ServerThread
,
512 ClientContext
->ClientToken
,
515 ClientContext
->SecurityQos
.ImpersonationLevel
);
520 SepDeleteToken(PVOID ObjectBody
)
522 PTOKEN AccessToken
= (PTOKEN
)ObjectBody
;
524 if (AccessToken
->UserAndGroups
)
525 ExFreePool(AccessToken
->UserAndGroups
);
527 if (AccessToken
->Privileges
)
528 ExFreePool(AccessToken
->Privileges
);
530 if (AccessToken
->DefaultDacl
)
531 ExFreePool(AccessToken
->DefaultDacl
);
536 SepInitializeTokenImplementation(VOID
)
538 SepTokenObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
540 SepTokenObjectType
->Tag
= TAG('T', 'O', 'K', 'T');
541 SepTokenObjectType
->MaxObjects
= ULONG_MAX
;
542 SepTokenObjectType
->MaxHandles
= ULONG_MAX
;
543 SepTokenObjectType
->TotalObjects
= 0;
544 SepTokenObjectType
->TotalHandles
= 0;
545 SepTokenObjectType
->PagedPoolCharge
= 0;
546 SepTokenObjectType
->NonpagedPoolCharge
= sizeof(TOKEN
);
547 SepTokenObjectType
->Mapping
= &SepTokenMapping
;
548 SepTokenObjectType
->Dump
= NULL
;
549 SepTokenObjectType
->Open
= NULL
;
550 SepTokenObjectType
->Close
= NULL
;
551 SepTokenObjectType
->Delete
= SepDeleteToken
;
552 SepTokenObjectType
->Parse
= NULL
;
553 SepTokenObjectType
->Security
= NULL
;
554 SepTokenObjectType
->QueryName
= NULL
;
555 SepTokenObjectType
->OkayToClose
= NULL
;
556 SepTokenObjectType
->Create
= NULL
;
557 SepTokenObjectType
->DuplicationNotify
= NULL
;
559 RtlCreateUnicodeString(&SepTokenObjectType
->TypeName
,
561 ObpCreateTypeObject (SepTokenObjectType
);
569 NtQueryInformationToken(IN HANDLE TokenHandle
,
570 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
571 OUT PVOID TokenInformation
,
572 IN ULONG TokenInformationLength
,
573 OUT PULONG ReturnLength
)
575 NTSTATUS Status
, LengthStatus
;
580 PTOKEN_GROUPS PtrTokenGroups
;
581 PTOKEN_DEFAULT_DACL PtrDefaultDacl
;
582 PTOKEN_STATISTICS PtrTokenStatistics
;
584 Status
= ObReferenceObjectByHandle(TokenHandle
,
585 (TokenInformationClass
== TokenSource
) ? TOKEN_QUERY_SOURCE
: TOKEN_QUERY
,
590 if (!NT_SUCCESS(Status
))
595 switch (TokenInformationClass
)
598 DPRINT("NtQueryInformationToken(TokenUser)\n");
599 Length
= RtlLengthSidAndAttributes(1, Token
->UserAndGroups
);
600 if (TokenInformationLength
< Length
)
602 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
603 if (NT_SUCCESS(Status
))
604 Status
= STATUS_BUFFER_TOO_SMALL
;
608 Status
= RtlCopySidAndAttributesArray(1,
609 Token
->UserAndGroups
,
610 TokenInformationLength
,
612 (char*)TokenInformation
+ 8,
615 if (NT_SUCCESS(Status
))
617 Length
= TokenInformationLength
- Length
;
618 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
624 DPRINT("NtQueryInformationToken(TokenGroups)\n");
625 Length
= RtlLengthSidAndAttributes(Token
->UserAndGroupCount
- 1, &Token
->UserAndGroups
[1]) + sizeof(ULONG
);
626 if (TokenInformationLength
< Length
)
628 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
629 if (NT_SUCCESS(Status
))
630 Status
= STATUS_BUFFER_TOO_SMALL
;
634 EndMem
= (char*)TokenInformation
+ Token
->UserAndGroupCount
* sizeof(SID_AND_ATTRIBUTES
);
635 PtrTokenGroups
= (PTOKEN_GROUPS
)TokenInformation
;
636 PtrTokenGroups
->GroupCount
= Token
->UserAndGroupCount
- 1;
637 Status
= RtlCopySidAndAttributesArray(Token
->UserAndGroupCount
- 1,
638 &Token
->UserAndGroups
[1],
639 TokenInformationLength
,
640 PtrTokenGroups
->Groups
,
644 if (NT_SUCCESS(Status
))
646 Length
= TokenInformationLength
- Length
;
647 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
652 case TokenPrivileges
:
653 DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
654 Length
= sizeof(ULONG
) + Token
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
655 if (TokenInformationLength
< Length
)
657 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
658 if (NT_SUCCESS(Status
))
659 Status
= STATUS_BUFFER_TOO_SMALL
;
664 TOKEN_PRIVILEGES
* pPriv
= (TOKEN_PRIVILEGES
*)TokenInformation
;
666 pPriv
->PrivilegeCount
= Token
->PrivilegeCount
;
667 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
669 RtlCopyLuid(&pPriv
->Privileges
[i
].Luid
, &Token
->Privileges
[i
].Luid
);
670 pPriv
->Privileges
[i
].Attributes
= Token
->Privileges
[i
].Attributes
;
672 Status
= STATUS_SUCCESS
;
677 DPRINT("NtQueryInformationToken(TokenOwner)\n");
678 Length
= RtlLengthSid(Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
) + sizeof(TOKEN_OWNER
);
679 if (TokenInformationLength
< Length
)
681 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
682 if (NT_SUCCESS(Status
))
683 Status
= STATUS_BUFFER_TOO_SMALL
;
687 ((PTOKEN_OWNER
)TokenInformation
)->Owner
=
688 (PSID
)(((PTOKEN_OWNER
)TokenInformation
) + 1);
689 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
690 ((PTOKEN_OWNER
)TokenInformation
)->Owner
,
691 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
);
692 Status
= STATUS_SUCCESS
;
696 case TokenPrimaryGroup
:
697 DPRINT("NtQueryInformationToken(TokenPrimaryGroup),"
698 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
699 Length
= RtlLengthSid(Token
->PrimaryGroup
) + sizeof(TOKEN_PRIMARY_GROUP
);
700 if (TokenInformationLength
< Length
)
702 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
703 if (NT_SUCCESS(Status
))
704 Status
= STATUS_BUFFER_TOO_SMALL
;
708 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
=
709 (PSID
)(((PTOKEN_PRIMARY_GROUP
)TokenInformation
) + 1);
710 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
711 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
,
712 Token
->PrimaryGroup
);
713 Status
= STATUS_SUCCESS
;
717 case TokenDefaultDacl
:
718 DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
719 PtrDefaultDacl
= (PTOKEN_DEFAULT_DACL
) TokenInformation
;
720 Length
= (Token
->DefaultDacl
? Token
->DefaultDacl
->AclSize
: 0) + sizeof(TOKEN_DEFAULT_DACL
);
721 if (TokenInformationLength
< Length
)
723 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
724 if (NT_SUCCESS(Status
))
725 Status
= STATUS_BUFFER_TOO_SMALL
;
727 else if (!Token
->DefaultDacl
)
729 PtrDefaultDacl
->DefaultDacl
= 0;
730 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
734 PtrDefaultDacl
->DefaultDacl
= (PACL
) (PtrDefaultDacl
+ 1);
735 memmove(PtrDefaultDacl
->DefaultDacl
,
737 Token
->DefaultDacl
->AclSize
);
738 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
743 DPRINT("NtQueryInformationToken(TokenSource)\n");
744 if (TokenInformationLength
< sizeof(TOKEN_SOURCE
))
746 Length
= sizeof(TOKEN_SOURCE
);
747 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
748 if (NT_SUCCESS(Status
))
749 Status
= STATUS_BUFFER_TOO_SMALL
;
753 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenSource
, sizeof(TOKEN_SOURCE
));
758 DPRINT("NtQueryInformationToken(TokenType)\n");
759 if (TokenInformationLength
< sizeof(TOKEN_TYPE
))
761 Length
= sizeof(TOKEN_TYPE
);
762 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
763 if (NT_SUCCESS(Status
))
764 Status
= STATUS_BUFFER_TOO_SMALL
;
768 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenType
, sizeof(TOKEN_TYPE
));
772 case TokenImpersonationLevel
:
773 DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
774 if (TokenInformationLength
< sizeof(SECURITY_IMPERSONATION_LEVEL
))
776 Length
= sizeof(SECURITY_IMPERSONATION_LEVEL
);
777 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
778 if (NT_SUCCESS(Status
))
779 Status
= STATUS_BUFFER_TOO_SMALL
;
783 Status
= MmCopyToCaller(TokenInformation
, &Token
->ImpersonationLevel
, sizeof(SECURITY_IMPERSONATION_LEVEL
));
787 case TokenStatistics
:
788 DPRINT("NtQueryInformationToken(TokenStatistics)\n");
789 if (TokenInformationLength
< sizeof(TOKEN_STATISTICS
))
791 Length
= sizeof(TOKEN_STATISTICS
);
792 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
793 if (NT_SUCCESS(Status
))
794 Status
= STATUS_BUFFER_TOO_SMALL
;
798 PtrTokenStatistics
= (PTOKEN_STATISTICS
)TokenInformation
;
799 PtrTokenStatistics
->TokenId
= Token
->TokenId
;
800 PtrTokenStatistics
->AuthenticationId
= Token
->AuthenticationId
;
801 PtrTokenStatistics
->ExpirationTime
= Token
->ExpirationTime
;
802 PtrTokenStatistics
->TokenType
= Token
->TokenType
;
803 PtrTokenStatistics
->ImpersonationLevel
= Token
->ImpersonationLevel
;
804 PtrTokenStatistics
->DynamicCharged
= Token
->DynamicCharged
;
805 PtrTokenStatistics
->DynamicAvailable
= Token
->DynamicAvailable
;
806 PtrTokenStatistics
->GroupCount
= Token
->UserAndGroupCount
- 1;
807 PtrTokenStatistics
->PrivilegeCount
= Token
->PrivilegeCount
;
808 PtrTokenStatistics
->ModifiedId
= Token
->ModifiedId
;
810 Status
= STATUS_SUCCESS
;
815 DPRINT("NtQueryInformationToken(TokenOrigin)\n");
816 if (TokenInformationLength
< sizeof(TOKEN_ORIGIN
))
818 Status
= STATUS_BUFFER_TOO_SMALL
;
822 Status
= MmCopyToCaller(&((PTOKEN_ORIGIN
)TokenInformation
)->OriginatingLogonSession
,
823 &Token
->AuthenticationId
, sizeof(LUID
));
825 Length
= sizeof(TOKEN_ORIGIN
);
826 LengthStatus
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
827 if (NT_SUCCESS(Status
))
829 Status
= LengthStatus
;
833 case TokenGroupsAndPrivileges
:
834 DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
835 Status
= STATUS_NOT_IMPLEMENTED
;
838 case TokenRestrictedSids
:
839 DPRINT1("NtQueryInformationToken(TokenRestrictedSids) not implemented\n");
840 Status
= STATUS_NOT_IMPLEMENTED
;
843 case TokenSandBoxInert
:
844 DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n");
845 Status
= STATUS_NOT_IMPLEMENTED
;
849 DPRINT1("NtQueryInformationToken(TokenSessionId) not implemented\n");
850 Status
= STATUS_NOT_IMPLEMENTED
;
854 DPRINT1("NtQueryInformationToken(%d) invalid parameter\n");
855 Status
= STATUS_INVALID_PARAMETER
;
859 ObDereferenceObject(Token
);
869 SeQueryInformationToken(
870 IN PACCESS_TOKEN Token
,
871 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
872 OUT PVOID
*TokenInformation
876 return STATUS_NOT_IMPLEMENTED
;
884 SeQuerySessionIdToken(
885 IN PACCESS_TOKEN Token
,
890 return STATUS_NOT_IMPLEMENTED
;
894 * NtSetTokenInformation: Partly implemented.
896 * TokenOrigin, TokenDefaultDacl, TokenSessionId
900 NtSetInformationToken(IN HANDLE TokenHandle
,
901 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
902 OUT PVOID TokenInformation
,
903 IN ULONG TokenInformationLength
)
907 TOKEN_OWNER TokenOwnerSet
= { 0 };
908 TOKEN_PRIMARY_GROUP TokenPrimaryGroupSet
= { 0 };
909 DWORD NeededAccess
= 0;
911 switch (TokenInformationClass
)
914 case TokenPrimaryGroup
:
915 NeededAccess
= TOKEN_ADJUST_DEFAULT
;
918 case TokenDefaultDacl
:
919 if (TokenInformationLength
< sizeof(TOKEN_DEFAULT_DACL
))
920 return STATUS_BUFFER_TOO_SMALL
;
921 NeededAccess
= TOKEN_ADJUST_DEFAULT
;
925 DPRINT1("NtSetInformationToken: lying about success (stub) - %x\n", TokenInformationClass
);
926 return STATUS_SUCCESS
;
930 Status
= ObReferenceObjectByHandle(TokenHandle
,
936 if (!NT_SUCCESS(Status
))
941 switch (TokenInformationClass
)
944 MmCopyFromCaller( &TokenOwnerSet
, TokenInformation
,
945 min(sizeof(TokenOwnerSet
),TokenInformationLength
) );
946 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
947 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
,
948 TokenOwnerSet
.Owner
);
949 Status
= STATUS_SUCCESS
;
950 DPRINT("NtSetInformationToken(TokenOwner)\n");
953 case TokenPrimaryGroup
:
954 MmCopyFromCaller( &TokenPrimaryGroupSet
, TokenInformation
,
955 min(sizeof(TokenPrimaryGroupSet
),
956 TokenInformationLength
) );
957 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
959 TokenPrimaryGroupSet
.PrimaryGroup
);
960 Status
= STATUS_SUCCESS
;
961 DPRINT("NtSetInformationToken(TokenPrimaryGroup),"
962 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
965 case TokenDefaultDacl
:
967 TOKEN_DEFAULT_DACL TokenDefaultDacl
= { 0 };
971 Status
= MmCopyFromCaller( &TokenDefaultDacl
, TokenInformation
,
972 sizeof(TOKEN_DEFAULT_DACL
) );
973 if (!NT_SUCCESS(Status
))
975 Status
= STATUS_INVALID_PARAMETER
;
979 Status
= MmCopyFromCaller( &OldAcl
, TokenDefaultDacl
.DefaultDacl
,
981 if (!NT_SUCCESS(Status
))
983 Status
= STATUS_INVALID_PARAMETER
;
987 NewAcl
= ExAllocatePool(NonPagedPool
, sizeof(ACL
));
990 Status
= STATUS_INSUFFICIENT_RESOURCES
;
994 Status
= MmCopyFromCaller( NewAcl
, TokenDefaultDacl
.DefaultDacl
,
996 if (!NT_SUCCESS(Status
))
998 Status
= STATUS_INVALID_PARAMETER
;
1003 if (Token
->DefaultDacl
)
1005 ExFreePool(Token
->DefaultDacl
);
1008 Token
->DefaultDacl
= NewAcl
;
1010 Status
= STATUS_SUCCESS
;
1015 Status
= STATUS_NOT_IMPLEMENTED
;
1019 ObDereferenceObject(Token
);
1028 * NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
1029 * this is certainly NOT true, thou i can't say for sure that EffectiveOnly
1030 * is correct either. -Gunnar
1033 NtDuplicateToken(IN HANDLE ExistingTokenHandle
,
1034 IN ACCESS_MASK DesiredAccess
,
1035 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
/*is it really optional?*/,
1036 IN BOOLEAN EffectiveOnly
,
1037 IN TOKEN_TYPE TokenType
,
1038 OUT PHANDLE NewTokenHandle
)
1040 KPROCESSOR_MODE PreviousMode
;
1045 PreviousMode
= KeGetPreviousMode();
1046 Status
= ObReferenceObjectByHandle(ExistingTokenHandle
,
1052 if (!NT_SUCCESS(Status
))
1054 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
1058 Status
= SepDuplicateToken(Token
,
1062 ObjectAttributes
->SecurityQualityOfService
?
1063 ObjectAttributes
->SecurityQualityOfService
->ImpersonationLevel
:
1064 0 /*SecurityAnonymous*/,
1068 ObDereferenceObject(Token
);
1070 if (!NT_SUCCESS(Status
))
1072 DPRINT1("Failed to duplicate token (Status %lx)\n", Status
);
1076 Status
= ObInsertObject((PVOID
)NewToken
,
1083 ObDereferenceObject(NewToken
);
1085 if (!NT_SUCCESS(Status
))
1087 DPRINT1("Failed to create token handle (Status %lx)\n");
1091 return STATUS_SUCCESS
;
1095 VOID
SepAdjustGroups(PACCESS_TOKEN Token
,
1097 BOOLEAN ResetToDefault
,
1098 PSID_AND_ATTRIBUTES Groups
,
1100 KPROCESSOR_MODE PreviousMode
,
1111 NtAdjustGroupsToken(IN HANDLE TokenHandle
,
1112 IN BOOLEAN ResetToDefault
,
1113 IN PTOKEN_GROUPS NewState
,
1114 IN ULONG BufferLength
,
1115 OUT PTOKEN_GROUPS PreviousState OPTIONAL
,
1116 OUT PULONG ReturnLength
)
1120 PACCESS_TOKEN Token
;
1125 Status
= ObReferenceObjectByHandle(TokenHandle
,
1133 SepAdjustGroups(Token
,
1145 return(STATUS_NOT_IMPLEMENTED
);
1152 SepAdjustPrivileges(PACCESS_TOKEN Token
,
1154 KPROCESSOR_MODE PreviousMode
,
1155 ULONG PrivilegeCount
,
1156 PLUID_AND_ATTRIBUTES Privileges
,
1157 PTOKEN_PRIVILEGES
* PreviousState
,
1166 if (Token
->PrivilegeCount
> 0)
1168 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1170 if (PreviousMode
!= KernelMode
)
1172 if (Token
->Privileges
[i
]->Attributes
& SE_PRIVILEGE_ENABLED
== 0)
1176 if (PreviousState
!= NULL
)
1178 memcpy(&PreviousState
[i
],
1179 &Token
->Privileges
[i
],
1180 sizeof(LUID_AND_ATTRIBUTES
));
1182 Token
->Privileges
[i
].Attributes
&= (~SE_PRIVILEGE_ENABLED
);
1189 if (PreviousMode
!= KernelMode
)
1191 Token
->TokenFlags
= Token
->TokenFlags
& (~1);
1195 if (PrivilegeCount
<= ?)
1208 NtAdjustPrivilegesToken (IN HANDLE TokenHandle
,
1209 IN BOOLEAN DisableAllPrivileges
,
1210 IN PTOKEN_PRIVILEGES NewState
,
1211 IN ULONG BufferLength
,
1212 OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL
,
1213 OUT PULONG ReturnLength OPTIONAL
)
1215 // PLUID_AND_ATTRIBUTES Privileges;
1216 KPROCESSOR_MODE PreviousMode
;
1217 // ULONG PrivilegeCount;
1231 DPRINT ("NtAdjustPrivilegesToken() called\n");
1233 // PrivilegeCount = NewState->PrivilegeCount;
1234 PreviousMode
= KeGetPreviousMode ();
1235 // SeCaptureLuidAndAttributesArray(NewState->Privileges,
1245 Status
= ObReferenceObjectByHandle (TokenHandle
,
1246 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1251 if (!NT_SUCCESS(Status
))
1253 DPRINT1 ("Failed to reference token (Status %lx)\n", Status
);
1254 // SeReleaseLuidAndAttributesArray(Privileges,
1262 SepAdjustPrivileges(Token
,
1274 if (DisableAllPrivileges
== TRUE
)
1276 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1278 if (Token
->Privileges
[i
].Attributes
!= 0)
1280 DPRINT ("Attributes differ\n");
1282 /* Save current privilege */
1283 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1285 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1286 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1290 /* Update current privlege */
1291 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1294 Status
= STATUS_SUCCESS
;
1299 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1301 for (j
= 0; j
< NewState
->PrivilegeCount
; j
++)
1303 if (Token
->Privileges
[i
].Luid
.LowPart
== NewState
->Privileges
[j
].Luid
.LowPart
&&
1304 Token
->Privileges
[i
].Luid
.HighPart
== NewState
->Privileges
[j
].Luid
.HighPart
)
1306 DPRINT ("Found privilege\n");
1308 if ((Token
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
) !=
1309 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
))
1311 DPRINT ("Attributes differ\n");
1312 DPRINT ("Current attributes %lx desired attributes %lx\n",
1313 Token
->Privileges
[i
].Attributes
,
1314 NewState
->Privileges
[j
].Attributes
);
1316 /* Save current privilege */
1317 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1319 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1320 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1324 /* Update current privlege */
1325 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1326 Token
->Privileges
[i
].Attributes
|=
1327 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
);
1328 DPRINT ("New attributes %lx\n",
1329 Token
->Privileges
[i
].Attributes
);
1335 Status
= Count
< NewState
->PrivilegeCount
? STATUS_NOT_ALL_ASSIGNED
: STATUS_SUCCESS
;
1338 if (ReturnLength
!= NULL
)
1340 *ReturnLength
= sizeof(TOKEN_PRIVILEGES
) +
1341 (sizeof(LUID_AND_ATTRIBUTES
) * (k
- 1));
1344 ObDereferenceObject (Token
);
1346 // SeReleaseLuidAndAttributesArray(Privileges,
1350 DPRINT ("NtAdjustPrivilegesToken() done\n");
1357 SepCreateSystemProcessToken(struct _EPROCESS
* Process
)
1363 ULONG uLocalSystemLength
= RtlLengthSid(SeLocalSystemSid
);
1364 ULONG uWorldLength
= RtlLengthSid(SeWorldSid
);
1365 ULONG uAuthUserLength
= RtlLengthSid(SeAuthenticatedUserSid
);
1366 ULONG uAdminsLength
= RtlLengthSid(SeAliasAdminsSid
);
1373 * Initialize the token
1375 Status
= ObCreateObject(KernelMode
,
1383 (PVOID
*)&AccessToken
);
1384 if (!NT_SUCCESS(Status
))
1389 Status
= NtAllocateLocallyUniqueId(&AccessToken
->TokenId
);
1390 if (!NT_SUCCESS(Status
))
1392 ObDereferenceObject(AccessToken
);
1396 Status
= NtAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
1397 if (!NT_SUCCESS(Status
))
1399 ObDereferenceObject(AccessToken
);
1403 Status
= NtAllocateLocallyUniqueId(&AccessToken
->AuthenticationId
);
1404 if (!NT_SUCCESS(Status
))
1406 ObDereferenceObject(AccessToken
);
1410 AccessToken
->TokenType
= TokenPrimary
;
1411 AccessToken
->ImpersonationLevel
= SecurityDelegation
;
1412 AccessToken
->TokenSource
.SourceIdentifier
.LowPart
= 0;
1413 AccessToken
->TokenSource
.SourceIdentifier
.HighPart
= 0;
1414 memcpy(AccessToken
->TokenSource
.SourceName
, "SeMgr\0\0\0", 8);
1415 AccessToken
->ExpirationTime
.QuadPart
= -1;
1416 AccessToken
->UserAndGroupCount
= 4;
1418 uSize
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1419 uSize
+= uLocalSystemLength
;
1420 uSize
+= uWorldLength
;
1421 uSize
+= uAuthUserLength
;
1422 uSize
+= uAdminsLength
;
1424 AccessToken
->UserAndGroups
=
1425 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1427 TAG('T', 'O', 'K', 'u'));
1428 SidArea
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1431 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1432 AccessToken
->UserAndGroups
[i
++].Attributes
= 0;
1433 RtlCopySid(uLocalSystemLength
, SidArea
, SeLocalSystemSid
);
1434 SidArea
= (char*)SidArea
+ uLocalSystemLength
;
1436 AccessToken
->DefaultOwnerIndex
= i
;
1437 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1438 AccessToken
->PrimaryGroup
= (PSID
) SidArea
;
1439 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
;
1440 Status
= RtlCopySid(uAdminsLength
, SidArea
, SeAliasAdminsSid
);
1441 SidArea
= (char*)SidArea
+ uAdminsLength
;
1443 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1444 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1445 RtlCopySid(uWorldLength
, SidArea
, SeWorldSid
);
1446 SidArea
= (char*)SidArea
+ uWorldLength
;
1448 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1449 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1450 RtlCopySid(uAuthUserLength
, SidArea
, SeAuthenticatedUserSid
);
1451 SidArea
= (char*)SidArea
+ uAuthUserLength
;
1453 AccessToken
->PrivilegeCount
= 20;
1455 uSize
= AccessToken
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1456 AccessToken
->Privileges
=
1457 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1459 TAG('T', 'O', 'K', 'p'));
1462 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1463 AccessToken
->Privileges
[i
++].Luid
= SeTcbPrivilege
;
1465 AccessToken
->Privileges
[i
].Attributes
= 0;
1466 AccessToken
->Privileges
[i
++].Luid
= SeCreateTokenPrivilege
;
1468 AccessToken
->Privileges
[i
].Attributes
= 0;
1469 AccessToken
->Privileges
[i
++].Luid
= SeTakeOwnershipPrivilege
;
1471 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1472 AccessToken
->Privileges
[i
++].Luid
= SeCreatePagefilePrivilege
;
1474 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1475 AccessToken
->Privileges
[i
++].Luid
= SeLockMemoryPrivilege
;
1477 AccessToken
->Privileges
[i
].Attributes
= 0;
1478 AccessToken
->Privileges
[i
++].Luid
= SeAssignPrimaryTokenPrivilege
;
1480 AccessToken
->Privileges
[i
].Attributes
= 0;
1481 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseQuotaPrivilege
;
1483 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1484 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseBasePriorityPrivilege
;
1486 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1487 AccessToken
->Privileges
[i
++].Luid
= SeCreatePermanentPrivilege
;
1489 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1490 AccessToken
->Privileges
[i
++].Luid
= SeDebugPrivilege
;
1492 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1493 AccessToken
->Privileges
[i
++].Luid
= SeAuditPrivilege
;
1495 AccessToken
->Privileges
[i
].Attributes
= 0;
1496 AccessToken
->Privileges
[i
++].Luid
= SeSecurityPrivilege
;
1498 AccessToken
->Privileges
[i
].Attributes
= 0;
1499 AccessToken
->Privileges
[i
++].Luid
= SeSystemEnvironmentPrivilege
;
1501 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1502 AccessToken
->Privileges
[i
++].Luid
= SeChangeNotifyPrivilege
;
1504 AccessToken
->Privileges
[i
].Attributes
= 0;
1505 AccessToken
->Privileges
[i
++].Luid
= SeBackupPrivilege
;
1507 AccessToken
->Privileges
[i
].Attributes
= 0;
1508 AccessToken
->Privileges
[i
++].Luid
= SeRestorePrivilege
;
1510 AccessToken
->Privileges
[i
].Attributes
= 0;
1511 AccessToken
->Privileges
[i
++].Luid
= SeShutdownPrivilege
;
1513 AccessToken
->Privileges
[i
].Attributes
= 0;
1514 AccessToken
->Privileges
[i
++].Luid
= SeLoadDriverPrivilege
;
1516 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1517 AccessToken
->Privileges
[i
++].Luid
= SeProfileSingleProcessPrivilege
;
1519 AccessToken
->Privileges
[i
].Attributes
= 0;
1520 AccessToken
->Privileges
[i
++].Luid
= SeSystemtimePrivilege
;
1522 AccessToken
->Privileges
[i
].Attributes
= 0;
1523 AccessToken
->Privileges
[i
++].Luid
= SeUndockPrivilege
;
1525 AccessToken
->Privileges
[i
].Attributes
= 0;
1526 AccessToken
->Privileges
[i
++].Luid
= SeManageVolumePrivilege
;
1531 uSize
= sizeof(ACL
);
1532 uSize
+= sizeof(ACE
) + uLocalSystemLength
;
1533 uSize
+= sizeof(ACE
) + uAdminsLength
;
1534 uSize
= (uSize
& (~3)) + 8;
1535 AccessToken
->DefaultDacl
=
1536 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1538 TAG('T', 'O', 'K', 'd'));
1539 Status
= RtlCreateAcl(AccessToken
->DefaultDacl
, uSize
, ACL_REVISION
);
1540 if ( NT_SUCCESS(Status
) )
1542 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_ALL
, SeLocalSystemSid
);
1545 if ( NT_SUCCESS(Status
) )
1547 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_READ
|GENERIC_EXECUTE
|READ_CONTROL
, SeAliasAdminsSid
);
1550 if ( ! NT_SUCCESS(Status
) )
1552 ObDereferenceObject(AccessToken
);
1556 Process
->Token
= AccessToken
;
1557 return(STATUS_SUCCESS
);
1562 NtCreateToken(OUT PHANDLE UnsafeTokenHandle
,
1563 IN ACCESS_MASK DesiredAccess
,
1564 IN POBJECT_ATTRIBUTES UnsafeObjectAttributes
,
1565 IN TOKEN_TYPE TokenType
,
1566 IN PLUID AuthenticationId
,
1567 IN PLARGE_INTEGER ExpirationTime
,
1568 IN PTOKEN_USER TokenUser
,
1569 IN PTOKEN_GROUPS TokenGroups
,
1570 IN PTOKEN_PRIVILEGES TokenPrivileges
,
1571 IN PTOKEN_OWNER TokenOwner
,
1572 IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup
,
1573 IN PTOKEN_DEFAULT_DACL TokenDefaultDacl
,
1574 IN PTOKEN_SOURCE TokenSource
)
1579 OBJECT_ATTRIBUTES SafeObjectAttributes
;
1580 POBJECT_ATTRIBUTES ObjectAttributes
;
1587 Status
= MmCopyFromCaller(&SafeObjectAttributes
,
1588 UnsafeObjectAttributes
,
1589 sizeof(OBJECT_ATTRIBUTES
));
1590 if (!NT_SUCCESS(Status
))
1593 ObjectAttributes
= &SafeObjectAttributes
;
1595 Status
= ZwAllocateLocallyUniqueId(&TokenId
);
1596 if (!NT_SUCCESS(Status
))
1599 Status
= ZwAllocateLocallyUniqueId(&ModifiedId
);
1600 if (!NT_SUCCESS(Status
))
1603 Status
= ObCreateObject(ExGetPreviousMode(),
1606 ExGetPreviousMode(),
1611 (PVOID
*)&AccessToken
);
1612 if (!NT_SUCCESS(Status
))
1614 DPRINT1("ObCreateObject() failed (Status %lx)\n");
1618 Status
= ObInsertObject ((PVOID
)AccessToken
,
1624 if (!NT_SUCCESS(Status
))
1626 DPRINT1("ObInsertObject() failed (Status %lx)\n");
1627 ObDereferenceObject (AccessToken
);
1631 RtlCopyLuid(&AccessToken
->TokenSource
.SourceIdentifier
,
1632 &TokenSource
->SourceIdentifier
);
1633 memcpy(AccessToken
->TokenSource
.SourceName
,
1634 TokenSource
->SourceName
,
1635 sizeof(TokenSource
->SourceName
));
1637 RtlCopyLuid(&AccessToken
->TokenId
, &TokenId
);
1638 RtlCopyLuid(&AccessToken
->AuthenticationId
, AuthenticationId
);
1639 AccessToken
->ExpirationTime
= *ExpirationTime
;
1640 RtlCopyLuid(&AccessToken
->ModifiedId
, &ModifiedId
);
1642 AccessToken
->UserAndGroupCount
= TokenGroups
->GroupCount
+ 1;
1643 AccessToken
->PrivilegeCount
= TokenPrivileges
->PrivilegeCount
;
1644 AccessToken
->UserAndGroups
= 0;
1645 AccessToken
->Privileges
= 0;
1647 AccessToken
->TokenType
= TokenType
;
1648 AccessToken
->ImpersonationLevel
= ObjectAttributes
->SecurityQualityOfService
->ImpersonationLevel
;
1651 * Normally we would just point these members into the variable information
1652 * area; however, our ObCreateObject() call can't allocate a variable information
1653 * area, so we allocate them seperately and provide a destroy function.
1656 uLength
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1657 uLength
+= RtlLengthSid(TokenUser
->User
.Sid
);
1658 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
1659 uLength
+= RtlLengthSid(TokenGroups
->Groups
[i
].Sid
);
1661 AccessToken
->UserAndGroups
=
1662 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1664 TAG('T', 'O', 'K', 'u'));
1666 EndMem
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1668 Status
= RtlCopySidAndAttributesArray(1,
1671 AccessToken
->UserAndGroups
,
1675 if (NT_SUCCESS(Status
))
1677 Status
= RtlCopySidAndAttributesArray(TokenGroups
->GroupCount
,
1678 TokenGroups
->Groups
,
1680 &AccessToken
->UserAndGroups
[1],
1686 if (NT_SUCCESS(Status
))
1688 Status
= SepFindPrimaryGroupAndDefaultOwner(
1690 TokenPrimaryGroup
->PrimaryGroup
,
1694 if (NT_SUCCESS(Status
))
1696 uLength
= TokenPrivileges
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1697 AccessToken
->Privileges
=
1698 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1700 TAG('T', 'O', 'K', 'p'));
1702 for (i
= 0; i
< TokenPrivileges
->PrivilegeCount
; i
++)
1704 Status
= MmCopyFromCaller(&AccessToken
->Privileges
[i
],
1705 &TokenPrivileges
->Privileges
[i
],
1706 sizeof(LUID_AND_ATTRIBUTES
));
1707 if (!NT_SUCCESS(Status
))
1712 if (NT_SUCCESS(Status
))
1714 AccessToken
->DefaultDacl
=
1715 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1716 TokenDefaultDacl
->DefaultDacl
->AclSize
,
1717 TAG('T', 'O', 'K', 'd'));
1718 memcpy(AccessToken
->DefaultDacl
,
1719 TokenDefaultDacl
->DefaultDacl
,
1720 TokenDefaultDacl
->DefaultDacl
->AclSize
);
1723 ObDereferenceObject(AccessToken
);
1725 if (NT_SUCCESS(Status
))
1727 Status
= MmCopyToCaller(UnsafeTokenHandle
,
1732 if (!NT_SUCCESS(Status
))
1734 ZwClose(TokenHandle
);
1738 return(STATUS_SUCCESS
);
1746 SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token
,
1749 *LogonId
= ((PTOKEN
)Token
)->AuthenticationId
;
1751 return STATUS_SUCCESS
;
1758 SECURITY_IMPERSONATION_LEVEL
1760 SeTokenImpersonationLevel(IN PACCESS_TOKEN Token
)
1762 return ((PTOKEN
)Token
)->ImpersonationLevel
;
1770 SeTokenType(IN PACCESS_TOKEN Token
)
1772 return ((PTOKEN
)Token
)->TokenType
;
1782 IN PACCESS_TOKEN Token
1794 SeTokenIsRestricted(
1795 IN PACCESS_TOKEN Token
1807 SeTokenIsWriteRestricted(
1808 IN PACCESS_TOKEN Token
1821 NtOpenThreadTokenEx(IN HANDLE ThreadHandle
,
1822 IN ACCESS_MASK DesiredAccess
,
1823 IN BOOLEAN OpenAsSelf
,
1824 IN ULONG HandleAttributes
,
1825 OUT PHANDLE TokenHandle
)
1828 PTOKEN Token
, NewToken
, PrimaryToken
;
1829 BOOLEAN CopyOnOpen
, EffectiveOnly
;
1830 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
1831 SE_IMPERSONATION_STATE ImpersonationState
;
1832 OBJECT_ATTRIBUTES ObjectAttributes
;
1833 SECURITY_DESCRIPTOR SecurityDescriptor
;
1838 * At first open the thread token for information access and verify
1839 * that the token associated with thread is valid.
1842 Status
= ObReferenceObjectByHandle(ThreadHandle
, THREAD_QUERY_INFORMATION
,
1843 PsThreadType
, UserMode
, (PVOID
*)&Thread
,
1845 if (!NT_SUCCESS(Status
))
1850 Token
= PsReferenceImpersonationToken(Thread
, &CopyOnOpen
, &EffectiveOnly
,
1851 &ImpersonationLevel
);
1854 ObfDereferenceObject(Thread
);
1855 return STATUS_NO_TOKEN
;
1858 ObDereferenceObject(Thread
);
1860 if (ImpersonationLevel
== SecurityAnonymous
)
1862 ObfDereferenceObject(Token
);
1863 return STATUS_CANT_OPEN_ANONYMOUS
;
1867 * Revert to self if OpenAsSelf is specified.
1872 PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1877 Status
= ObReferenceObjectByHandle(ThreadHandle
, THREAD_ALL_ACCESS
,
1878 PsThreadType
, UserMode
,
1879 (PVOID
*)&Thread
, NULL
);
1880 if (!NT_SUCCESS(Status
))
1882 ObfDereferenceObject(Token
);
1885 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1890 PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
1891 Status
= SepCreateImpersonationTokenDacl(Token
, PrimaryToken
, &Dacl
);
1892 ObfDereferenceObject(PrimaryToken
);
1893 ObfDereferenceObject(Thread
);
1894 if (!NT_SUCCESS(Status
))
1896 ObfDereferenceObject(Token
);
1899 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1904 RtlCreateSecurityDescriptor(&SecurityDescriptor
,
1905 SECURITY_DESCRIPTOR_REVISION
);
1906 RtlSetDaclSecurityDescriptor(&SecurityDescriptor
, TRUE
, Dacl
,
1909 InitializeObjectAttributes(&ObjectAttributes
, NULL
, HandleAttributes
,
1910 NULL
, &SecurityDescriptor
);
1912 Status
= SepDuplicateToken(Token
, &ObjectAttributes
, EffectiveOnly
,
1913 TokenImpersonation
, ImpersonationLevel
,
1914 KernelMode
, &NewToken
);
1916 if (!NT_SUCCESS(Status
))
1918 ObfDereferenceObject(Token
);
1921 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1926 Status
= ObInsertObject(NewToken
, NULL
, DesiredAccess
, 0, NULL
,
1929 ObfDereferenceObject(NewToken
);
1933 Status
= ObOpenObjectByPointer(Token
, HandleAttributes
,
1934 NULL
, DesiredAccess
, SepTokenObjectType
,
1935 ExGetPreviousMode(), TokenHandle
);
1938 ObfDereferenceObject(Token
);
1942 PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState
);
1952 NtOpenThreadToken(IN HANDLE ThreadHandle
,
1953 IN ACCESS_MASK DesiredAccess
,
1954 IN BOOLEAN OpenAsSelf
,
1955 OUT PHANDLE TokenHandle
)
1957 return NtOpenThreadTokenEx(ThreadHandle
, DesiredAccess
, OpenAsSelf
, 0,