reactos/ntoskrnl/se/subject.c
George Bișoc 9a2c62b544
[NTOS:SE] Reorganize the security manager component
The current state of Security manager's code is kind of a mess. Mainly, there's code scattered around places where they shouldn't belong and token implementation (token.c) is already of a bloat in itself as it is. The file has over 6k lines and it's subject to grow exponentially with improvements, features, whatever that is.

With that being said, the token implementation code in the kernel will be split accordingly and rest of the code moved to appropriate places. The new layout will look as follows (excluding the already existing files):

- client.c (Client security implementation code)
- objtype.c (Object type list implementation code -- more code related to object types will be put here when I'm going to implement object type access checks in the future)
- subject.c (Subject security context support)

The token implementation in the kernel will be split in 4 distinct files as shown:

- token.c (Base token support routines)
- tokenlif.c (Life management of a token object -- that is Duplication, Creation and Filtering)
- tokencls.c (Token Query/Set Information Classes support)
- tokenadj.c (Token privileges/groups adjusting support)

In addition to that, tidy up the internal header and reorganize it as well.
2022-05-29 20:22:19 +02:00

186 lines
4.5 KiB
C

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Security subject context support routines
* COPYRIGHT: Copyright Alex Ionescu <alex@relsoft.net>
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
ERESOURCE SepSubjectContextLock;
/* PUBLIC FUNCTIONS ***********************************************************/
/**
* @brief
* An extended function that captures the security subject context based upon
* the specified thread and process.
*
* @param[in] Thread
* A thread where the calling thread's token is to be referenced for
* the security context.
*
* @param[in] Process
* A process where the main process' token is to be referenced for
* the security context.
*
* @param[out] SubjectContext
* The returned security subject context.
*
* @return
* Nothing.
*/
VOID
NTAPI
SeCaptureSubjectContextEx(
_In_ PETHREAD Thread,
_In_ PEPROCESS Process,
_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
BOOLEAN CopyOnOpen, EffectiveOnly;
PAGED_CODE();
/* Save the unique ID */
SubjectContext->ProcessAuditId = Process->UniqueProcessId;
/* Check if we have a thread */
if (!Thread)
{
/* We don't, so no token */
SubjectContext->ClientToken = NULL;
}
else
{
/* Get the impersonation token */
SubjectContext->ClientToken = PsReferenceImpersonationToken(Thread,
&CopyOnOpen,
&EffectiveOnly,
&SubjectContext->ImpersonationLevel);
}
/* Get the primary token */
SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
}
/**
* @brief
* Captures the security subject context of the calling thread and calling
* process.
*
* @param[out] SubjectContext
* The returned security subject context.
*
* @return
* Nothing.
*/
VOID
NTAPI
SeCaptureSubjectContext(
_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
/* Call the extended API */
SeCaptureSubjectContextEx(PsGetCurrentThread(),
PsGetCurrentProcess(),
SubjectContext);
}
/**
* @brief
* Locks both the referenced primary and client access tokens of a
* security subject context.
*
* @param[in] SubjectContext
* A valid security context with both referenced tokens.
*
* @return
* Nothing.
*/
VOID
NTAPI
SeLockSubjectContext(
_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
PTOKEN PrimaryToken, ClientToken;
PAGED_CODE();
/* Read both tokens */
PrimaryToken = SubjectContext->PrimaryToken;
ClientToken = SubjectContext->ClientToken;
/* Always lock the primary */
SepAcquireTokenLockShared(PrimaryToken);
/* Lock the impersonation one if it's there */
if (!ClientToken) return;
SepAcquireTokenLockShared(ClientToken);
}
/**
* @brief
* Unlocks both the referenced primary and client access tokens of a
* security subject context.
*
* @param[in] SubjectContext
* A valid security context with both referenced tokens.
*
* @return
* Nothing.
*/
VOID
NTAPI
SeUnlockSubjectContext(
_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
PTOKEN PrimaryToken, ClientToken;
PAGED_CODE();
/* Read both tokens */
PrimaryToken = SubjectContext->PrimaryToken;
ClientToken = SubjectContext->ClientToken;
/* Unlock the impersonation one if it's there */
if (ClientToken)
{
SepReleaseTokenLock(ClientToken);
}
/* Always unlock the primary one */
SepReleaseTokenLock(PrimaryToken);
}
/**
* @brief
* Releases both the primary and client tokens of a security
* subject context.
*
* @param[in] SubjectContext
* The captured security context.
*
* @return
* Nothing.
*/
VOID
NTAPI
SeReleaseSubjectContext(
_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
PAGED_CODE();
/* Drop reference on the primary */
ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken);
SubjectContext->PrimaryToken = NULL;
/* Drop reference on the impersonation, if there was one */
PsDereferenceImpersonationToken(SubjectContext->ClientToken);
SubjectContext->ClientToken = NULL;
}
/* EOF */