1 /* $Id: token.c,v 1.37 2004/07/13 08:43:35 ekohl Exp $
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 NewToken
,
51 PACCESS_TOKEN
* OldTokenP
)
53 PACCESS_TOKEN OldToken
;
55 if (NewToken
->TokenType
!= TokenPrimary
)
57 return(STATUS_UNSUCCESSFUL
);
59 if (NewToken
->TokenInUse
!= 0)
61 return(STATUS_UNSUCCESSFUL
);
63 OldToken
= Process
->Token
;
64 Process
->Token
= NewToken
;
65 NewToken
->TokenInUse
= 1;
66 ObReferenceObjectByPointer(NewToken
,
70 OldToken
->TokenInUse
= 0;
71 *OldTokenP
= OldToken
;
72 return(STATUS_SUCCESS
);
76 RtlLengthSidAndAttributes(ULONG Count
,
77 PSID_AND_ATTRIBUTES Src
)
82 uLength
= Count
* sizeof(SID_AND_ATTRIBUTES
);
83 for (i
= 0; i
< Count
; i
++)
84 uLength
+= RtlLengthSid(Src
[i
].Sid
);
91 SepFindPrimaryGroupAndDefaultOwner(PACCESS_TOKEN Token
,
97 Token
->PrimaryGroup
= 0;
101 Token
->DefaultOwnerIndex
= Token
->UserAndGroupCount
;
104 /* Validate and set the primary group and user pointers */
105 for (i
= 0; i
< Token
->UserAndGroupCount
; i
++)
108 RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, DefaultOwner
))
110 Token
->DefaultOwnerIndex
= i
;
113 if (RtlEqualSid(Token
->UserAndGroups
[i
].Sid
, PrimaryGroup
))
115 Token
->PrimaryGroup
= Token
->UserAndGroups
[i
].Sid
;
119 if (Token
->DefaultOwnerIndex
== Token
->UserAndGroupCount
)
121 return(STATUS_INVALID_OWNER
);
124 if (Token
->PrimaryGroup
== 0)
126 return(STATUS_INVALID_PRIMARY_GROUP
);
129 return(STATUS_SUCCESS
);
134 SepDuplicateToken(PACCESS_TOKEN Token
,
135 POBJECT_ATTRIBUTES ObjectAttributes
,
136 TOKEN_TYPE TokenType
,
137 SECURITY_IMPERSONATION_LEVEL Level
,
138 SECURITY_IMPERSONATION_LEVEL ExistingLevel
,
139 KPROCESSOR_MODE PreviousMode
,
140 PACCESS_TOKEN
* NewAccessToken
)
148 PACCESS_TOKEN AccessToken
;
150 Status
= ObCreateObject(PreviousMode
,
155 sizeof(ACCESS_TOKEN
),
158 (PVOID
*)&AccessToken
);
159 if (!NT_SUCCESS(Status
))
161 DPRINT1("ObCreateObject() failed (Status %lx)\n");
165 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->TokenId
);
166 if (!NT_SUCCESS(Status
))
168 ObDereferenceObject(AccessToken
);
172 Status
= ZwAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
173 if (!NT_SUCCESS(Status
))
175 ObDereferenceObject(AccessToken
);
179 AccessToken
->TokenInUse
= 0;
180 AccessToken
->TokenType
= TokenType
;
181 AccessToken
->ImpersonationLevel
= Level
;
182 AccessToken
->AuthenticationId
.LowPart
= SYSTEM_LUID
;
183 AccessToken
->AuthenticationId
.HighPart
= 0;
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
)
270 PACCESS_TOKEN pNewToken
;
271 PACCESS_TOKEN pParentToken
;
273 OBJECT_ATTRIBUTES ObjectAttributes
;
275 pParentToken
= (PACCESS_TOKEN
) ParentProcess
->Token
;
277 InitializeObjectAttributes(&ObjectAttributes
,
283 Status
= SepDuplicateToken(pParentToken
,
286 pParentToken
->ImpersonationLevel
,
287 pParentToken
->ImpersonationLevel
,
290 if ( ! NT_SUCCESS(Status
) )
293 NewProcess
->Token
= pNewToken
;
294 return(STATUS_SUCCESS
);
298 NTSTATUS
SeCopyClientToken(PACCESS_TOKEN Token
,
299 SECURITY_IMPERSONATION_LEVEL Level
,
300 KPROCESSOR_MODE PreviousMode
,
301 PACCESS_TOKEN
* NewToken
)
304 OBJECT_ATTRIBUTES ObjectAttributes
;
306 InitializeObjectAttributes(&ObjectAttributes
,
311 Status
= SepDuplicateToken(Token
,
314 SecurityIdentification
,
326 SeCreateClientSecurity(IN
struct _ETHREAD
*Thread
,
327 IN PSECURITY_QUALITY_OF_SERVICE Qos
,
328 IN BOOLEAN RemoteClient
,
329 OUT PSECURITY_CLIENT_CONTEXT ClientContext
)
331 TOKEN_TYPE TokenType
;
333 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
336 PACCESS_TOKEN NewToken
;
338 Token
= PsReferenceEffectiveToken(Thread
,
341 &ImpersonationLevel
);
344 ClientContext
->DirectAccessEffectiveOnly
= Qos
->EffectiveOnly
;
348 if (Qos
->ImpersonationLevel
> ImpersonationLevel
)
352 ObDereferenceObject(Token
);
354 return(STATUS_UNSUCCESSFUL
);
356 if (ImpersonationLevel
== 0 ||
357 ImpersonationLevel
== 1 ||
358 (RemoteClient
!= FALSE
&& ImpersonationLevel
!= 3))
362 ObDereferenceObject(Token
);
364 return(STATUS_UNSUCCESSFUL
);
367 Qos
->EffectiveOnly
!= 0)
369 ClientContext
->DirectAccessEffectiveOnly
= TRUE
;
373 ClientContext
->DirectAccessEffectiveOnly
= FALSE
;
377 if (Qos
->ContextTrackingMode
== 0)
379 ClientContext
->DirectlyAccessClientToken
= FALSE
;
380 g
= SeCopyClientToken(Token
, ImpersonationLevel
, 0, &NewToken
);
383 // ObDeleteCapturedInsertInfo(NewToken);
385 if (TokenType
== TokenPrimary
|| Token
!= NULL
)
387 ObDereferenceObject(Token
);
396 ClientContext
->DirectlyAccessClientToken
= TRUE
;
397 if (RemoteClient
!= FALSE
)
399 // SeGetTokenControlInformation(Token, &ClientContext->Unknown11);
403 ClientContext
->SecurityQos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
404 ClientContext
->SecurityQos
.ImpersonationLevel
= Qos
->ImpersonationLevel
;
405 ClientContext
->SecurityQos
.ContextTrackingMode
= Qos
->ContextTrackingMode
;
406 ClientContext
->SecurityQos
.EffectiveOnly
= Qos
->EffectiveOnly
;
407 ClientContext
->ServerIsRemote
= RemoteClient
;
408 ClientContext
->Token
= NewToken
;
410 return(STATUS_SUCCESS
);
418 SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext
,
419 IN PETHREAD ServerThread OPTIONAL
)
423 if (ClientContext
->DirectlyAccessClientToken
== FALSE
)
425 b
= ClientContext
->SecurityQos
.EffectiveOnly
;
429 b
= ClientContext
->DirectAccessEffectiveOnly
;
431 if (ServerThread
== NULL
)
433 ServerThread
= PsGetCurrentThread();
435 PsImpersonateClient(ServerThread
,
436 ClientContext
->Token
,
439 ClientContext
->SecurityQos
.ImpersonationLevel
);
444 SepDeleteToken(PVOID ObjectBody
)
446 PACCESS_TOKEN AccessToken
= (PACCESS_TOKEN
)ObjectBody
;
448 if (AccessToken
->UserAndGroups
)
449 ExFreePool(AccessToken
->UserAndGroups
);
451 if (AccessToken
->Privileges
)
452 ExFreePool(AccessToken
->Privileges
);
454 if (AccessToken
->DefaultDacl
)
455 ExFreePool(AccessToken
->DefaultDacl
);
460 SepInitializeTokenImplementation(VOID
)
462 SepTokenObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
464 SepTokenObjectType
->Tag
= TAG('T', 'O', 'K', 'T');
465 SepTokenObjectType
->MaxObjects
= ULONG_MAX
;
466 SepTokenObjectType
->MaxHandles
= ULONG_MAX
;
467 SepTokenObjectType
->TotalObjects
= 0;
468 SepTokenObjectType
->TotalHandles
= 0;
469 SepTokenObjectType
->PagedPoolCharge
= 0;
470 SepTokenObjectType
->NonpagedPoolCharge
= sizeof(ACCESS_TOKEN
);
471 SepTokenObjectType
->Mapping
= &SepTokenMapping
;
472 SepTokenObjectType
->Dump
= NULL
;
473 SepTokenObjectType
->Open
= NULL
;
474 SepTokenObjectType
->Close
= NULL
;
475 SepTokenObjectType
->Delete
= SepDeleteToken
;
476 SepTokenObjectType
->Parse
= NULL
;
477 SepTokenObjectType
->Security
= NULL
;
478 SepTokenObjectType
->QueryName
= NULL
;
479 SepTokenObjectType
->OkayToClose
= NULL
;
480 SepTokenObjectType
->Create
= NULL
;
481 SepTokenObjectType
->DuplicationNotify
= NULL
;
483 RtlCreateUnicodeString(&SepTokenObjectType
->TypeName
,
485 ObpCreateTypeObject (SepTokenObjectType
);
493 NtQueryInformationToken(IN HANDLE TokenHandle
,
494 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
495 OUT PVOID TokenInformation
,
496 IN ULONG TokenInformationLength
,
497 OUT PULONG ReturnLength
)
504 PTOKEN_GROUPS PtrTokenGroups
;
505 PTOKEN_DEFAULT_DACL PtrDefaultDacl
;
506 PTOKEN_STATISTICS PtrTokenStatistics
;
508 Status
= ObReferenceObjectByHandle(TokenHandle
,
509 (TokenInformationClass
== TokenSource
) ? TOKEN_QUERY_SOURCE
: TOKEN_QUERY
,
514 if (!NT_SUCCESS(Status
))
519 switch (TokenInformationClass
)
522 DPRINT("NtQueryInformationToken(TokenUser)\n");
523 Length
= RtlLengthSidAndAttributes(1, Token
->UserAndGroups
);
524 if (TokenInformationLength
< Length
)
526 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
527 if (NT_SUCCESS(Status
))
528 Status
= STATUS_BUFFER_TOO_SMALL
;
532 Status
= RtlCopySidAndAttributesArray(1,
533 Token
->UserAndGroups
,
534 TokenInformationLength
,
536 (char*)TokenInformation
+ 8,
539 if (NT_SUCCESS(Status
))
541 Length
= TokenInformationLength
- Length
;
542 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
548 DPRINT("NtQueryInformationToken(TokenGroups)\n");
549 Length
= RtlLengthSidAndAttributes(Token
->UserAndGroupCount
- 1, &Token
->UserAndGroups
[1]) + sizeof(ULONG
);
550 if (TokenInformationLength
< Length
)
552 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
553 if (NT_SUCCESS(Status
))
554 Status
= STATUS_BUFFER_TOO_SMALL
;
558 EndMem
= (char*)TokenInformation
+ Token
->UserAndGroupCount
* sizeof(SID_AND_ATTRIBUTES
);
559 PtrTokenGroups
= (PTOKEN_GROUPS
)TokenInformation
;
560 PtrTokenGroups
->GroupCount
= Token
->UserAndGroupCount
- 1;
561 Status
= RtlCopySidAndAttributesArray(Token
->UserAndGroupCount
- 1,
562 &Token
->UserAndGroups
[1],
563 TokenInformationLength
,
564 PtrTokenGroups
->Groups
,
568 if (NT_SUCCESS(Status
))
570 Length
= TokenInformationLength
- Length
;
571 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
576 case TokenPrivileges
:
577 DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
578 Length
= sizeof(ULONG
) + Token
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
579 if (TokenInformationLength
< Length
)
581 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
582 if (NT_SUCCESS(Status
))
583 Status
= STATUS_BUFFER_TOO_SMALL
;
588 TOKEN_PRIVILEGES
* pPriv
= (TOKEN_PRIVILEGES
*)TokenInformation
;
590 pPriv
->PrivilegeCount
= Token
->PrivilegeCount
;
591 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
593 RtlCopyLuid(&pPriv
->Privileges
[i
].Luid
, &Token
->Privileges
[i
].Luid
);
594 pPriv
->Privileges
[i
].Attributes
= Token
->Privileges
[i
].Attributes
;
596 Status
= STATUS_SUCCESS
;
601 DPRINT("NtQueryInformationToken(TokenOwner)\n");
602 Length
= RtlLengthSid(Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
) + sizeof(TOKEN_OWNER
);
603 if (TokenInformationLength
< Length
)
605 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
606 if (NT_SUCCESS(Status
))
607 Status
= STATUS_BUFFER_TOO_SMALL
;
611 ((PTOKEN_OWNER
)TokenInformation
)->Owner
=
612 (PSID
)(((PTOKEN_OWNER
)TokenInformation
) + 1);
613 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
614 ((PTOKEN_OWNER
)TokenInformation
)->Owner
,
615 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
);
616 Status
= STATUS_SUCCESS
;
620 case TokenPrimaryGroup
:
621 DPRINT("NtQueryInformationToken(TokenPrimaryGroup),"
622 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
623 Length
= RtlLengthSid(Token
->PrimaryGroup
) + sizeof(TOKEN_PRIMARY_GROUP
);
624 if (TokenInformationLength
< Length
)
626 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
627 if (NT_SUCCESS(Status
))
628 Status
= STATUS_BUFFER_TOO_SMALL
;
632 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
=
633 (PSID
)(((PTOKEN_PRIMARY_GROUP
)TokenInformation
) + 1);
634 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
635 ((PTOKEN_PRIMARY_GROUP
)TokenInformation
)->PrimaryGroup
,
636 Token
->PrimaryGroup
);
637 Status
= STATUS_SUCCESS
;
641 case TokenDefaultDacl
:
642 DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
643 PtrDefaultDacl
= (PTOKEN_DEFAULT_DACL
) TokenInformation
;
644 Length
= (Token
->DefaultDacl
? Token
->DefaultDacl
->AclSize
: 0) + sizeof(TOKEN_DEFAULT_DACL
);
645 if (TokenInformationLength
< Length
)
647 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
648 if (NT_SUCCESS(Status
))
649 Status
= STATUS_BUFFER_TOO_SMALL
;
651 else if (!Token
->DefaultDacl
)
653 PtrDefaultDacl
->DefaultDacl
= 0;
654 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
658 PtrDefaultDacl
->DefaultDacl
= (PACL
) (PtrDefaultDacl
+ 1);
659 memmove(PtrDefaultDacl
->DefaultDacl
,
661 Token
->DefaultDacl
->AclSize
);
662 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
667 DPRINT("NtQueryInformationToken(TokenSource)\n");
668 if (TokenInformationLength
< sizeof(TOKEN_SOURCE
))
670 Length
= sizeof(TOKEN_SOURCE
);
671 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
672 if (NT_SUCCESS(Status
))
673 Status
= STATUS_BUFFER_TOO_SMALL
;
677 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenSource
, sizeof(TOKEN_SOURCE
));
682 DPRINT("NtQueryInformationToken(TokenType)\n");
683 if (TokenInformationLength
< sizeof(TOKEN_TYPE
))
685 Length
= sizeof(TOKEN_TYPE
);
686 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
687 if (NT_SUCCESS(Status
))
688 Status
= STATUS_BUFFER_TOO_SMALL
;
692 Status
= MmCopyToCaller(TokenInformation
, &Token
->TokenType
, sizeof(TOKEN_TYPE
));
696 case TokenImpersonationLevel
:
697 DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
698 if (TokenInformationLength
< sizeof(SECURITY_IMPERSONATION_LEVEL
))
700 Length
= sizeof(SECURITY_IMPERSONATION_LEVEL
);
701 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
702 if (NT_SUCCESS(Status
))
703 Status
= STATUS_BUFFER_TOO_SMALL
;
707 Status
= MmCopyToCaller(TokenInformation
, &Token
->ImpersonationLevel
, sizeof(SECURITY_IMPERSONATION_LEVEL
));
711 case TokenStatistics
:
712 DPRINT("NtQueryInformationToken(TokenStatistics)\n");
713 if (TokenInformationLength
< sizeof(TOKEN_STATISTICS
))
715 Length
= sizeof(TOKEN_STATISTICS
);
716 Status
= MmCopyToCaller(ReturnLength
, &Length
, sizeof(ULONG
));
717 if (NT_SUCCESS(Status
))
718 Status
= STATUS_BUFFER_TOO_SMALL
;
722 PtrTokenStatistics
= (PTOKEN_STATISTICS
)TokenInformation
;
723 PtrTokenStatistics
->TokenId
= Token
->TokenId
;
724 PtrTokenStatistics
->AuthenticationId
= Token
->AuthenticationId
;
725 PtrTokenStatistics
->ExpirationTime
= Token
->ExpirationTime
;
726 PtrTokenStatistics
->TokenType
= Token
->TokenType
;
727 PtrTokenStatistics
->ImpersonationLevel
= Token
->ImpersonationLevel
;
728 PtrTokenStatistics
->DynamicCharged
= Token
->DynamicCharged
;
729 PtrTokenStatistics
->DynamicAvailable
= Token
->DynamicAvailable
;
730 PtrTokenStatistics
->GroupCount
= Token
->UserAndGroupCount
- 1;
731 PtrTokenStatistics
->PrivilegeCount
= Token
->PrivilegeCount
;
732 PtrTokenStatistics
->ModifiedId
= Token
->ModifiedId
;
734 Status
= STATUS_SUCCESS
;
739 ObDereferenceObject(Token
);
745 * NtSetTokenInformation: Partly implemented.
747 * TokenOrigin, TokenDefaultDacl, TokenSessionId
751 NtSetInformationToken(IN HANDLE TokenHandle
,
752 IN TOKEN_INFORMATION_CLASS TokenInformationClass
,
753 OUT PVOID TokenInformation
,
754 IN ULONG TokenInformationLength
)
758 TOKEN_OWNER TokenOwnerSet
= { 0 };
759 TOKEN_PRIMARY_GROUP TokenPrimaryGroupSet
= { 0 };
760 DWORD NeededAccess
= 0;
762 switch (TokenInformationClass
)
765 case TokenPrimaryGroup
:
766 NeededAccess
= TOKEN_ADJUST_DEFAULT
;
770 return STATUS_NOT_IMPLEMENTED
;
773 Status
= ObReferenceObjectByHandle(TokenHandle
,
779 if (!NT_SUCCESS(Status
))
784 switch (TokenInformationClass
)
787 MmCopyFromCaller( &TokenOwnerSet
, TokenInformation
,
788 min(sizeof(TokenOwnerSet
),TokenInformationLength
) );
789 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_OWNER
),
790 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
,
791 TokenOwnerSet
.Owner
);
792 Status
= STATUS_SUCCESS
;
793 DPRINT("NtSetInformationToken(TokenOwner)\n");
796 case TokenPrimaryGroup
:
797 MmCopyFromCaller( &TokenPrimaryGroupSet
, TokenInformation
,
798 min(sizeof(TokenPrimaryGroupSet
),
799 TokenInformationLength
) );
800 RtlCopySid(TokenInformationLength
- sizeof(TOKEN_PRIMARY_GROUP
),
802 TokenPrimaryGroupSet
.PrimaryGroup
);
803 Status
= STATUS_SUCCESS
;
804 DPRINT("NtSetInformationToken(TokenPrimaryGroup),"
805 "Token->PrimaryGroup = 0x%08x\n", Token
->PrimaryGroup
);
809 Status
= STATUS_NOT_IMPLEMENTED
;
813 ObDereferenceObject(Token
);
823 NtDuplicateToken(IN HANDLE ExistingTokenHandle
,
824 IN ACCESS_MASK DesiredAccess
,
825 IN POBJECT_ATTRIBUTES ObjectAttributes
,
826 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
827 IN TOKEN_TYPE TokenType
,
828 OUT PHANDLE NewTokenHandle
)
830 KPROCESSOR_MODE PreviousMode
;
832 PACCESS_TOKEN NewToken
;
834 ULONG ExistingImpersonationLevel
;
836 PreviousMode
= KeGetPreviousMode();
837 Status
= ObReferenceObjectByHandle(ExistingTokenHandle
,
843 if (!NT_SUCCESS(Status
))
845 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
849 ExistingImpersonationLevel
= Token
->ImpersonationLevel
;
850 Status
= SepDuplicateToken(Token
,
854 ExistingImpersonationLevel
,
858 ObDereferenceObject(Token
);
860 if (!NT_SUCCESS(Status
))
862 DPRINT1("Failed to duplicate token (Status %lx)\n", Status
);
866 Status
= ObInsertObject((PVOID
)NewToken
,
873 ObDereferenceObject(NewToken
);
875 if (!NT_SUCCESS(Status
))
877 DPRINT1("Failed to create token handle (Status %lx)\n");
881 return STATUS_SUCCESS
;
885 VOID
SepAdjustGroups(PACCESS_TOKEN Token
,
887 BOOLEAN ResetToDefault
,
888 PSID_AND_ATTRIBUTES Groups
,
890 KPROCESSOR_MODE PreviousMode
,
901 NtAdjustGroupsToken(IN HANDLE TokenHandle
,
902 IN BOOLEAN ResetToDefault
,
903 IN PTOKEN_GROUPS NewState
,
904 IN ULONG BufferLength
,
905 OUT PTOKEN_GROUPS PreviousState OPTIONAL
,
906 OUT PULONG ReturnLength
)
915 Status
= ObReferenceObjectByHandle(TokenHandle
,
923 SepAdjustGroups(Token
,
935 return(STATUS_NOT_IMPLEMENTED
);
942 SepAdjustPrivileges(PACCESS_TOKEN Token
,
944 KPROCESSOR_MODE PreviousMode
,
945 ULONG PrivilegeCount
,
946 PLUID_AND_ATTRIBUTES Privileges
,
947 PTOKEN_PRIVILEGES
* PreviousState
,
956 if (Token
->PrivilegeCount
> 0)
958 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
960 if (PreviousMode
!= KernelMode
)
962 if (Token
->Privileges
[i
]->Attributes
& SE_PRIVILEGE_ENABLED
== 0)
966 if (PreviousState
!= NULL
)
968 memcpy(&PreviousState
[i
],
969 &Token
->Privileges
[i
],
970 sizeof(LUID_AND_ATTRIBUTES
));
972 Token
->Privileges
[i
].Attributes
&= (~SE_PRIVILEGE_ENABLED
);
979 if (PreviousMode
!= KernelMode
)
981 Token
->TokenFlags
= Token
->TokenFlags
& (~1);
985 if (PrivilegeCount
<= ?)
998 NtAdjustPrivilegesToken (IN HANDLE TokenHandle
,
999 IN BOOLEAN DisableAllPrivileges
,
1000 IN PTOKEN_PRIVILEGES NewState
,
1001 IN ULONG BufferLength
,
1002 OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL
,
1003 OUT PULONG ReturnLength OPTIONAL
)
1005 // PLUID_AND_ATTRIBUTES Privileges;
1006 KPROCESSOR_MODE PreviousMode
;
1007 // ULONG PrivilegeCount;
1008 PACCESS_TOKEN Token
;
1021 DPRINT ("NtAdjustPrivilegesToken() called\n");
1023 // PrivilegeCount = NewState->PrivilegeCount;
1024 PreviousMode
= KeGetPreviousMode ();
1025 // SeCaptureLuidAndAttributesArray(NewState->Privileges,
1035 Status
= ObReferenceObjectByHandle (TokenHandle
,
1036 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1041 if (!NT_SUCCESS(Status
))
1043 DPRINT1 ("Failed to reference token (Status %lx)\n", Status
);
1044 // SeReleaseLuidAndAttributesArray(Privileges,
1052 SepAdjustPrivileges(Token
,
1064 if (DisableAllPrivileges
== TRUE
)
1066 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1068 if (Token
->Privileges
[i
].Attributes
!= 0)
1070 DPRINT ("Attributes differ\n");
1072 /* Save current privilege */
1073 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1075 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1076 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1080 /* Update current privlege */
1081 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1084 Status
= STATUS_SUCCESS
;
1089 for (i
= 0; i
< Token
->PrivilegeCount
; i
++)
1091 for (j
= 0; j
< NewState
->PrivilegeCount
; j
++)
1093 if (Token
->Privileges
[i
].Luid
.LowPart
== NewState
->Privileges
[j
].Luid
.LowPart
&&
1094 Token
->Privileges
[i
].Luid
.HighPart
== NewState
->Privileges
[j
].Luid
.HighPart
)
1096 DPRINT ("Found privilege\n");
1098 if ((Token
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
) !=
1099 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
))
1101 DPRINT ("Attributes differ\n");
1102 DPRINT ("Current attributes %lx desired attributes %lx\n",
1103 Token
->Privileges
[i
].Attributes
,
1104 NewState
->Privileges
[j
].Attributes
);
1106 /* Save current privilege */
1107 if (PreviousState
!= NULL
&& k
< PreviousState
->PrivilegeCount
)
1109 PreviousState
->Privileges
[k
].Luid
= Token
->Privileges
[i
].Luid
;
1110 PreviousState
->Privileges
[k
].Attributes
= Token
->Privileges
[i
].Attributes
;
1114 /* Update current privlege */
1115 Token
->Privileges
[i
].Attributes
&= ~SE_PRIVILEGE_ENABLED
;
1116 Token
->Privileges
[i
].Attributes
|=
1117 (NewState
->Privileges
[j
].Attributes
& SE_PRIVILEGE_ENABLED
);
1118 DPRINT ("New attributes %lx\n",
1119 Token
->Privileges
[i
].Attributes
);
1125 Status
= Count
< NewState
->PrivilegeCount
? STATUS_NOT_ALL_ASSIGNED
: STATUS_SUCCESS
;
1128 if (ReturnLength
!= NULL
)
1130 *ReturnLength
= sizeof(TOKEN_PRIVILEGES
) +
1131 (sizeof(LUID_AND_ATTRIBUTES
) * (k
- 1));
1134 ObDereferenceObject (Token
);
1136 // SeReleaseLuidAndAttributesArray(Privileges,
1140 DPRINT ("NtAdjustPrivilegesToken() done\n");
1147 SepCreateSystemProcessToken(struct _EPROCESS
* Process
)
1153 ULONG uLocalSystemLength
= RtlLengthSid(SeLocalSystemSid
);
1154 ULONG uWorldLength
= RtlLengthSid(SeWorldSid
);
1155 ULONG uAuthUserLength
= RtlLengthSid(SeAuthenticatedUserSid
);
1156 ULONG uAdminsLength
= RtlLengthSid(SeAliasAdminsSid
);
1158 PACCESS_TOKEN AccessToken
;
1163 * Initialize the token
1165 Status
= ObCreateObject(KernelMode
,
1170 sizeof(ACCESS_TOKEN
),
1173 (PVOID
*)&AccessToken
);
1174 if (!NT_SUCCESS(Status
))
1179 Status
= NtAllocateLocallyUniqueId(&AccessToken
->TokenId
);
1180 if (!NT_SUCCESS(Status
))
1182 ObDereferenceObject(AccessToken
);
1186 Status
= NtAllocateLocallyUniqueId(&AccessToken
->ModifiedId
);
1187 if (!NT_SUCCESS(Status
))
1189 ObDereferenceObject(AccessToken
);
1193 AccessToken
->AuthenticationId
.LowPart
= SYSTEM_LUID
;
1194 AccessToken
->AuthenticationId
.HighPart
= 0;
1196 AccessToken
->TokenType
= TokenPrimary
;
1197 AccessToken
->ImpersonationLevel
= SecurityDelegation
;
1198 AccessToken
->TokenSource
.SourceIdentifier
.LowPart
= 0;
1199 AccessToken
->TokenSource
.SourceIdentifier
.HighPart
= 0;
1200 memcpy(AccessToken
->TokenSource
.SourceName
, "SeMgr\0\0\0", 8);
1201 AccessToken
->ExpirationTime
.QuadPart
= -1;
1202 AccessToken
->UserAndGroupCount
= 4;
1204 uSize
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1205 uSize
+= uLocalSystemLength
;
1206 uSize
+= uWorldLength
;
1207 uSize
+= uAuthUserLength
;
1208 uSize
+= uAdminsLength
;
1210 AccessToken
->UserAndGroups
=
1211 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1213 TAG('T', 'O', 'K', 'u'));
1214 SidArea
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1217 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1218 AccessToken
->UserAndGroups
[i
++].Attributes
= 0;
1219 RtlCopySid(uLocalSystemLength
, SidArea
, SeLocalSystemSid
);
1220 SidArea
= (char*)SidArea
+ uLocalSystemLength
;
1222 AccessToken
->DefaultOwnerIndex
= i
;
1223 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1224 AccessToken
->PrimaryGroup
= (PSID
) SidArea
;
1225 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
;
1226 Status
= RtlCopySid(uAdminsLength
, SidArea
, SeAliasAdminsSid
);
1227 SidArea
= (char*)SidArea
+ uAdminsLength
;
1229 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1230 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1231 RtlCopySid(uWorldLength
, SidArea
, SeWorldSid
);
1232 SidArea
= (char*)SidArea
+ uWorldLength
;
1234 AccessToken
->UserAndGroups
[i
].Sid
= (PSID
) SidArea
;
1235 AccessToken
->UserAndGroups
[i
++].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
1236 RtlCopySid(uAuthUserLength
, SidArea
, SeAuthenticatedUserSid
);
1237 SidArea
= (char*)SidArea
+ uAuthUserLength
;
1239 AccessToken
->PrivilegeCount
= 20;
1241 uSize
= AccessToken
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1242 AccessToken
->Privileges
=
1243 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1245 TAG('T', 'O', 'K', 'p'));
1248 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1249 AccessToken
->Privileges
[i
++].Luid
= SeTcbPrivilege
;
1251 AccessToken
->Privileges
[i
].Attributes
= 0;
1252 AccessToken
->Privileges
[i
++].Luid
= SeCreateTokenPrivilege
;
1254 AccessToken
->Privileges
[i
].Attributes
= 0;
1255 AccessToken
->Privileges
[i
++].Luid
= SeTakeOwnershipPrivilege
;
1257 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1258 AccessToken
->Privileges
[i
++].Luid
= SeCreatePagefilePrivilege
;
1260 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1261 AccessToken
->Privileges
[i
++].Luid
= SeLockMemoryPrivilege
;
1263 AccessToken
->Privileges
[i
].Attributes
= 0;
1264 AccessToken
->Privileges
[i
++].Luid
= SeAssignPrimaryTokenPrivilege
;
1266 AccessToken
->Privileges
[i
].Attributes
= 0;
1267 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseQuotaPrivilege
;
1269 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1270 AccessToken
->Privileges
[i
++].Luid
= SeIncreaseBasePriorityPrivilege
;
1272 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1273 AccessToken
->Privileges
[i
++].Luid
= SeCreatePermanentPrivilege
;
1275 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1276 AccessToken
->Privileges
[i
++].Luid
= SeDebugPrivilege
;
1278 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1279 AccessToken
->Privileges
[i
++].Luid
= SeAuditPrivilege
;
1281 AccessToken
->Privileges
[i
].Attributes
= 0;
1282 AccessToken
->Privileges
[i
++].Luid
= SeSecurityPrivilege
;
1284 AccessToken
->Privileges
[i
].Attributes
= 0;
1285 AccessToken
->Privileges
[i
++].Luid
= SeSystemEnvironmentPrivilege
;
1287 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1288 AccessToken
->Privileges
[i
++].Luid
= SeChangeNotifyPrivilege
;
1290 AccessToken
->Privileges
[i
].Attributes
= 0;
1291 AccessToken
->Privileges
[i
++].Luid
= SeBackupPrivilege
;
1293 AccessToken
->Privileges
[i
].Attributes
= 0;
1294 AccessToken
->Privileges
[i
++].Luid
= SeRestorePrivilege
;
1296 AccessToken
->Privileges
[i
].Attributes
= 0;
1297 AccessToken
->Privileges
[i
++].Luid
= SeShutdownPrivilege
;
1299 AccessToken
->Privileges
[i
].Attributes
= 0;
1300 AccessToken
->Privileges
[i
++].Luid
= SeLoadDriverPrivilege
;
1302 AccessToken
->Privileges
[i
].Attributes
= SE_PRIVILEGE_ENABLED_BY_DEFAULT
|SE_PRIVILEGE_ENABLED
;
1303 AccessToken
->Privileges
[i
++].Luid
= SeProfileSingleProcessPrivilege
;
1305 AccessToken
->Privileges
[i
].Attributes
= 0;
1306 AccessToken
->Privileges
[i
++].Luid
= SeSystemtimePrivilege
;
1308 AccessToken
->Privileges
[i
].Attributes
= 0;
1309 AccessToken
->Privileges
[i
++].Luid
= SeUndockPrivilege
;
1311 AccessToken
->Privileges
[i
].Attributes
= 0;
1312 AccessToken
->Privileges
[i
++].Luid
= SeManageVolumePrivilege
;
1317 uSize
= sizeof(ACL
);
1318 uSize
+= sizeof(ACE
) + uLocalSystemLength
;
1319 uSize
+= sizeof(ACE
) + uAdminsLength
;
1320 uSize
= (uSize
& (~3)) + 8;
1321 AccessToken
->DefaultDacl
=
1322 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1324 TAG('T', 'O', 'K', 'd'));
1325 Status
= RtlCreateAcl(AccessToken
->DefaultDacl
, uSize
, ACL_REVISION
);
1326 if ( NT_SUCCESS(Status
) )
1328 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_ALL
, SeLocalSystemSid
);
1331 if ( NT_SUCCESS(Status
) )
1333 Status
= RtlAddAccessAllowedAce(AccessToken
->DefaultDacl
, ACL_REVISION
, GENERIC_READ
|GENERIC_EXECUTE
|READ_CONTROL
, SeAliasAdminsSid
);
1336 if ( ! NT_SUCCESS(Status
) )
1338 ObDereferenceObject(AccessToken
);
1342 Process
->Token
= AccessToken
;
1343 return(STATUS_SUCCESS
);
1348 NtCreateToken(OUT PHANDLE UnsafeTokenHandle
,
1349 IN ACCESS_MASK DesiredAccess
,
1350 IN POBJECT_ATTRIBUTES UnsafeObjectAttributes
,
1351 IN TOKEN_TYPE TokenType
,
1352 IN PLUID AuthenticationId
,
1353 IN PLARGE_INTEGER ExpirationTime
,
1354 IN PTOKEN_USER TokenUser
,
1355 IN PTOKEN_GROUPS TokenGroups
,
1356 IN PTOKEN_PRIVILEGES TokenPrivileges
,
1357 IN PTOKEN_OWNER TokenOwner
,
1358 IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup
,
1359 IN PTOKEN_DEFAULT_DACL TokenDefaultDacl
,
1360 IN PTOKEN_SOURCE TokenSource
)
1363 PACCESS_TOKEN AccessToken
;
1365 OBJECT_ATTRIBUTES SafeObjectAttributes
;
1366 POBJECT_ATTRIBUTES ObjectAttributes
;
1373 Status
= MmCopyFromCaller(&SafeObjectAttributes
,
1374 UnsafeObjectAttributes
,
1375 sizeof(OBJECT_ATTRIBUTES
));
1376 if (!NT_SUCCESS(Status
))
1379 ObjectAttributes
= &SafeObjectAttributes
;
1381 Status
= ZwAllocateLocallyUniqueId(&TokenId
);
1382 if (!NT_SUCCESS(Status
))
1385 Status
= ZwAllocateLocallyUniqueId(&ModifiedId
);
1386 if (!NT_SUCCESS(Status
))
1389 Status
= ObCreateObject(ExGetPreviousMode(),
1392 ExGetPreviousMode(),
1394 sizeof(ACCESS_TOKEN
),
1397 (PVOID
*)&AccessToken
);
1398 if (!NT_SUCCESS(Status
))
1400 DPRINT1("ObCreateObject() failed (Status %lx)\n");
1404 Status
= ObInsertObject ((PVOID
)AccessToken
,
1410 if (!NT_SUCCESS(Status
))
1412 DPRINT1("ObInsertObject() failed (Status %lx)\n");
1413 ObDereferenceObject (AccessToken
);
1417 RtlCopyLuid(&AccessToken
->TokenSource
.SourceIdentifier
,
1418 &TokenSource
->SourceIdentifier
);
1419 memcpy(AccessToken
->TokenSource
.SourceName
,
1420 TokenSource
->SourceName
,
1421 sizeof(TokenSource
->SourceName
));
1423 RtlCopyLuid(&AccessToken
->TokenId
, &TokenId
);
1424 RtlCopyLuid(&AccessToken
->AuthenticationId
, AuthenticationId
);
1425 AccessToken
->ExpirationTime
= *ExpirationTime
;
1426 RtlCopyLuid(&AccessToken
->ModifiedId
, &ModifiedId
);
1428 AccessToken
->UserAndGroupCount
= TokenGroups
->GroupCount
+ 1;
1429 AccessToken
->PrivilegeCount
= TokenPrivileges
->PrivilegeCount
;
1430 AccessToken
->UserAndGroups
= 0;
1431 AccessToken
->Privileges
= 0;
1433 AccessToken
->TokenType
= TokenType
;
1434 AccessToken
->ImpersonationLevel
= ObjectAttributes
->SecurityQualityOfService
->ImpersonationLevel
;
1437 * Normally we would just point these members into the variable information
1438 * area; however, our ObCreateObject() call can't allocate a variable information
1439 * area, so we allocate them seperately and provide a destroy function.
1442 uLength
= sizeof(SID_AND_ATTRIBUTES
) * AccessToken
->UserAndGroupCount
;
1443 uLength
+= RtlLengthSid(TokenUser
->User
.Sid
);
1444 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
1445 uLength
+= RtlLengthSid(TokenGroups
->Groups
[i
].Sid
);
1447 AccessToken
->UserAndGroups
=
1448 (PSID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1450 TAG('T', 'O', 'K', 'u'));
1452 EndMem
= &AccessToken
->UserAndGroups
[AccessToken
->UserAndGroupCount
];
1454 Status
= RtlCopySidAndAttributesArray(1,
1457 AccessToken
->UserAndGroups
,
1461 if (NT_SUCCESS(Status
))
1463 Status
= RtlCopySidAndAttributesArray(TokenGroups
->GroupCount
,
1464 TokenGroups
->Groups
,
1466 &AccessToken
->UserAndGroups
[1],
1472 if (NT_SUCCESS(Status
))
1474 Status
= SepFindPrimaryGroupAndDefaultOwner(
1476 TokenPrimaryGroup
->PrimaryGroup
,
1480 if (NT_SUCCESS(Status
))
1482 uLength
= TokenPrivileges
->PrivilegeCount
* sizeof(LUID_AND_ATTRIBUTES
);
1483 AccessToken
->Privileges
=
1484 (PLUID_AND_ATTRIBUTES
)ExAllocatePoolWithTag(NonPagedPool
,
1486 TAG('T', 'O', 'K', 'p'));
1488 for (i
= 0; i
< TokenPrivileges
->PrivilegeCount
; i
++)
1490 Status
= MmCopyFromCaller(&AccessToken
->Privileges
[i
],
1491 &TokenPrivileges
->Privileges
[i
],
1492 sizeof(LUID_AND_ATTRIBUTES
));
1493 if (!NT_SUCCESS(Status
))
1498 if (NT_SUCCESS(Status
))
1500 AccessToken
->DefaultDacl
=
1501 (PACL
) ExAllocatePoolWithTag(NonPagedPool
,
1502 TokenDefaultDacl
->DefaultDacl
->AclSize
,
1503 TAG('T', 'O', 'K', 'd'));
1504 memcpy(AccessToken
->DefaultDacl
,
1505 TokenDefaultDacl
->DefaultDacl
,
1506 TokenDefaultDacl
->DefaultDacl
->AclSize
);
1509 ObDereferenceObject(AccessToken
);
1511 if (NT_SUCCESS(Status
))
1513 Status
= MmCopyToCaller(UnsafeTokenHandle
,
1518 if (!NT_SUCCESS(Status
))
1520 ZwClose(TokenHandle
);
1524 return(STATUS_SUCCESS
);
1532 SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token
,
1535 LogonId
->LowPart
= Token
->AuthenticationId
.LowPart
;
1536 LogonId
->HighPart
= Token
->AuthenticationId
.HighPart
;
1538 return STATUS_SUCCESS
;
1545 SECURITY_IMPERSONATION_LEVEL STDCALL
1546 SeTokenImpersonationLevel(IN PACCESS_TOKEN Token
)
1548 return Token
->ImpersonationLevel
;
1556 SeTokenType(IN PACCESS_TOKEN Token
)
1558 return Token
->TokenType
;