https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6413009c10c7d0064f87d…
commit 6413009c10c7d0064f87dc1733d09acdd138fb51
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Wed Aug 11 16:24:45 2021 +0200
Commit: George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Sun Aug 22 10:29:47 2021 +0200
[NTOS:SE] Document the whole subsystem in Doxygen format
And update the file comment headers.
---
ntoskrnl/se/access.c | 327 +++++++++++++--
ntoskrnl/se/accesschk.c | 290 ++++++++++++-
ntoskrnl/se/acl.c | 196 ++++++++-
ntoskrnl/se/audit.c | 1030 +++++++++++++++++++++++++++++++++++++++++++++--
ntoskrnl/se/priv.c | 288 ++++++++++++-
ntoskrnl/se/sd.c | 348 ++++++++++++++--
ntoskrnl/se/semgr.c | 158 +++++++-
ntoskrnl/se/sid.c | 131 +++++-
ntoskrnl/se/srm.c | 187 ++++++++-
ntoskrnl/se/token.c | 814 +++++++++++++++++++++++++++++++++++--
10 files changed, 3577 insertions(+), 192 deletions(-)
diff --git a/ntoskrnl/se/access.c b/ntoskrnl/se/access.c
index a4f5cb0ee67..42c2ab8d1c8 100644
--- a/ntoskrnl/se/access.c
+++ b/ntoskrnl/se/access.c
@@ -1,11 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/access.c
- * PURPOSE: Access state functions
- *
- * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net) -
- * Based on patch by Javier M. Mellid
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Security access state functions support
+ * COPYRIGHT: Copyright Alex Ionescu <alex(a)relsoft.net>
*/
/* INCLUDES *******************************************************************/
@@ -20,6 +17,32 @@ ERESOURCE SepSubjectContextLock;
/* PRIVATE FUNCTIONS **********************************************************/
+/**
+ * @brief
+ * Checks if a SID is present in a token.
+ *
+ * @param[in] _Token
+ * A valid token object.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self SID.
+ *
+ * @param[in] _Sid
+ * A regular SID.
+ *
+ * @param[in] Deny
+ * If set to TRUE, the caller expected that a SID in a token
+ * must be a deny-only SID, that is, access checks are performed
+ * only for deny-only ACEs of the said SID.
+ *
+ * @param[in] Restricted
+ * If set to TRUE, the caller expects that a SID in a token is
+ * restricted.
+ *
+ * @return
+ * Returns TRUE if the specified SID in the call is present in the token,
+ * FALSE otherwise.
+ */
BOOLEAN
NTAPI
SepSidInTokenEx(IN PACCESS_TOKEN _Token,
@@ -106,6 +129,20 @@ SepSidInTokenEx(IN PACCESS_TOKEN _Token,
return FALSE;
}
+/**
+ * @brief
+ * Checks if a SID is present in a token.
+ *
+ * @param[in] _Token
+ * A valid token object.
+ *
+ * @param[in] _Sid
+ * A regular SID.
+ *
+ * @return
+ * Returns TRUE if the specified SID in the call is present in the token,
+ * FALSE otherwise.
+ */
BOOLEAN
NTAPI
SepSidInToken(IN PACCESS_TOKEN _Token,
@@ -115,6 +152,24 @@ SepSidInToken(IN PACCESS_TOKEN _Token,
return SepSidInTokenEx(_Token, NULL, Sid, FALSE, FALSE);
}
+/**
+ * @brief
+ * Checks if a token belongs to the main user, being the owner.
+ *
+ * @param[in] _Token
+ * A valid token object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor where the owner is to be found.
+ *
+ * @param[in] TokenLocked
+ * If set to TRUE, the token has been already locked and there's
+ * no need to lock it again. Otherwise the function will acquire
+ * the lock.
+ *
+ * @return
+ * Returns TRUE if the token belongs to a owner, FALSE otherwise.
+ */
BOOLEAN
NTAPI
SepTokenIsOwner(IN PACCESS_TOKEN _Token,
@@ -146,6 +201,19 @@ SepTokenIsOwner(IN PACCESS_TOKEN _Token,
return Result;
}
+/**
+ * @brief
+ * Retrieves token control information.
+ *
+ * @param[in] _Token
+ * A valid token object.
+ *
+ * @param[out] SecurityDescriptor
+ * The returned token control information.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeGetTokenControlInformation(IN PACCESS_TOKEN _Token,
@@ -169,6 +237,41 @@ SeGetTokenControlInformation(IN PACCESS_TOKEN _Token,
SepReleaseTokenLock(Token);
}
+/**
+ * @brief
+ * Creates a client security context based upon an access token.
+ *
+ * @param[in] Token
+ * A valid token object.
+ *
+ * @param[in] ClientSecurityQos
+ * The Quality of Service (QoS) of a client security context.
+ *
+ * @param[in] ServerIsRemote
+ * If the client is a remote server (TRUE), the function will retrieve the
+ * control information of an access token, that is, we're doing delegation
+ * and that the server isn't local.
+ *
+ * @param[in] TokenType
+ * Type of token.
+ *
+ * @param[in] ThreadEffectiveOnly
+ * If set to TRUE, the client wants that the current thread wants to modify
+ * (enable or disable) privileges and groups.
+ *
+ * @param[in] ImpersonationLevel
+ * Security impersonation level filled in the QoS context.
+ *
+ * @param[out] ClientContext
+ * The returned security client context.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if client security creation has completed successfully.
+ * STATUS_INVALID_PARAMETER is returned if one or more of the parameters are bogus.
+ * STATUS_BAD_IMPERSONATION_LEVEL is returned if the current impersonation level
+ * within QoS context doesn't meet with the conditions required. A failure
+ * NTSTATUS code is returned otherwise.
+ */
NTSTATUS
NTAPI
SepCreateClientSecurity(IN PACCESS_TOKEN Token,
@@ -258,8 +361,24 @@ SepCreateClientSecurity(IN PACCESS_TOKEN Token,
/* PUBLIC FUNCTIONS ***********************************************************/
-/*
- * @implemented
+/**
+ * @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
@@ -293,8 +412,16 @@ SeCaptureSubjectContextEx(IN PETHREAD Thread,
SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
}
-/*
- * @implemented
+/**
+ * @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
@@ -306,8 +433,16 @@ SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT
SubjectContext)
SubjectContext);
}
-/*
- * @implemented
+/**
+ * @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
@@ -328,8 +463,16 @@ SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
SepAcquireTokenLockShared(ClientToken);
}
-/*
- * @implemented
+/**
+ * @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
@@ -352,8 +495,16 @@ SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
SepReleaseTokenLock(PrimaryToken);
}
-/*
- * @implemented
+/**
+ * @brief
+ * Releases both the primary and client tokens of a security
+ * subject context.
+ *
+ * @param[in] SubjectContext
+ * The captured security context.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -370,8 +521,30 @@ SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
SubjectContext->ClientToken = NULL;
}
-/*
- * @implemented
+/**
+ * @brief
+ * An extended function that creates an access state.
+ *
+ * @param[in] Thread
+ * Valid thread object where subject context is to be captured.
+ *
+ * @param[in] Process
+ * Valid process object where subject context is to be captured.
+ *
+ * @param[in, out] AccessState
+ * An initialized returned parameter to an access state.
+ *
+ * @param[in] AuxData
+ * Auxiliary security data for access state.
+ *
+ * @param[in] Access
+ * Type of access mask to assign.
+ *
+ * @param[in] GenericMapping
+ * Generic mapping for the access state to assign.
+ *
+ * @return
+ * Returns STATUS_SUCCESS.
*/
NTSTATUS
NTAPI
@@ -431,8 +604,24 @@ SeCreateAccessStateEx(IN PETHREAD Thread,
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Creates an access state.
+ *
+ * @param[in, out] AccessState
+ * An initialized returned parameter to an access state.
+ *
+ * @param[in] AuxData
+ * Auxiliary security data for access state.
+ *
+ * @param[in] Access
+ * Type of access mask to assign.
+ *
+ * @param[in] GenericMapping
+ * Generic mapping for the access state to assign.
+ *
+ * @return
+ * See SeCreateAccessStateEx.
*/
NTSTATUS
NTAPI
@@ -452,8 +641,15 @@ SeCreateAccessState(IN OUT PACCESS_STATE AccessState,
GenericMapping);
}
-/*
- * @implemented
+/**
+ * @brief
+ * Deletes an allocated access state from the memory.
+ *
+ * @param[in] AccessState
+ * A valid access state.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -484,8 +680,18 @@ SeDeleteAccessState(IN PACCESS_STATE AccessState)
SeReleaseSubjectContext(&AccessState->SubjectSecurityContext);
}
-/*
- * @implemented
+/**
+ * @brief
+ * Sets a new generic mapping for an allocated access state.
+ *
+ * @param[in] AccessState
+ * A valid access state.
+ *
+ * @param[in] GenericMapping
+ * New generic mapping to assign.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -498,8 +704,24 @@ SeSetAccessStateGenericMapping(IN PACCESS_STATE AccessState,
((PAUX_ACCESS_DATA)AccessState->AuxData)->GenericMapping = *GenericMapping;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Creates a client security context.
+ *
+ * @param[in] Thread
+ * Thread object of the client where impersonation has to begin.
+ *
+ * @param[in] Qos
+ * Quality of service to specify what kind of impersonation to be done.
+ *
+ * @param[in] RemoteClient
+ * If set to TRUE, the client that we're going to impersonate is remote.
+ *
+ * @param[out] ClientContext
+ * The returned security client context.
+ *
+ * @return
+ * See SepCreateClientSecurity.
*/
NTSTATUS
NTAPI
@@ -541,8 +763,26 @@ SeCreateClientSecurity(IN PETHREAD Thread,
return Status;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Creates a client security context based upon the captured security
+ * subject context.
+ *
+ * @param[in] SubjectContext
+ * The captured subject context where client security is to be created
+ * from.
+ *
+ * @param[in] ClientSecurityQos
+ * Quality of service to specify what kind of impersonation to be done.
+ *
+ * @param[in] ServerIsRemote
+ * If set to TRUE, the client that we're going to impersonate is remote.
+ *
+ * @param[out] ClientContext
+ * The returned security client context.
+ *
+ * @return
+ * See SepCreateClientSecurity.
*/
NTSTATUS
NTAPI
@@ -581,8 +821,19 @@ SeCreateClientSecurityFromSubjectContext(IN PSECURITY_SUBJECT_CONTEXT
SubjectCon
return Status;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Extended function that impersonates a client.
+ *
+ * @param[in] ClientContext
+ * A valid client context.
+ *
+ * @param[in] ServerThread
+ * The thread where impersonation is to be done.
+ *
+ * @return
+ * STATUS_SUCCESS is returned if the calling thread successfully impersonates
+ * the client. A failure NTSTATUS code is returned otherwise.
*/
NTSTATUS
NTAPI
@@ -615,8 +866,18 @@ SeImpersonateClientEx(IN PSECURITY_CLIENT_CONTEXT ClientContext,
ClientContext->SecurityQos.ImpersonationLevel);
}
-/*
- * @implemented
+/**
+ * @brief
+ * Impersonates a client user.
+ *
+ * @param[in] ClientContext
+ * A valid client context.
+ *
+ * @param[in] ServerThread
+ * The thread where impersonation is to be done.
+ * *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
diff --git a/ntoskrnl/se/accesschk.c b/ntoskrnl/se/accesschk.c
index a7784b1c2b6..26e5630469b 100644
--- a/ntoskrnl/se/accesschk.c
+++ b/ntoskrnl/se/accesschk.c
@@ -1,10 +1,9 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/accesschk.c
- * PURPOSE: Security manager
- *
- * PROGRAMMERS: No programmer listed.
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Security access check control implementation
+ * COPYRIGHT: Copyright Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ * Copyright Eric Kohl
*/
/* INCLUDES *******************************************************************/
@@ -18,8 +17,53 @@
/* PRIVATE FUNCTIONS **********************************************************/
-/*
- * FIXME: Incomplete!
+/**
+ * @brief
+ * Private function that determines whether security access rights can be given
+ * to an object depending on the security descriptor and other security context
+ * entities, such as an owner.
+ *
+ * @param[in] SecurityDescriptor
+ * Security descriptor of the object that is being accessed.
+ *
+ * @param[in] SubjectSecurityContext
+ * The captured subject security context.
+ *
+ * @param[in] DesiredAccess
+ * Access right bitmask that the calling thread wants to acquire.
+ *
+ * @param[in] ObjectTypeListLength
+ * The length of a object type list.
+ *
+ * @param[in] PreviouslyGrantedAccess
+ * The access rights previously acquired in the past.
+ *
+ * @param[out] Privileges
+ * The returned set of privileges.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights of an object type.
+ *
+ * @param[in] AccessMode
+ * The processor request level mode.
+ *
+ * @param[out] GrantedAccessList
+ * A list of granted access rights.
+ *
+ * @param[out] AccessStatusList
+ * The returned status code specifying why access cannot be made
+ * onto an object (if said access is denied in the first place).
+ *
+ * @param[in] UseResultList
+ * If set to TRUE, the function will return complete lists of
+ * access status codes and granted access rights.
+ *
+ * @return
+ * Returns TRUE if access onto the specific object is allowed, FALSE
+ * otherwise.
+ *
+ * @remarks
+ * The function is currently incomplete!
*/
BOOLEAN NTAPI
SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
@@ -286,6 +330,17 @@ ReturnCommonStatus:
return NT_SUCCESS(Status);
}
+/**
+ * @brief
+ * Retrieves the main user from a security descriptor.
+ *
+ * @param[in] SecurityDescriptor
+ * A valid allocated security descriptor structure where the owner
+ * is to be retrieved.
+ *
+ * @return
+ * Returns a SID that represents the main user (owner).
+ */
static PSID
SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
{
@@ -301,6 +356,17 @@ SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
return Owner;
}
+/**
+ * @brief
+ * Retrieves the group from a security descriptor.
+ *
+ * @param[in] SecurityDescriptor
+ * A valid allocated security descriptor structure where the group
+ * is to be retrieved.
+ *
+ * @return
+ * Returns a SID that represents a group.
+ */
static PSID
SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
{
@@ -316,6 +382,16 @@ SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
return Group;
}
+/**
+ * @brief
+ * Retrieves the length size of a set list of privileges structure.
+ *
+ * @param[in] PrivilegeSet
+ * A valid set of privileges.
+ *
+ * @return
+ * Returns the total length of a set of privileges.
+ */
static
ULONG
SepGetPrivilegeSetLength(IN PPRIVILEGE_SET PrivilegeSet)
@@ -332,8 +408,47 @@ SepGetPrivilegeSetLength(IN PPRIVILEGE_SET PrivilegeSet)
/* PUBLIC FUNCTIONS ***********************************************************/
-/*
- * @implemented
+/**
+ * @brief
+ * Determines whether security access rights can be given to an object
+ * depending on the security descriptor and other security context
+ * entities, such as an owner.
+ *
+ * @param[in] SecurityDescriptor
+ * Security descriptor of the object that is being accessed.
+ *
+ * @param[in] SubjectSecurityContext
+ * The captured subject security context.
+ *
+ * @param[in] SubjectContextLocked
+ * If set to TRUE, a lock must be acquired for the security subject
+ * context.
+ *
+ * @param[in] DesiredAccess
+ * Access right bitmask that the calling thread wants to acquire.
+ *
+ * @param[in] PreviouslyGrantedAccess
+ * The access rights previously acquired in the past.
+ *
+ * @param[out] Privileges
+ * The returned set of privileges.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights of an object type.
+ *
+ * @param[in] AccessMode
+ * The processor request level mode.
+ *
+ * @param[out] GrantedAccess
+ * A list of granted access rights.
+ *
+ * @param[out] AccessStatus
+ * The returned status code specifying why access cannot be made
+ * onto an object (if said access is denied in the first place).
+ *
+ * @return
+ * Returns TRUE if access onto the specific object is allowed, FALSE
+ * otherwise.
*/
BOOLEAN
NTAPI
@@ -452,8 +567,29 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
return ret;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Determines whether security access rights can be given to an object
+ * depending on the security descriptor. Unlike the regular access check
+ * procedure in the NT kernel, the fast traverse check is a faster way
+ * to quickly check if access can be made into an object.
+ *
+ * @param[in] SecurityDescriptor
+ * Security descriptor of the object that is being accessed.
+ *
+ * @param[in] AccessState
+ * An access state to determine if the access token in the current
+ * security context of the object is an restricted token.
+ *
+ * @param[in] DesiredAccess
+ * The access right bitmask where the calling thread wants to acquire.
+ *
+ * @param[in] AccessMode
+ * Process level request mode.
+ *
+ * @return
+ * Returns TRUE if access onto the specific object is allowed, FALSE
+ * otherwise.
*/
BOOLEAN
NTAPI
@@ -521,8 +657,48 @@ SeFastTraverseCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
/* SYSTEM CALLS ***************************************************************/
-/*
- * @implemented
+/**
+ * @brief
+ * Determines whether security access rights can be given to an object
+ * depending on the security descriptor and a valid handle to an access
+ * token.
+ *
+ * @param[in] SecurityDescriptor
+ * Security descriptor of the object that is being accessed.
+ *
+ * @param[in] TokenHandle
+ * A handle to a token.
+ *
+ * @param[in] DesiredAccess
+ * The access right bitmask where the calling thread wants to acquire.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights of an object type.
+ *
+ * @param[out] PrivilegeSet
+ * The returned set of privileges.
+ *
+ * @param[in,out] PrivilegeSetLength
+ * The total length size of a set of privileges.
+ *
+ * @param[out] GrantedAccess
+ * A list of granted access rights.
+ *
+ * @param[out] AccessStatus
+ * The returned status code specifying why access cannot be made
+ * onto an object (if said access is denied in the first place).
+ *
+ * @return
+ * Returns STATUS_SUCCESS if access check has been done without problems
+ * and that the object can be accessed. STATUS_GENERIC_NOT_MAPPED is returned
+ * if no generic access right is mapped. STATUS_NO_IMPERSONATION_TOKEN is returned
+ * if the token from the handle is not an impersonation token.
+ * STATUS_BAD_IMPERSONATION_LEVEL is returned if the token cannot be impersonated
+ * because the current security impersonation level doesn't permit so.
+ * STATUS_INVALID_SECURITY_DESCR is returned if the security descriptor given
+ * to the call is not a valid one. STATUS_BUFFER_TOO_SMALL is returned if
+ * the buffer to the captured privileges has a length that is less than the required
+ * size of the set of privileges. A failure NTSTATUS code is returned otherwise.
*/
NTSTATUS
NTAPI
@@ -768,7 +944,48 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
return STATUS_SUCCESS;
}
-
+/**
+ * @brief
+ * Determines whether security access could be granted or not on
+ * an object by the requestor who wants such access through type.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor with information data for auditing.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self user SID.
+ *
+ * @param[in] ClientToken
+ * A client access token.
+ *
+ * @param[in] DesiredAccess
+ * The desired access masks rights requested by the caller.
+ *
+ * @param[in] ObjectTypeList
+ * A list of object types.
+ *
+ * @param[in] ObjectTypeLength
+ * The length size of the list.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping list of access masks rights.
+ *
+ * @param[in] PrivilegeSet
+ * An array set of privileges.
+ *
+ * @param[in,out] PrivilegeSetLength
+ * The length size of the array set of privileges.
+ *
+ * @param[out] GrantedAccess
+ * The returned granted access rights.
+ *
+ * @param[out] AccessStatus
+ * The returned NTSTATUS code indicating the final results
+ * of auditing.
+ *
+ * @return
+ * To be added...
+ */
NTSTATUS
NTAPI
NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
@@ -787,6 +1004,49 @@ NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
return STATUS_NOT_IMPLEMENTED;
}
+/**
+ * @brief
+ * Determines whether security access could be granted or not on
+ * an object by the requestor who wants such access through
+ * type list.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor with information data for auditing.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self user SID.
+ *
+ * @param[in] ClientToken
+ * A client access token.
+ *
+ * @param[in] DesiredAccess
+ * The desired access masks rights requested by the caller.
+ *
+ * @param[in] ObjectTypeList
+ * A list of object types.
+ *
+ * @param[in] ObjectTypeLength
+ * The length size of the list.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping list of access masks rights.
+ *
+ * @param[in] PrivilegeSet
+ * An array set of privileges.
+ *
+ * @param[in,out] PrivilegeSetLength
+ * The length size of the array set of privileges.
+ *
+ * @param[out] GrantedAccess
+ * The returned granted access rights.
+ *
+ * @param[out] AccessStatus
+ * The returned NTSTATUS code indicating the final results
+ * of auditing.
+ *
+ * @return
+ * To be added...
+ */
NTSTATUS
NTAPI
NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
diff --git a/ntoskrnl/se/acl.c b/ntoskrnl/se/acl.c
index 1da423b43c2..f68cc40695e 100644
--- a/ntoskrnl/se/acl.c
+++ b/ntoskrnl/se/acl.c
@@ -1,10 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/acl.c
- * PURPOSE: Security manager
- *
- * PROGRAMMERS: David Welch <welch(a)cwcom.net>
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Access control lists (ACLs) implementation
+ * COPYRIGHT: Copyright David Welch <welch(a)cwcom.net>
*/
/* INCLUDES *******************************************************************/
@@ -25,6 +23,15 @@ PACL SeSystemAnonymousLogonDacl = NULL;
/* FUNCTIONS ******************************************************************/
+/**
+ * @brief
+ * Initializes known discretionary access control lists in the system upon
+ * kernel and Executive initialization procedure.
+ *
+ * @return
+ * Returns TRUE if all the DACLs have been successfully initialized,
+ * FALSE otherwise.
+ */
CODE_SEG("INIT")
BOOLEAN
NTAPI
@@ -246,6 +253,25 @@ SepInitDACLs(VOID)
return TRUE;
}
+/**
+ * @brief
+ * Allocates a discretionary access control list based on certain properties
+ * of a regular and primary access tokens.
+ *
+ * @param[in] Token
+ * An access token.
+ *
+ * @param[in] PrimaryToken
+ * A primary access token.
+ *
+ * @param[out] Dacl
+ * The returned allocated DACL.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if DACL creation from tokens has completed
+ * successfully. STATUS_INSUFFICIENT_RESOURCES is returned if DACL
+ * allocation from memory pool fails otherwise.
+ */
NTSTATUS
NTAPI
SepCreateImpersonationTokenDacl(
@@ -294,6 +320,33 @@ SepCreateImpersonationTokenDacl(
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Captures an access control list from an already valid input ACL.
+ *
+ * @param[in] InputAcl
+ * A valid ACL.
+ *
+ * @param[in] AccessMode
+ * Processor level access mode. The processor mode determines how
+ * are the input arguments probed.
+ *
+ * @param[in] PoolType
+ * Pool type for new captured ACL for creation. The pool type determines
+ * how the ACL data should reside in the pool memory.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE and the processor access mode being KernelMode, we're
+ * capturing an ACL directly in the kernel. Otherwise we're capturing
+ * within a kernel mode driver.
+ *
+ * @param[out] CapturedAcl
+ * The returned and allocated captured ACL.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the ACL has been successfully captured.
+ * STATUS_INSUFFICIENT_RESOURCES is returned otherwise.
+ */
NTSTATUS
NTAPI
SepCaptureAcl(IN PACL InputAcl,
@@ -382,6 +435,24 @@ SepCaptureAcl(IN PACL InputAcl,
return Status;
}
+/**
+ * @brief
+ * Releases (frees) a captured ACL from the memory pool.
+ *
+ * @param[in] CapturedAcl
+ * A valid captured ACL to free.
+ *
+ * @param[in] AccessMode
+ * Processor level access mode.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE and the processor access mode being KernelMode, we're
+ * releasing an ACL directly in the kernel. Otherwise we're releasing
+ * within a kernel mode driver.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepReleaseAcl(IN PACL CapturedAcl,
@@ -398,6 +469,29 @@ SepReleaseAcl(IN PACL CapturedAcl,
}
}
+/**
+ * @brief
+ * Determines if a certain ACE can or cannot be propagated based on
+ * ACE inheritation flags and whatnot.
+ *
+ * @param[in] AceFlags
+ * Bit flags of an ACE to perform propagation checks.
+ *
+ * @param[out] NewAceFlags
+ * New ACE bit blags based on the specific ACE flags of the first
+ * argument parameter.
+ *
+ * @param[in] IsInherited
+ * If set to TRUE, an ACE is deemed as directly inherited from another
+ * instance. In that case we're allowed to propagate.
+ *
+ * @param[in] IsDirectoryObject
+ * If set to TRUE, an object directly inherits this ACE so we can propagate
+ * it.
+ *
+ * @return
+ * Returns TRUE if an ACE can be propagated, FALSE otherwise.
+ */
BOOLEAN
SepShouldPropagateAce(
_In_ UCHAR AceFlags,
@@ -446,6 +540,42 @@ SepShouldPropagateAce(
return FALSE;
}
+/**
+ * @brief
+ * Propagates (copies) an access control list.
+ *
+ * @param[out] AclDest
+ * The destination parameter with propagated ACL.
+ *
+ * @param[in,out] AclLength
+ * The length of the ACL that we propagate.
+ *
+ * @param[in] AclSource
+ * The source instance of a valid ACL.
+ *
+ * @param[in] Owner
+ * A SID that represents the main user that identifies the ACL.
+ *
+ * @param[in] Group
+ * A SID that represents a group that identifies the ACL.
+ *
+ * @param[in] IsInherited
+ * If set to TRUE, that means the ACL is directly inherited.
+ *
+ * @param[in] IsDirectoryObject
+ * If set to TRUE, that means the ACL is directly inherited because
+ * of the object that inherits it.
+ *
+ * @param[in] GenericMapping
+ * Generic mapping of access rights to map only certain effective
+ * ACEs.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if ACL has been propagated successfully.
+ * STATUS_BUFFER_TOO_SMALL is returned if the ACL length is not greater
+ * than the maximum written size of the buffer for ACL propagation
+ * otherwise.
+ */
NTSTATUS
SepPropagateAcl(
_Out_writes_bytes_opt_(AclLength) PACL AclDest,
@@ -609,6 +739,60 @@ SepPropagateAcl(
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Selects an ACL and returns it to the caller.
+ *
+ * @param[in] ExplicitAcl
+ * If specified, the specified ACL to the call will be
+ * the selected ACL for the caller.
+ *
+ * @param[in] ExplicitPresent
+ * If set to TRUE and with specific ACL filled to the call, the
+ * function will immediately return the specific ACL as the selected
+ * ACL for the caller.
+ *
+ * @param[in] ExplicitDefaulted
+ * If set to FALSE and with specific ACL filled to the call, the ACL
+ * is not a default ACL. Otherwise it's a default ACL that we cannot
+ * select it as is.
+ *
+ * @param[in] ParentAcl
+ * If specified, the parent ACL will be used to determine the exact ACL
+ * length to check if the ACL in question is not empty. If the list
+ * is not empty then the function will select such ACL to the caller.
+ *
+ * @param[in] DefaultAcl
+ * If specified, the default ACL will be the selected one for the caller.
+ *
+ * @param[out] AclLength
+ * The size length of an ACL.
+ *
+ * @param[in] Owner
+ * A SID that represents the main user that identifies the ACL.
+ *
+ * @param[in] Group
+ * A SID that represents a group that identifies the ACL.
+ *
+ * @param[out] AclPresent
+ * The returned boolean value, indicating if the ACL that we want to select
+ * does actually exist.
+ *
+ * @param[out] IsInherited
+ * The returned boolean value, indicating if the ACL we want to select it
+ * is actually inherited or not.
+ *
+ * @param[in] IsDirectoryObject
+ * If set to TRUE, the object inherits this ACL.
+ *
+ * @param[in] GenericMapping
+ * Generic mapping of access rights to map only certain effective
+ * ACEs of an ACL that we want to select it.
+ *
+ * @return
+ * Returns the selected access control list (ACL) to the caller,
+ * NULL otherwise.
+ */
PACL
SepSelectAcl(
_In_opt_ PACL ExplicitAcl,
diff --git a/ntoskrnl/se/audit.c b/ntoskrnl/se/audit.c
index 03604d30259..a7123d0a19b 100644
--- a/ntoskrnl/se/audit.c
+++ b/ntoskrnl/se/audit.c
@@ -1,11 +1,9 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/audit.c
- * PURPOSE: Audit functions
- *
- * PROGRAMMERS: Eric Kohl
- * Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Security auditing functions
+ * COPYRIGHT: Copyright Eric Kohl
+ * Copyright Timo Kreuzer <timo.kreuzer(a)reactos.org>
*/
/* INCLUDES *******************************************************************/
@@ -20,6 +18,17 @@ UNICODE_STRING SeSubsystemName =
RTL_CONSTANT_STRING(L"Security");
/* PRIVATE FUNCTIONS***********************************************************/
+/**
+ * @unimplemented
+ * @brief
+ * Peforms a detailed security auditing with an access token.
+ *
+ * @param[in] Token
+ * A valid token object.
+ *
+ * @return
+ * To be added...
+ */
BOOLEAN
NTAPI
SeDetailedAuditingWithToken(IN PTOKEN Token)
@@ -28,6 +37,19 @@ SeDetailedAuditingWithToken(IN PTOKEN Token)
return FALSE;
}
+/**
+ * @unimplemented
+ * @brief
+ * Peforms a security auditing against a process that is about to
+ * be created.
+ *
+ * @param[in] Process
+ * An object that points to a process which is in process of
+ * creation.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeAuditProcessCreate(IN PEPROCESS Process)
@@ -35,6 +57,19 @@ SeAuditProcessCreate(IN PEPROCESS Process)
/* FIXME */
}
+/**
+ * @unimplemented
+ * @brief
+ * Peforms a security auditing against a process that is about to
+ * be terminated.
+ *
+ * @param[in] Process
+ * An object that points to a process which is in process of
+ * termination.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeAuditProcessExit(IN PEPROCESS Process)
@@ -42,6 +77,26 @@ SeAuditProcessExit(IN PEPROCESS Process)
/* FIXME */
}
+/**
+ * @brief
+ * Initializes a process audit name and returns it to the caller.
+ *
+ * @param[in] FileObject
+ * File object that points to a name to be queried.
+ *
+ * @param[in] DoAudit
+ * If set to TRUE, the function will perform various security
+ * auditing onto the audit name.
+ *
+ * @param[out] AuditInfo
+ * The returned audit info data.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if process audit name initialization
+ * has completed successfully. STATUS_NO_MEMORY is returned if
+ * pool allocation for object name info has failed. A failure
+ * NTSTATUS code is returned otherwise.
+ */
NTSTATUS
NTAPI
SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject,
@@ -117,6 +172,24 @@ SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject,
return Status;
}
+/**
+ * @brief
+ * Finds the process image name of a specific process.
+ *
+ * @param[in] Process
+ * Process object submitted by the caller, where the image name
+ * is to be located.
+ *
+ * @param[out] ProcessImageName
+ * An output Unicode string structure with the located process
+ * image name.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if process image name has been located
+ * successfully. STATUS_NO_MEMORY is returned if pool allocation
+ * for the image name has failed. A failure NTSTATUS code is
+ * returned otherwise.
+ */
NTSTATUS
NTAPI
SeLocateProcessImageName(IN PEPROCESS Process,
@@ -185,6 +258,25 @@ SeLocateProcessImageName(IN PEPROCESS Process,
return Status;
}
+/**
+ * @brief
+ * Closes an audit alarm event of an object.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string pointing to the name of the subsystem where auditing
+ * alarm event has to be closed.
+ *
+ * @param[in] HandleId
+ * A handle to an ID where such ID represents the identification of the
+ * object where audit alarm is to be closed.
+ *
+ * @param[in] Sid
+ * A SID that represents the user who attempted to close the audit
+ * alarm.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepAdtCloseObjectAuditAlarm(
@@ -195,6 +287,41 @@ SepAdtCloseObjectAuditAlarm(
UNIMPLEMENTED;
}
+/**
+ * @brief
+ * Performs an audit alarm to a privileged service request.
+ * This is a worker function.
+ *
+ * @param[in] SubjectContext
+ * A security subject context used for the auditing process.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that represents the name of a subsystem that
+ * actuated the procedure of alarm auditing of a privileged
+ * service.
+ *
+ * @param[in] ServiceName
+ * A Unicode string that represents the name of a privileged
+ * service request for auditing.
+ *
+ * @param[in] Token
+ * An access token.
+ *
+ * @param[in] PrimaryToken
+ * A primary access token.
+ *
+ * @param[in] Privileges
+ * An array set of privileges used to check if the privileged
+ * service does actually have all the required set of privileges
+ * for security access.
+ *
+ * @param[in] AccessGranted
+ * When auditing is done, the function will return TRUE to the caller
+ * if access is granted, FALSE otherwise.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepAdtPrivilegedServiceAuditAlarm(
@@ -209,6 +336,29 @@ SepAdtPrivilegedServiceAuditAlarm(
DPRINT("SepAdtPrivilegedServiceAuditAlarm is unimplemented\n");
}
+/**
+ * @brief
+ * Performs an audit alarm to a privileged service request.
+ *
+ * @param[in] ServiceName
+ * A Unicode string that represents the name of a privileged
+ * service request for auditing.
+ *
+ * @param[in] SubjectContext
+ * A security subject context used for the auditing process.
+ *
+ * @param[in] PrivilegeSet
+ * An array set of privileges used to check if the privileged
+ * service does actually have all the required set of privileges
+ * for security access.
+ *
+ * @param[in] AccessGranted
+ * When auditing is done, the function will return TRUE to the caller
+ * if access is granted, FALSE otherwise.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SePrivilegedServiceAuditAlarm(
@@ -256,7 +406,28 @@ SePrivilegedServiceAuditAlarm(
}
-
+/**
+ * @brief
+ * Captures a list of object types.
+ *
+ * @param[in] ObjectTypeList
+ * An existing list of object types.
+ *
+ * @param[in] ObjectTypeListLength
+ * The length size of the list.
+ *
+ * @param[in] PreviousMode
+ * Processor access level mode.
+ *
+ * @param[out] CapturedObjectTypeList
+ * The captured list of object types.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the list of object types has been captured
+ * successfully. STATUS_INVALID_PARAMETER is returned if the caller hasn't
+ * supplied a buffer list of object types. STATUS_INSUFFICIENT_RESOURCES
+ * is returned if pool memory allocation for the captured list has failed.
+ */
static
NTSTATUS
SeCaptureObjectTypeList(
@@ -313,6 +484,19 @@ SeCaptureObjectTypeList(
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Releases a buffer list of object types.
+ *
+ * @param[in] CapturedObjectTypeList
+ * A list of object types to free.
+ *
+ * @param[in] PreviousMode
+ * Processor access level mode.
+ *
+ * @return
+ * Nothing.
+ */
static
VOID
SeReleaseObjectTypeList(
@@ -323,6 +507,78 @@ SeReleaseObjectTypeList(
ExFreePoolWithTag(CapturedObjectTypeList, TAG_SEPA);
}
+/**
+ * @unimplemented
+ * @brief
+ * Worker function that serves as the main heart and brain of the whole
+ * concept and implementation of auditing in the kernel.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that represents the name of a subsystem that
+ * actuates the auditing process.
+ *
+ * @param[in] HandleId
+ * A handle to an ID used to identify an object where auditing
+ * is to be done.
+ *
+ * @param[in] SubjectContext
+ * Security subject context.
+ *
+ * @param[in] ObjectTypeName
+ * A Unicode string that represents the name of an object type.
+ *
+ * @param[in] ObjectName
+ * The name of the object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor with internal security information details
+ * for audit.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self user SID.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] AuditType
+ * Type of audit to start. This parameter influences how an audit
+ * should be done.
+ *
+ * @param[in] HaveAuditPrivilege
+ * If set to TRUE, the security subject context has the audit privilege thus
+ * it is allowed the ability to perform the audit.
+ *
+ * @param[in] ObjectTypeList
+ * A list of object types.
+ *
+ * @param[in] ObjectTypeListLength
+ * The length size of the list.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping table of access rights used whilst performing auditing
+ * sequence procedure.
+ *
+ * @param[out] GrantedAccessList
+ * This parameter is used to return to the caller a list of actual granted access
+ * rights masks that the audited object has.
+ *
+ * @param[out] AccessStatusList
+ * This parameter is used to return to the caller a list of status return codes.
+ * The function may actually return a single NTSTATUS code if the calling thread
+ * sets UseResultList parameter to FALSE.
+ *
+ * @param[out] GenerateOnClose
+ * Returns TRUE if the function has generated a list of granted access rights and
+ * status codes on termination, FALSE otherwise.
+ *
+ * @param[in] UseResultList
+ * If set to TRUE, the caller wants that the function should only return a single
+ * NTSTATUS code.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the function has completed the whole internal
+ * auditing procedure mechanism with success.
+ */
_Must_inspect_result_
static
NTSTATUS
@@ -365,6 +621,89 @@ SepAccessCheckAndAuditAlarmWorker(
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Performs security auditing, if the specific object can be granted
+ * security access or not.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that represents the name of a subsystem that
+ * actuates the auditing process.
+ *
+ * @param[in] HandleId
+ * A handle to an ID used to identify an object where auditing
+ * is to be done.
+ *
+ * @param[in] SubjectContext
+ * Security subject context.
+ *
+ * @param[in] ObjectTypeName
+ * A Unicode string that represents the name of an object type.
+ *
+ * @param[in] ObjectName
+ * The name of the object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor with internal security information details
+ * for audit.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self user SID.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] AuditType
+ * Type of audit to start. This parameter influences how an audit
+ * should be done.
+ *
+ * @param[in] Flags
+ * Flag bitmask parameter.
+ *
+ * @param[in] HaveAuditPrivilege
+ * If set to TRUE, the security subject context has the audit privilege thus
+ * it is allowed the ability to perform the audit.
+ *
+ * @param[in] ObjectTypeList
+ * A list of object types.
+ *
+ * @param[in] ObjectTypeListLength
+ * The length size of the list.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping table of access rights used whilst performing auditing
+ * sequence procedure.
+ *
+ * @param[out] GrantedAccessList
+ * This parameter is used to return to the caller a list of actual granted access
+ * rights masks that the audited object has.
+ *
+ * @param[out] AccessStatusList
+ * This parameter is used to return to the caller a list of status return codes.
+ * The function may actually return a single NTSTATUS code if the calling thread
+ * sets UseResultList parameter to FALSE.
+ *
+ * @param[out] GenerateOnClose
+ * Returns TRUE if the function has generated a list of granted access rights and
+ * status codes on termination, FALSE otherwise.
+ *
+ * @param[in] UseResultList
+ * If set to TRUE, the caller wants that the function should only return a single
+ * NTSTATUS code.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the function has completed the whole internal
+ * auditing procedure mechanism with success. STATUS_INVALID_PARAMETER is
+ * returned if one of the parameters do not satisfy the general requirements
+ * by the function. STATUS_INSUFFICIENT_RESOURCES is returned if pool memory
+ * allocation has failed. STATUS_PRIVILEGE_NOT_HELD is returned if the current
+ * security subject context does not have the required audit privilege to actually
+ * perform auditing in the first place. STATUS_INVALID_SECURITY_DESCR is returned
+ * if the security descriptor provided by the caller is not valid, that is, such
+ * descriptor doesn't belong to the main user (owner) and current group.
+ * STATUS_GENERIC_NOT_MAPPED is returned if the access rights masks aren't actually
+ * mapped. A failure NTSTATUS code is returned otherwise.
+ */
_Must_inspect_result_
NTSTATUS
NTAPI
@@ -700,8 +1039,24 @@ Cleanup:
/* PUBLIC FUNCTIONS ***********************************************************/
-/*
+/**
* @unimplemented
+ * @brief
+ * Performs an audit against a hard link creation.
+ *
+ * @param[in] FileName
+ * A Unicode string that points to the name of the file.
+ *
+ * @param[in] LinkName
+ * A Unicode string that points to a link.
+ *
+ * @param[out] bSuccess
+ * If TRUE, the function has successfully audited
+ * the hard link and security access can be granted,
+ * FALSE otherwise.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -712,8 +1067,21 @@ SeAuditHardLinkCreation(IN PUNICODE_STRING FileName,
UNIMPLEMENTED;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Determines whether auditing against file events is being
+ * done or not.
+ *
+ * @param[in] AccessGranted
+ * If set to TRUE, the access attempt is deemed as successful
+ * otherwise set it to FALSE.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @return
+ * Returns TRUE if auditing is being currently done, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -724,8 +1092,25 @@ SeAuditingFileEvents(IN BOOLEAN AccessGranted,
return FALSE;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Determines whether auditing against file events with subject context
+ * is being done or not.
+ *
+ * @param[in] AccessGranted
+ * If set to TRUE, the access attempt is deemed as successful
+ * otherwise set it to FALSE.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] SubjectSecurityContext
+ * If specified, the function will check if security auditing is currently
+ * being done with this context.
+ *
+ * @return
+ * Returns TRUE if auditing is being currently done, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -737,8 +1122,21 @@ SeAuditingFileEventsWithContext(IN BOOLEAN AccessGranted,
return FALSE;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Determines whether auditing against hard links events is being
+ * done or not.
+ *
+ * @param[in] AccessGranted
+ * If set to TRUE, the access attempt is deemed as successful
+ * otherwise set it to FALSE.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @return
+ * Returns TRUE if auditing is being currently done, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -749,8 +1147,25 @@ SeAuditingHardLinkEvents(IN BOOLEAN AccessGranted,
return FALSE;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Determines whether auditing against hard links events with subject context
+ * is being done or not.
+ *
+ * @param[in] AccessGranted
+ * If set to TRUE, the access attempt is deemed as successful
+ * otherwise set it to FALSE.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] SubjectSecurityContext
+ * If specified, the function will check if security auditing is currently
+ * being done with this context.
+ *
+ * @return
+ * Returns TRUE if auditing is being currently done, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -762,8 +1177,25 @@ SeAuditingHardLinkEventsWithContext(IN BOOLEAN AccessGranted,
return FALSE;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Determines whether auditing against files or global events with
+ * subject context is being done or not.
+ *
+ * @param[in] AccessGranted
+ * If set to TRUE, the access attempt is deemed as successful
+ * otherwise set it to FALSE.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] SubjectSecurityContext
+ * If specified, the function will check if security auditing is currently
+ * being done with this context.
+ *
+ * @return
+ * Returns TRUE if auditing is being currently done, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -775,8 +1207,23 @@ SeAuditingFileOrGlobalEvents(IN BOOLEAN AccessGranted,
return FALSE;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Closes an alarm audit of an object.
+ *
+ * @param[in] Object
+ * An arbitrary pointer data that points to the object.
+ *
+ * @param[in] Handle
+ * A handle of the said object.
+ *
+ * @param[in] PerformAction
+ * Set this to TRUE to perform any auxiliary action, otherwise
+ * set to FALSE.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -787,8 +1234,19 @@ SeCloseObjectAuditAlarm(IN PVOID Object,
UNIMPLEMENTED;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Deletes an alarm audit of an object.
+ *
+ * @param[in] Object
+ * An arbitrary pointer data that points to the object.
+ *
+ * @param[in] Handle
+ * A handle of the said object.
+ *
+ * @return
+ * Nothing.
*/
VOID NTAPI
SeDeleteObjectAuditAlarm(IN PVOID Object,
@@ -797,8 +1255,46 @@ SeDeleteObjectAuditAlarm(IN PVOID Object,
UNIMPLEMENTED;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Creates an audit with alarm notification of an object
+ * that is being opened.
+ *
+ * @param[in] ObjectTypeName
+ * A Unicode string that points to the object type name.
+ *
+ * @param[in] Object
+ * If specified, the function will use this parameter to
+ * directly open the object.
+ *
+ * @param[in] AbsoluteObjectName
+ * If specified, the function will use this parameter to
+ * directly open the object through the absolute name
+ * of the object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] AccessState
+ * An access state right mask when opening the object.
+ *
+ * @param[in] ObjectCreated
+ * Set this to TRUE if the object has been fully created,
+ * FALSE otherwise.
+ *
+ * @param[in] AccessGranted
+ * Set this to TRUE if access was deemed as granted.
+ *
+ * @param[in] AccessMode
+ * Processor level access mode.
+ *
+ * @param[out] GenerateOnClose
+ * A boolean flag returned to the caller once audit generation procedure
+ * finishes.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -822,8 +1318,46 @@ SeOpenObjectAuditAlarm(IN PUNICODE_STRING ObjectTypeName,
return;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Creates an audit with alarm notification of an object
+ * that is being opened for deletion.
+ *
+ * @param[in] ObjectTypeName
+ * A Unicode string that points to the object type name.
+ *
+ * @param[in] Object
+ * If specified, the function will use this parameter to
+ * directly open the object.
+ *
+ * @param[in] AbsoluteObjectName
+ * If specified, the function will use this parameter to
+ * directly open the object through the absolute name
+ * of the object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] AccessState
+ * An access state right mask when opening the object.
+ *
+ * @param[in] ObjectCreated
+ * Set this to TRUE if the object has been fully created,
+ * FALSE otherwise.
+ *
+ * @param[in] AccessGranted
+ * Set this to TRUE if access was deemed as granted.
+ *
+ * @param[in] AccessMode
+ * Processor level access mode.
+ *
+ * @param[out] GenerateOnClose
+ * A boolean flag returned to the caller once audit generation procedure
+ * finishes.
+ *
+ * @return
+ * Nothing.
*/
VOID NTAPI
SeOpenObjectForDeleteAuditAlarm(IN PUNICODE_STRING ObjectTypeName,
@@ -839,8 +1373,34 @@ SeOpenObjectForDeleteAuditAlarm(IN PUNICODE_STRING ObjectTypeName,
UNIMPLEMENTED;
}
-/*
+/**
* @unimplemented
+ * @brief
+ * Raises an audit with alarm notification message
+ * when an object tries to acquire this privilege.
+ *
+ * @param[in] Handle
+ * A handle to an object.
+ *
+ * @param[in] SubjectContext
+ * The security subject context for auditing.
+ *
+ * @param[in] DesiredAccess
+ * The desired right access masks requested by the caller.
+ *
+ * @param[in] Privileges
+ * An array set of privileges for auditing.
+ *
+ * @param[out] AccessGranted
+ * When the auditing procedure routine ends, it returns TRUE to the
+ * caller if the object has the required privileges for access,
+ * FALSE otherwise.
+ *
+ * @param[in] CurrentMode
+ * Processor level access mode.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -856,6 +1416,28 @@ SePrivilegeObjectAuditAlarm(IN HANDLE Handle,
/* SYSTEM CALLS ***************************************************************/
+/**
+ * @brief
+ * Raises an alarm audit message when an object is about
+ * to be closed.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to the name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle of an ID used for identification instance for auditing.
+ *
+ * @param[in] GenerateOnClose
+ * A boolean value previously created by the "open" equivalent of this
+ * function. If the caller explicitly sets this to FALSE, the function
+ * assumes that the object is not opened.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if all the operations have completed successfully.
+ * STATUS_PRIVILEGE_NOT_HELD is returned if the security subject context
+ * does not have the audit privilege to actually begin auditing procedures
+ * in the first place.
+ */
NTSTATUS
NTAPI
NtCloseObjectAuditAlarm(
@@ -954,7 +1536,26 @@ Cleanup:
return Status;
}
-
+/**
+ * @unimplemented
+ * @brief
+ * Raises an alarm audit message when an object is about
+ * to be deleted.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to the name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle of an ID used for identification instance for auditing.
+ *
+ * @param[in] GenerateOnClose
+ * A boolean value previously created by the "open" equivalent of this
+ * function. If the caller explicitly sets this to FALSE, the function
+ * assumes that the object is not opened.
+ *
+ * @return
+ * To be added...
+ */
NTSTATUS NTAPI
NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
IN PVOID HandleId,
@@ -964,6 +1565,55 @@ NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
return STATUS_NOT_IMPLEMENTED;
}
+/**
+ * @unimplemented
+ * @brief
+ * Raises an alarm audit message when an object is about
+ * to be opened.
+ *
+ * @param[in] SubjectContext
+ * A security subject context for auditing.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle to an ID used for identification instance for auditing.
+ *
+ * @param[in] ObjectTypeName
+ * A Unicode string that points to an object type name.
+ *
+ * @param[in] ObjectName
+ * The name of the object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] ClientToken
+ * A client access token, representing the client we want to impersonate.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] GrantedAccess
+ * The granted access mask rights.
+ *
+ * @param[in] Privileges
+ * If specified, the function will use this set of privileges to audit.
+ *
+ * @param[in] ObjectCreation
+ * Set this to TRUE if the object has just been created.
+ *
+ * @param[in] AccessGranted
+ * Set this to TRUE if the access attempt was deemed as granted.
+ *
+ * @param[out] GenerateOnClose
+ * A boolean flag returned to the caller once audit generation procedure
+ * finishes.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepOpenObjectAuditAlarm(
@@ -997,6 +1647,59 @@ SepOpenObjectAuditAlarm(
*GenerateOnClose = FALSE;
}
+/**
+ * @brief
+ * Raises an alarm audit message when an object is about
+ * to be opened.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle to an ID used for identification instance for auditing.
+ *
+ * @param[in] ObjectTypeName
+ * A Unicode string that points to an object type name.
+ *
+ * @param[in] ObjectName
+ * The name of the object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] ClientTokenHandle
+ * A handle to a client access token.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] GrantedAccess
+ * The granted access mask rights.
+ *
+ * @param[in] PrivilegeSet
+ * If specified, the function will use this set of privileges to audit.
+ *
+ * @param[in] ObjectCreation
+ * Set this to TRUE if the object has just been created.
+ *
+ * @param[in] AccessGranted
+ * Set this to TRUE if the access attempt was deemed as granted.
+ *
+ * @param[out] GenerateOnClose
+ * A boolean flag returned to the caller once audit generation procedure
+ * finishes.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if all the operations have been completed successfully.
+ * STATUS_PRIVILEGE_NOT_HELD is returned if the given subject context does not
+ * hold the required audit privilege to actually begin auditing in the first place.
+ * STATUS_BAD_IMPERSONATION_LEVEL is returned if the security impersonation level
+ * of the client token is not on par with the impersonation level that alllows
+ * impersonation. STATUS_INVALID_PARAMETER is returned if the caller has
+ * submitted a bogus set of privileges as such array set exceeds the maximum
+ * count of privileges that the kernel can accept. A failure NTSTATUS code
+ * is returned otherwise.
+ */
__kernel_entry
NTSTATUS
NTAPI
@@ -1227,7 +1930,37 @@ Cleanup:
return Status;
}
-
+/**
+ * @brief
+ * Raises an alarm audit message when a caller attempts to request
+ * a privileged service call.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] ServiceName
+ * A Unicode string that points to a name of the privileged service.
+ *
+ * @param[in] ClientTokenHandle
+ * A handle to a client access token.
+ *
+ * @param[in] Privileges
+ * An array set of privileges.
+ *
+ * @param[in] AccessGranted
+ * Set this to TRUE if the access attempt was deemed as granted.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if all the operations have been completed successfully.
+ * STATUS_PRIVILEGE_NOT_HELD is returned if the given subject context does not
+ * hold the required audit privilege to actually begin auditing in the first place.
+ * STATUS_BAD_IMPERSONATION_LEVEL is returned if the security impersonation level
+ * of the client token is not on par with the impersonation level that alllows
+ * impersonation. STATUS_INVALID_PARAMETER is returned if the caller has
+ * submitted a bogus set of privileges as such array set exceeds the maximum
+ * count of privileges that the kernel can accept. A failure NTSTATUS code
+ * is returned otherwise.
+ */
__kernel_entry
NTSTATUS
NTAPI
@@ -1387,7 +2120,32 @@ Cleanup:
return Status;
}
-
+/**
+ * @brief
+ * Raises an alarm audit message when a caller attempts to access a
+ * privileged object.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle to an ID that is used as identification instance for auditing.
+ *
+ * @param[in] ClientToken
+ * A handle to a client access token.
+ *
+ * @param[in] DesiredAccess
+ * A handle to a client access token.
+ *
+ * @param[in] Privileges
+ * An array set of privileges.
+ *
+ * @param[in] AccessGranted
+ * Set this to TRUE if the access attempt was deemed as granted.
+ *
+ * @return
+ * To be added...
+ */
NTSTATUS NTAPI
NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
IN PVOID HandleId,
@@ -1400,7 +2158,49 @@ NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
return STATUS_NOT_IMPLEMENTED;
}
-
+/**
+ * @brief
+ * Raises an alarm audit message when a caller attempts to access an
+ * object and determine if the access can be made.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle to an ID that is used as identification instance for auditing.
+ *
+ * @param[in] ObjectTypeName
+ * The name of the object type.
+ *
+ * @param[in] ObjectName
+ * The object name.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access mask rights.
+ *
+ * @param[in] ObjectCreation
+ * Set this to TRUE if the object has just been created.
+ *
+ * @param[out] GrantedAccess
+ * Returns the granted access rights.
+ *
+ * @param[out] AccessStatus
+ * Returns a NTSTATUS status code indicating whether access check
+ * can be granted or not.
+ *
+ * @param[out] GenerateOnClose
+ * Returns TRUE if the function has generated a list of granted access rights and
+ * status codes on termination, FALSE otherwise.
+ *
+ * @return
+ * See SepAccessCheckAndAuditAlarm.
+ */
_Must_inspect_result_
__kernel_entry
NTSTATUS
@@ -1438,6 +2238,66 @@ NtAccessCheckAndAuditAlarm(
FALSE);
}
+/**
+ * @brief
+ * Raises an alarm audit message when a caller attempts to access an
+ * object and determine if the access can be made by type.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle to an ID that is used as identification instance for auditing.
+ *
+ * @param[in] ObjectTypeName
+ * The name of the object type.
+ *
+ * @param[in] ObjectName
+ * The object name.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self user SID.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] AuditType
+ * Type of audit to start, influencing how the audit should
+ * be done.
+ *
+ * @param[in] Flags
+ * Flag bitmask, used to check if auditing can be done
+ * without privileges.
+ *
+ * @param[in] ObjectTypeList
+ * A list of object types.
+ *
+ * @param[in] ObjectTypeLength
+ * The length size of the list.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access mask rights.
+ *
+ * @param[in] ObjectCreation
+ * Set this to TRUE if the object has just been created.
+ *
+ * @param[out] GrantedAccess
+ * Returns the granted access rights.
+ *
+ * @param[out] AccessStatus
+ * Returns a NTSTATUS status code indicating whether access check
+ * can be granted or not.
+ *
+ * @param[out] GenerateOnClose
+ * Returns TRUE if the function has generated a list of granted access rights and
+ * status codes on termination, FALSE otherwise.
+ *
+ * @return
+ * See SepAccessCheckAndAuditAlarm.
+ */
_Must_inspect_result_
__kernel_entry
NTSTATUS
@@ -1480,6 +2340,66 @@ NtAccessCheckByTypeAndAuditAlarm(
FALSE);
}
+/**
+ * @brief
+ * Raises an alarm audit message when a caller attempts to access an
+ * object and determine if the access can be made by given type result.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle to an ID that is used as identification instance for auditing.
+ *
+ * @param[in] ObjectTypeName
+ * The name of the object type.
+ *
+ * @param[in] ObjectName
+ * The object name.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self user SID.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] AuditType
+ * Type of audit to start, influencing how the audit should
+ * be done.
+ *
+ * @param[in] Flags
+ * Flag bitmask, used to check if auditing can be done
+ * without privileges.
+ *
+ * @param[in] ObjectTypeList
+ * A list of object types.
+ *
+ * @param[in] ObjectTypeLength
+ * The length size of the list.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access mask rights.
+ *
+ * @param[in] ObjectCreation
+ * Set this to TRUE if the object has just been created.
+ *
+ * @param[out] GrantedAccessList
+ * Returns the granted access rights.
+ *
+ * @param[out] AccessStatusList
+ * Returns a NTSTATUS status code indicating whether access check
+ * can be granted or not.
+ *
+ * @param[out] GenerateOnClose
+ * Returns TRUE if the function has generated a list of granted access rights and
+ * status codes on termination, FALSE otherwise.
+ *
+ * @return
+ * See SepAccessCheckAndAuditAlarm.
+ */
_Must_inspect_result_
__kernel_entry
NTSTATUS
@@ -1522,6 +2442,70 @@ NtAccessCheckByTypeResultListAndAuditAlarm(
TRUE);
}
+/**
+ * @brief
+ * Raises an alarm audit message when a caller attempts to access an
+ * object and determine if the access can be made by given type result
+ * and a token handle.
+ *
+ * @param[in] SubsystemName
+ * A Unicode string that points to a name of the subsystem.
+ *
+ * @param[in] HandleId
+ * A handle to an ID that is used as identification instance for auditing.
+ *
+ * @param[in] ClientToken
+ * A handle to a client access token.
+ *
+ * @param[in] ObjectTypeName
+ * The name of the object type.
+ *
+ * @param[in] ObjectName
+ * The object name.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[in] PrincipalSelfSid
+ * A principal self user SID.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights masks requested by the caller.
+ *
+ * @param[in] AuditType
+ * Type of audit to start, influencing how the audit should
+ * be done.
+ *
+ * @param[in] Flags
+ * Flag bitmask, used to check if auditing can be done
+ * without privileges.
+ *
+ * @param[in] ObjectTypeList
+ * A list of object types.
+ *
+ * @param[in] ObjectTypeLength
+ * The length size of the list.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access mask rights.
+ *
+ * @param[in] ObjectCreation
+ * Set this to TRUE if the object has just been created.
+ *
+ * @param[out] GrantedAccessList
+ * Returns the granted access rights.
+ *
+ * @param[out] AccessStatusList
+ * Returns a NTSTATUS status code indicating whether access check
+ * can be granted or not.
+ *
+ * @param[out] GenerateOnClose
+ * Returns TRUE if the function has generated a list of granted access rights and
+ * status codes on termination, FALSE otherwise.
+ *
+ * @return
+ * See SepAccessCheckAndAuditAlarm.
+ */
_Must_inspect_result_
__kernel_entry
NTSTATUS
diff --git a/ntoskrnl/se/priv.c b/ntoskrnl/se/priv.c
index 53286f5fc84..42f69c5e84a 100644
--- a/ntoskrnl/se/priv.c
+++ b/ntoskrnl/se/priv.c
@@ -1,10 +1,10 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/priv.c
- * PURPOSE: Security manager
- *
- * PROGRAMMERS: No programmer listed.
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Security privileges support
+ * COPYRIGHT: Copyright Alex Ionescu <alex(a)relsoft.net>
+ * Copyright Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ * Copyright Eric Kohl
*/
/* INCLUDES ******************************************************************/
@@ -54,6 +54,15 @@ const LUID SeCreateSymbolicLinkPrivilege =
CONST_LUID(SE_CREATE_SYMBOLIC_LINK_PR
/* PRIVATE FUNCTIONS **********************************************************/
+/**
+ * @brief
+ * Initializes the privileges during the startup phase of the security
+ * manager module. This function serves as a placeholder as it currently
+ * does nothing.
+ *
+ * @return
+ * Nothing.
+ */
CODE_SEG("INIT")
VOID
NTAPI
@@ -62,7 +71,32 @@ SepInitPrivileges(VOID)
}
-
+/**
+ * @brief
+ * Checks the privileges pointed by Privileges array argument if they exist and
+ * match with the privileges from an access token.
+ *
+ * @param[in] Token
+ * An access token where privileges are to be checked.
+ *
+ * @param[in] Privileges
+ * An array of privileges with attributes used as checking indicator for
+ * the function.
+ *
+ * @param[in] PrivilegeCount
+ * The total number count of privileges in the array.
+ *
+ * @param[in] PrivilegeControl
+ * Privilege control bit mask to determine if we should check all the
+ * privileges based on the number count of privileges or not.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns TRUE if the required privileges exist and that they do match.
+ * Otherwise the functions returns FALSE.
+ */
BOOLEAN
NTAPI
SepPrivilegeCheck(PTOKEN Token,
@@ -129,6 +163,25 @@ SepPrivilegeCheck(PTOKEN Token,
return FALSE;
}
+/**
+ * @brief
+ * Checks only single privilege based upon the privilege pointed by a LUID and
+ * if it matches with the one from an access token.
+ *
+ * @param[in] PrivilegeValue
+ * The privilege to be checked.
+ *
+ * @param[in] Token
+ * An access token where its privilege is to be checked against the one
+ * provided by the caller.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns TRUE if the required privilege exists and that it matches
+ * with the one from the access token, FALSE otherwise.
+ */
NTSTATUS
NTAPI
SepSinglePrivilegeCheck(
@@ -149,6 +202,40 @@ SepSinglePrivilegeCheck(
PreviousMode);
}
+/**
+ * @brief
+ * Checks the security policy and returns a set of privileges
+ * based upon the said security policy context.
+ *
+ * @param[in,out] DesiredAccess
+ * The desired access right mask.
+ *
+ * @param[in,out] GrantedAccess
+ * The granted access rights masks. The rights are granted depending
+ * on the desired access rights requested by the calling thread.
+ *
+ * @param[in] SubjectContext
+ * Security subject context. If the caller supplies one, the access token
+ * supplied by the caller will be assigned to one of client or primary tokens
+ * of the subject context in question.
+ *
+ * @param[in] Token
+ * An access token.
+ *
+ * @param[out] OutPrivilegeSet
+ * An array set of privileges to be reported to the caller, if the actual
+ * calling thread wants such set of privileges in the first place.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns STATUS_PRIVILEGE_NOT_HELD if the respective operations have succeeded
+ * without problems. STATUS_PRIVILEGE_NOT_HELD is returned if the access token
+ * doesn't have SeSecurityPrivilege privilege to warrant ACCESS_SYSTEM_SECURITY
+ * access right. STATUS_INSUFFICIENT_RESOURCES is returned if we failed
+ * to allocate block of memory pool for the array set of privileges.
+ */
NTSTATUS
NTAPI
SePrivilegePolicyCheck(
@@ -248,6 +335,23 @@ SePrivilegePolicyCheck(
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Checks a single privilege and performs an audit
+ * against a privileged service based on a security subject
+ * context.
+ *
+ * @param[in] DesiredAccess
+ * Security subject context used for privileged service
+ * auditing.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns TRUE if service auditing and privilege checking
+ * tests have succeeded, FALSE otherwise.
+ */
BOOLEAN
NTAPI
SeCheckAuditPrivilege(
@@ -282,6 +386,48 @@ SeCheckAuditPrivilege(
return Result;
}
+/**
+ * @brief
+ * Captures a LUID with attributes structure. This function is mainly
+ * tied in the context of privileges.
+ *
+ * @param[in] Src
+ * Source of a valid LUID with attributes structure.
+ *
+ * @param[in] PrivilegeCount
+ * Count number of privileges to be captured.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @param[in] AllocatedMem
+ * If specified, the function will use this allocated block memory
+ * buffer for the captured LUID and attributes structure. Otherwise
+ * the function will automatically allocate some buffer for it.
+ *
+ * @param[in] AllocatedLength
+ * The length of the buffer, pointed by AllocatedMem.
+ *
+ * @param[in] PoolType
+ * Pool type of the memory allocation.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE, the capturing is done in the kernel itself.
+ * FALSE if the capturing is done in a kernel mode driver instead.
+ *
+ * @param[out] Dest
+ * The captured LUID with attributes buffer.
+ *
+ * @param[in,out] Length
+ * The length of the captured privileges count.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the LUID and attributes array
+ * has been captured successfully. STATUS_INSUFFICIENT_RESOURCES is returned
+ * if memory pool allocation for the captured buffer has failed.
+ * STATUS_BUFFER_TOO_SMALL is returned if the buffer size is less than the
+ * required size.
+ */
NTSTATUS
NTAPI
SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src,
@@ -378,6 +524,23 @@ SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src,
return Status;
}
+/**
+ * @brief
+ * Releases a LUID with attributes structure.
+ *
+ * @param[in] Privilege
+ * Array of a LUID and attributes that represents a privilege.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE, the releasing is done in the kernel itself.
+ * FALSE if the releasing is done in a kernel mode driver instead.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege,
@@ -395,8 +558,21 @@ SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege,
/* PUBLIC FUNCTIONS ***********************************************************/
-/*
- * @implemented
+/**
+ * @brief
+ * Appends additional privileges.
+ *
+ * @param[in] AccessState
+ * Access request to append.
+ *
+ * @param[in] Privileges
+ * Set of new privileges to append.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the privileges have been successfully
+ * appended. Otherwise STATUS_INSUFFICIENT_RESOURCES is returned,
+ * indicating that pool allocation has failed for the buffer to hold
+ * the new set of privileges.
*/
NTSTATUS
NTAPI
@@ -468,8 +644,15 @@ SeAppendPrivileges(IN OUT PACCESS_STATE AccessState,
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Frees a set of privileges.
+ *
+ * @param[in] Privileges
+ * Set of privileges array to be freed.
+ *
+ * @return
+ * Nothing.
*/
VOID
NTAPI
@@ -479,8 +662,25 @@ SeFreePrivileges(IN PPRIVILEGE_SET Privileges)
ExFreePoolWithTag(Privileges, TAG_PRIVILEGE_SET);
}
-/*
- * @implemented
+/**
+ * @brief
+ * Checks if a set of privileges exist and match within a
+ * security subject context.
+ *
+ * @param[in] Privileges
+ * A set of privileges where the check must be performed
+ * against the subject context.
+ *
+ * @param[in] SubjectContext
+ * A subject security context.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns TRUE if all the privileges do exist and match
+ * with the ones specified by the caller and subject
+ * context, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -512,8 +712,20 @@ SePrivilegeCheck(PPRIVILEGE_SET Privileges,
PreviousMode);
}
-/*
- * @implemented
+/**
+ * @brief
+ * Checks if a single privilege is present in the context
+ * of the calling thread.
+ *
+ * @param[in] PrivilegeValue
+ * The specific privilege to be checked.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns TRUE if the privilege is present, FALSE
+ * otherwise.
*/
BOOLEAN
NTAPI
@@ -551,6 +763,28 @@ SeSinglePrivilegeCheck(IN LUID PrivilegeValue,
return Result;
}
+/**
+ * @brief
+ * Checks a privileged object if such object has
+ * the specific privilege submitted by the caller.
+ *
+ * @param[in] PrivilegeValue
+ * A privilege to be checked against the one from
+ * the object.
+ *
+ * @param[in] ObjectHandle
+ * A handle to any kind of object.
+ *
+ * @param[in] DesiredAccess
+ * Desired access right mask requested by the caller.
+ *
+ * @param[in] PreviousMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns TRUE if the privilege is present, FALSE
+ * otherwise.
+ */
BOOLEAN
NTAPI
SeCheckPrivilegedObject(IN LUID PrivilegeValue,
@@ -591,6 +825,30 @@ SeCheckPrivilegedObject(IN LUID PrivilegeValue,
/* SYSTEM CALLS ***************************************************************/
+/**
+ * @brief
+ * Checks a client access token if it has the required set of
+ * privileges.
+ *
+ * @param[in] ClientToken
+ * A handle to an access client token.
+ *
+ * @param[in] RequiredPrivileges
+ * A set of required privileges to be checked against the privileges
+ * of the access token.
+ *
+ * @param[out] Result
+ * The result, as a boolean value. If TRUE, the token has all the required
+ * privileges, FALSE otherwise.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the function has completed successfully.
+ * STATUS_INVALID_PARAMETER is returned if the set array of required
+ * privileges has a bogus number of privileges, that is, the array
+ * has a count of privileges that exceeds the maximum threshold
+ * (or in other words, an integer overflow). A failure NTSTATUS code
+ * is returned otherwise.
+ */
NTSTATUS
NTAPI
NtPrivilegeCheck(IN HANDLE ClientToken,
diff --git a/ntoskrnl/se/sd.c b/ntoskrnl/se/sd.c
index 72eff599ce5..fc9369d1808 100644
--- a/ntoskrnl/se/sd.c
+++ b/ntoskrnl/se/sd.c
@@ -1,10 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/sd.c
- * PURPOSE: Security manager
- *
- * PROGRAMMERS: David Welch <welch(a)cwcom.net>
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Security descriptors (SDs) implementation support
+ * COPYRIGHT: Copyright David Welch <welch(a)cwcom.net>
*/
/* INCLUDES *******************************************************************/
@@ -25,6 +23,14 @@ PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd = NULL;
/* PRIVATE FUNCTIONS **********************************************************/
+/**
+ * @brief
+ * Initializes the known security descriptors in the system.
+ *
+ * @return
+ * Returns TRUE if all the security descriptors have been initialized,
+ * FALSE otherwise.
+ */
CODE_SEG("INIT")
BOOLEAN
NTAPI
@@ -124,6 +130,26 @@ SepInitSDs(VOID)
return TRUE;
}
+/**
+ * @brief
+ * Sets a "World" security descriptor.
+ *
+ * @param[in] SecurityInformation
+ * Security information details, alongside with the security
+ * descriptor to set the World SD.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor buffer.
+ *
+ * @param[in] BufferLength
+ * Length size of the buffer.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the World security descriptor has been
+ * set. STATUS_ACCESS_DENIED is returned if the caller hasn't
+ * provided security information details thus the SD cannot
+ * be set.
+ */
NTSTATUS
NTAPI
SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
@@ -217,6 +243,23 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION
SecurityInformation,
/* PUBLIC FUNCTIONS ***********************************************************/
+/**
+ * @brief
+ * Determines the size of a SID.
+ *
+ * @param[in] Sid
+ * A security identifier where its size is to be determined.
+ *
+ * @param[in,out] OutSAC
+ * The returned sub authority count of the security
+ * identifier.
+ *
+ * @param[in] ProcessorMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns the size length of a security identifier (SID).
+ */
static
ULONG
DetermineSIDSize(
@@ -248,6 +291,21 @@ DetermineSIDSize(
return Size;
}
+/**
+ * @brief
+ * Determines the size of an ACL.
+ *
+ * @param[in] Acl
+ * An access control list where its size is to be
+ * determined.
+ *
+ * @param[in] ProcessorMode
+ * Processor level access mode.
+ *
+ * @return
+ * Returns the size length of a an access control
+ * list (ACL).
+ */
static
ULONG
DetermineACLSize(
@@ -267,6 +325,37 @@ DetermineACLSize(
return Size;
}
+/**
+ * @brief
+ * Captures a security descriptor.
+ *
+ * @param[in] _OriginalSecurityDescriptor
+ * An already existing and valid security descriptor
+ * to be captured.
+ *
+ * @param[in] CurrentMode
+ * Processor level access mode.
+ *
+ * @param[in] PoolType
+ * Pool type to be used when allocating the captured
+ * buffer.
+ *
+ * @param[in] CaptureIfKernel
+ * Set this to TRUE if capturing is done within the
+ * kernel.
+ *
+ * @param[out] CapturedSecurityDescriptor
+ * The captured security descriptor.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the operations have been
+ * completed successfully and that the security descriptor
+ * has been captured. STATUS_UNKNOWN_REVISION is returned
+ * if the security descriptor has an unknown revision.
+ * STATUS_INSUFFICIENT_RESOURCES is returned if memory
+ * pool allocation for the captured buffer has failed.
+ * A failure NTSTATUS code is returned otherwise.
+ */
NTSTATUS
NTAPI
SeCaptureSecurityDescriptor(
@@ -452,8 +541,32 @@ SeCaptureSecurityDescriptor(
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Queries information details about a security
+ * descriptor.
+ *
+ * @param[in] SecurityInformation
+ * Security information details to be queried
+ * from a security descriptor.
+ *
+ * @param[out] SecurityDescriptor
+ * The returned security descriptor with security information
+ * data.
+ *
+ * @param[in,out] Length
+ * The returned length of a security descriptor.
+ *
+ * @param[in,out] ObjectsSecurityDescriptor
+ * The returned object security descriptor.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the operations have been
+ * completed successfully and that the specific information
+ * about the security descriptor has been queried.
+ * STATUS_BUFFER_TOO_SMALL is returned if the buffer size
+ * is too small to contain the queried info about the
+ * security descriptor.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
@@ -600,8 +713,22 @@ SeQuerySecurityDescriptorInfo(
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Releases a captured security descriptor buffer.
+ *
+ * @param[in] CapturedSecurityDescriptor
+ * The captured security descriptor to be freed.
+ *
+ * @param[in] CurrentMode
+ * Processor level access mode.
+ *
+ * @param[in] CaptureIfKernelMode
+ * Set this to TRUE if the releasing is to be done within
+ * the kernel.
+ *
+ * @return
+ * Returns STATUS_SUCCESS.
*/
NTSTATUS
NTAPI
@@ -627,8 +754,32 @@ SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR
CapturedSecurityDescriptor,
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Modifies some information data about a security
+ * descriptor.
+ *
+ * @param[in] Object
+ * If specified, the function will use this arbitrary
+ * object that points to an object security descriptor.
+ *
+ * @param[in] SecurityInformation
+ * Security information details to be set.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor where its info is to be changed.
+ *
+ * @param[in,out] ObjectsSecurityDescriptor
+ * The returned pointer to security descriptor objects.
+ *
+ * @param[in] PoolType
+ * Pool type for the new security descriptor to allocate.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights masks.
+ *
+ * @return
+ * See SeSetSecurityDescriptorInfoEx.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
@@ -652,8 +803,42 @@ SeSetSecurityDescriptorInfo(
GenericMapping);
}
-/*
- * @implemented
+/**
+ * @brief
+ * An extended function that sets new information data to
+ * a security descriptor.
+ *
+ * @param[in] Object
+ * If specified, the function will use this arbitrary
+ * object that points to an object security descriptor.
+ *
+ * @param[in] SecurityInformation
+ * Security information details to be set.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor where its info is to be changed.
+ *
+ * @param[in,out] ObjectsSecurityDescriptor
+ * The returned pointer to security descriptor objects.
+ *
+ * @param[in] AutoInheritFlags
+ * Flags bitmask inheritation, influencing how the security
+ * descriptor can be inherited and if it can be in the first
+ * place.
+ *
+ * @param[in] PoolType
+ * Pool type for the new security descriptor to allocate.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights masks.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the operations have been
+ * completed without problems and that new info has been
+ * set to the security descriptor. STATUS_NO_SECURITY_ON_OBJECT
+ * is returned if the object does not have a security descriptor.
+ * STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation
+ * for the new security descriptor with new info set has failed.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
@@ -795,9 +980,22 @@ SeSetSecurityDescriptorInfoEx(
return STATUS_SUCCESS;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Determines if a security descriptor is valid according
+ * to the general security requirements and conditions
+ * set by the kernel.
+ *
+ * @param[in] Length
+ * The length of a security descriptor.
+ *
+ * @param[in] _SecurityDescriptor
+ * A security descriptor where its properties are to be
+ * checked for validity.
+ *
+ * @return
+ * Returns TRUE if the given security descriptor is valid,
+ * FALSE otherwise.
*/
BOOLEAN NTAPI
SeValidSecurityDescriptor(IN ULONG Length,
@@ -932,8 +1130,15 @@ SeValidSecurityDescriptor(IN ULONG Length,
return TRUE;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Frees a security descriptor.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor to be freed from memory.
+ *
+ * @return
+ * Returns STATUS_SUCCESS.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
@@ -952,8 +1157,58 @@ SeDeassignSecurity(
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * An extended function that assigns a security descriptor for a new
+ * object.
+ *
+ * @param[in] _ParentDescriptor
+ * A security descriptor of the parent object that is being
+ * created.
+ *
+ * @param[in] _ExplicitDescriptor
+ * An explicit security descriptor that is applied to a new
+ * object.
+ *
+ * @param[out] NewDescriptor
+ * The new allocated security descriptor.
+ *
+ * @param[in] ObjectType
+ * The type of the new object.
+ *
+ * @param[in] IsDirectoryObject
+ * Set this to TRUE if the newly created object is a directory
+ * object, otherwise set this to FALSE.
+ *
+ * @param[in] AutoInheritFlags
+ * Automatic inheritance flags that influence how access control
+ * entries within ACLs from security descriptors are inherited.
+ *
+ * @param[in] SubjectContext
+ * Security subject context of the new object.
+ *
+ * @param[in] GenericMapping
+ * Generic mapping of access mask rights.
+ *
+ * @param[in] PoolType
+ * This parameter is unused.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the operations have been completed
+ * successfully and that the security descriptor has been
+ * assigned to the new object. STATUS_NO_TOKEN is returned
+ * if the caller hasn't supplied a valid argument to a security
+ * subject context. STATUS_INVALID_OWNER is returned if the caller
+ * hasn't supplied a parent descriptor that belongs to the main
+ * user (owner). STATUS_INVALID_PRIMARY_GROUP is returned
+ * by the same reason as with the previous NTSTATUS code.
+ * The two NTSTATUS codes are returned if the calling thread
+ * stated that the owner and/or group is defaulted to the
+ * parent descriptor (SEF_DEFAULT_OWNER_FROM_PARENT and/or
+ * SEF_DEFAULT_GROUP_FROM_PARENT respectively).
+ * STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation
+ * for the descriptor buffer has failed. A failure NTSTATUS is returned
+ * otherwise.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
@@ -1244,8 +1499,36 @@ SeAssignSecurityEx(
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Assigns a security descriptor for a new object.
+ *
+ * @param[in] ParentDescriptor
+ * A security descriptor of the parent object that is being
+ * created.
+ *
+ * @param[in] ExplicitDescriptor
+ * An explicit security descriptor that is applied to a new
+ * object.
+ *
+ * @param[out] NewDescriptor
+ * The new allocated security descriptor.
+ *
+ * @param[in] IsDirectoryObject
+ * Set this to TRUE if the newly created object is a directory
+ * object, otherwise set this to FALSE.
+ *
+ * @param[in] SubjectContext
+ * Security subject context of the new object.
+ *
+ * @param[in] GenericMapping
+ * Generic mapping of access mask rights.
+ *
+ * @param[in] PoolType
+ * This parameter is unused.
+ *
+ * @return
+ * See SeAssignSecurityEx.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
@@ -1272,8 +1555,23 @@ SeAssignSecurity(
PoolType);
}
-/*
- * @implemented
+/**
+ * @brief
+ * Computes the quota size of a security descriptor.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor.
+ *
+ * @param[out] QuotaInfoSize
+ * The returned quota size of the given security descriptor to
+ * the caller. The function may return 0 to this parameter if
+ * the descriptor doesn't have a group or a discretionary
+ * access control list (DACL) even.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the quota size of a security
+ * descriptor has been computed successfully. STATUS_UNKNOWN_REVISION
+ * is returned if the security descriptor has an invalid revision.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
diff --git a/ntoskrnl/se/semgr.c b/ntoskrnl/se/semgr.c
index 4e217c8a982..961177eaa87 100644
--- a/ntoskrnl/se/semgr.c
+++ b/ntoskrnl/se/semgr.c
@@ -1,10 +1,11 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/semgr.c
- * PURPOSE: Security manager
- *
- * PROGRAMMERS: No programmer listed.
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Security manager infrastructure
+ * COPYRIGHT: Copyright Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ * Copyright Eric Kohl
+ * Copyright Aleksey Bragin
+ * Copyright Alex Ionescu <alex(a)relsoft.net>
*/
/* INCLUDES *******************************************************************/
@@ -26,6 +27,14 @@ extern ERESOURCE SepSubjectContextLock;
/* PRIVATE FUNCTIONS **********************************************************/
+/**
+ * @brief
+ * Initializes all the security exports upon initialization phase of
+ * the module.
+ *
+ * @return
+ * Returns TRUE.
+ */
static
CODE_SEG("INIT")
BOOLEAN
@@ -91,7 +100,15 @@ SepInitExports(VOID)
return TRUE;
}
-
+/**
+ * @brief
+ * Handles the phase 0 procedure of the SRM initialization.
+ *
+ * @return
+ * Returns TRUE if the phase 0 initialization has succeeded and that
+ * we can proceed further with next initialization phase, FALSE
+ * otherwise.
+ */
CODE_SEG("INIT")
BOOLEAN
NTAPI
@@ -137,6 +154,14 @@ SepInitializationPhase0(VOID)
return TRUE;
}
+/**
+ * @brief
+ * Handles the phase 1 procedure of the SRM initialization.
+ *
+ * @return
+ * Returns TRUE if the phase 1 initialization has succeeded, FALSE
+ * otherwise.
+ */
CODE_SEG("INIT")
BOOLEAN
NTAPI
@@ -245,6 +270,15 @@ SepInitializationPhase1(VOID)
return TRUE;
}
+/**
+ * @brief
+ * Main security manager initialization function.
+ *
+ * @return
+ * Returns a boolean value according to the phase initialization
+ * routine that handles it. If TRUE, the routine deems the initialization
+ * phase as complete, FALSE otherwise.
+ */
CODE_SEG("INIT")
BOOLEAN
NTAPI
@@ -275,6 +309,43 @@ SeInitSystem(VOID)
}
}
+/**
+ * @brief
+ * Internal function that is responsible for querying, deleting, assigning and
+ * setting a security descriptor for an object in the NT kernel. It is the default
+ * security method for objects regarding the security context of objects.
+ *
+ * @param[in] Object
+ * The object that has the default security method, which the function has been
+ * called upon.
+ *
+ * @param[in] OperationType
+ * Operation type to perform to that object.
+ *
+ * @param[in] SecurityInformation
+ * Auxiliary security information of the object.
+ *
+ * @param[in] SecurityDescriptor
+ * A security descriptor. This SD is used accordingly to the operation type
+ * requested by the caller.
+ *
+ * @param[in] ReturnLength
+ * The length size of the queried security descriptor, in bytes.
+ *
+ * @param[in] OldSecurityDescriptor
+ * The old SD that belonged to the object, in case we're either deleting
+ * or replacing it.
+ *
+ * @param[in] PoolType
+ * Pool type allocation for the security descriptor.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights masks for the object.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the specific operation tasked has been
+ * completed. Otherwise a failure NTSTATUS code is returned.
+ */
NTSTATUS
NTAPI
SeDefaultObjectMethod(IN PVOID Object,
@@ -336,6 +407,20 @@ SeDefaultObjectMethod(IN PVOID Object,
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Queries the access mask from a security information context.
+ *
+ * @param[in] SecurityInformation
+ * The security information context where the access mask is to be
+ * gathered.
+ *
+ * @param[out] DesiredAccess
+ * The queried access mask right.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
@@ -355,6 +440,19 @@ SeQuerySecurityAccessMask(IN SECURITY_INFORMATION
SecurityInformation,
}
}
+/**
+ * @brief
+ * Sets the access mask for a security information context.
+ *
+ * @param[in] SecurityInformation
+ * The security information context to apply a new access right.
+ *
+ * @param[out] DesiredAccess
+ * The returned access mask right.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
@@ -378,6 +476,30 @@ SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
}
}
+/**
+ * @unimplemented
+ * @brief
+ * Report a security event to the security manager.
+ *
+ * @param[in] Flags
+ * Flags that influence how the event should be reported.
+ *
+ * @param[in] SourceName
+ * A Unicode string that represents the source name of the event.
+ *
+ * @param[in] UserSid
+ * The SID that represents a user that initiated the reporting.
+ *
+ * @param[in] AuditParameters
+ * An array of parameters for auditing purposes. This is used
+ * for reporting the event which the security manager will take
+ * care subsequently of doing eventual security auditing.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the security event has been reported.
+ * STATUS_INVALID_PARAMETER is returned if one of the parameters
+ * do not satisfy the requirements expected by the function.
+ */
NTSTATUS
NTAPI
SeReportSecurityEvent(
@@ -447,6 +569,28 @@ SeReportSecurityEvent(
return STATUS_SUCCESS;
}
+/**
+ * @unimplemented
+ * @brief
+ * Sets an array of audit parameters for later security auditing use.
+ *
+ * @param[in,out] AuditParameters
+ * An array of audit parameters to be set.
+ *
+ * @param[in] Type
+ * The type of audit parameters to be set.
+ *
+ * @param[in] Index
+ * Index number that represents an instance of an audit parameters.
+ * Such index must be within the maximum range of audit parameters.
+ *
+ * @param[in] Data
+ * An arbitrary buffer data that is bounds to what kind of audit parameter
+ * type must be set.
+ *
+ * @return
+ * To be added...
+ */
_Const_
NTSTATUS
NTAPI
diff --git a/ntoskrnl/se/sid.c b/ntoskrnl/se/sid.c
index 24a7a9b526e..89fd380648c 100644
--- a/ntoskrnl/se/sid.c
+++ b/ntoskrnl/se/sid.c
@@ -1,10 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/se/sid.c
- * PURPOSE: Security manager
- *
- * PROGRAMMERS: David Welch <welch(a)cwcom.net>
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Security Identifier (SID) implementation support and handling
+ * COPYRIGHT: Copyright David Welch <welch(a)cwcom.net>
*/
/* INCLUDES *******************************************************************/
@@ -54,6 +52,13 @@ PSID SeNetworkServiceSid = NULL;
/* FUNCTIONS ******************************************************************/
+/**
+ * @brief
+ * Frees all the known initialized SIDs in the system from the memory.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
FreeInitializedSids(VOID)
@@ -88,6 +93,14 @@ FreeInitializedSids(VOID)
if (SeAnonymousLogonSid) ExFreePoolWithTag(SeAnonymousLogonSid, TAG_SID);
}
+/**
+ * @brief
+ * Initializes all the SIDs known in the system.
+ *
+ * @return
+ * Returns TRUE if all the SIDs have been initialized,
+ * FALSE otherwise.
+ */
CODE_SEG("INIT")
BOOLEAN
NTAPI
@@ -263,6 +276,31 @@ SepInitSecurityIDs(VOID)
return TRUE;
}
+/**
+ * @brief
+ * Captures a SID.
+ *
+ * @param[in] InputSid
+ * A valid security identifier to be captured.
+ *
+ * @param[in] AccessMode
+ * Processor level access mode.
+ *
+ * @param[in] PoolType
+ * Pool memory type for the captured SID to assign upon
+ * allocation.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE, the capturing is done within the kernel.
+ * Otherwise the capturing is done in a kernel mode driver.
+ *
+ * @param[out] CapturedSid
+ * The captured security identifier, returned to the caller.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the SID was captured. STATUS_INSUFFICIENT_RESOURCES
+ * is returned if memory pool allocation for the captured SID has failed.
+ */
NTSTATUS
NTAPI
SepCaptureSid(IN PSID InputSid,
@@ -331,6 +369,23 @@ SepCaptureSid(IN PSID InputSid,
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Releases a captured SID.
+ *
+ * @param[in] CapturedSid
+ * The captured SID to be released.
+ *
+ * @param[in] AccessMode
+ * Processor level access mode.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE, the releasing is done within the kernel.
+ * Otherwise the releasing is done in a kernel mode driver.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepReleaseSid(IN PSID CapturedSid,
@@ -347,6 +402,52 @@ SepReleaseSid(IN PSID CapturedSid,
}
}
+/**
+ * @brief
+ * Captures a SID with attributes.
+ *
+ * @param[in] SrcSidAndAttributes
+ * Source of the SID with attributes to be captured.
+ *
+ * @param[in] AttributeCount
+ * The number count of attributes, in total.
+ *
+ * @param[in] PreviousMode
+ * Processor access level mode.
+ *
+ * @param[in] AllocatedMem
+ * The allocated memory buffer for the captured SID. If the caller
+ * supplies no allocated block of memory then the function will
+ * allocate some buffer block of memory for the captured SID
+ * automatically.
+ *
+ * @param[in] AllocatedLength
+ * The length of the buffer that points to the allocated memory,
+ * in bytes.
+ *
+ * @param[in] PoolType
+ * The pool type for the captured SID and attributes to assign.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE, the capturing is done within the kernel.
+ * Otherwise the capturing is done in a kernel mode driver.
+ *
+ * @param[out] CapturedSidAndAttributes
+ * The captured SID and attributes.
+ *
+ * @param[out] ResultLength
+ * The length of the captured SID and attributes, in bytes.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if SID and attributes capturing
+ * has been completed successfully. STATUS_INVALID_PARAMETER
+ * is returned if the count of attributes exceeds the maximum
+ * threshold that the kernel can permit. STATUS_INSUFFICIENT_RESOURCES
+ * is returned if memory pool allocation for the captured SID has failed.
+ * STATUS_BUFFER_TOO_SMALL is returned if the length of the allocated
+ * buffer is less than the required size. A failure NTSTATUS code is
+ * returned otherwise.
+ */
NTSTATUS
NTAPI
SeCaptureSidAndAttributesArray(
@@ -548,6 +649,23 @@ SeCaptureSidAndAttributesArray(
return Status;
}
+/**
+ * @brief
+ * Releases a captured SID with attributes.
+ *
+ * @param[in] CapturedSidAndAttributes
+ * The captured SID with attributes to be released.
+ *
+ * @param[in] AccessMode
+ * Processor access level mode.
+ *
+ * @param[in] CaptureIfKernel
+ * If set to TRUE, the releasing is done within the kernel.
+ * Otherwise the releasing is done in a kernel mode driver.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeReleaseSidAndAttributesArray(
@@ -564,5 +682,4 @@ SeReleaseSidAndAttributesArray(
}
}
-
/* EOF */
diff --git a/ntoskrnl/se/srm.c b/ntoskrnl/se/srm.c
index 90809a907e1..abdb7ee2fb7 100644
--- a/ntoskrnl/se/srm.c
+++ b/ntoskrnl/se/srm.c
@@ -13,9 +13,6 @@
#define NDEBUG
#include <debug.h>
-extern LUID SeSystemAuthenticationId;
-extern LUID SeAnonymousAuthenticationId;
-
/* PRIVATE DEFINITIONS ********************************************************/
typedef struct _SEP_LOGON_SESSION_TERMINATED_NOTIFICATION
@@ -42,6 +39,9 @@ SepRmCreateLogonSession(
/* GLOBALS ********************************************************************/
+extern LUID SeSystemAuthenticationId;
+extern LUID SeAnonymousAuthenticationId;
+
HANDLE SeRmCommandPort;
HANDLE SeLsaInitEvent;
@@ -62,7 +62,6 @@ KGUARDED_MUTEX SepRmDbLock;
PSEP_LOGON_SESSION_REFERENCES SepLogonSessions = NULL;
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION SepLogonNotifications = NULL;
-
/* PRIVATE FUNCTIONS **********************************************************/
/**
@@ -163,7 +162,15 @@ Cleanup:
return Status;
}
-
+/**
+ * @brief
+ * Manages the phase 0 initialization of the security reference
+ * monitoring module of the kernel.
+ *
+ * @return
+ * Returns TRUE when phase 0 initialization has completed without
+ * problems, FALSE otherwise.
+ */
BOOLEAN
NTAPI
SeRmInitPhase0(VOID)
@@ -190,7 +197,15 @@ SeRmInitPhase0(VOID)
return TRUE;
}
-
+/**
+ * @brief
+ * Manages the phase 1 initialization of the security reference
+ * monitoring module of the kernel.
+ *
+ * @return
+ * Returns TRUE when phase 1 initialization has completed without
+ * problems, FALSE otherwise.
+ */
BOOLEAN
NTAPI
SeRmInitPhase1(VOID)
@@ -247,6 +262,13 @@ SeRmInitPhase1(VOID)
return TRUE;
}
+/**
+ * @brief
+ * Initializes the local security authority audit bounds.
+ *
+ * @return
+ * Nothing.
+ */
static
VOID
SepAdtInitializeBounds(VOID)
@@ -285,7 +307,18 @@ SepAdtInitializeBounds(VOID)
SepAdtMaxListLength = ListBounds.MaxLength;
}
-
+/**
+ * @brief
+ * Sets an audit event for future security auditing monitoring.
+ *
+ * @param[in,out] Message
+ * The reference monitoring API message. It is used to determine
+ * if the right API message number is provided, RmAuditSetCommand
+ * in this case.
+ *
+ * @return
+ * Returns STATUS_SUCCESS.
+ */
static
NTSTATUS
SepRmSetAuditEvent(
@@ -456,6 +489,24 @@ SepRmRemoveLogonSessionFromToken(
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Creates a logon session. The security reference monitoring (SRM)
+ * module of Executive uses this as an internal kernel data for
+ * respective logon sessions management within the kernel,
+ * as in form of a SEP_LOGON_SESSION_REFERENCES data structure.
+ *
+ * @param[in,out] LogonLuid
+ * A logon ID represented as a LUID. This LUID is used to create
+ * our logon session and add it to the sessions database.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the logon has been created successfully.
+ * STATUS_LOGON_SESSION_EXISTS is returned if a logon session with
+ * the pointed logon ID in the call already exists.
+ * STATUS_INSUFFICIENT_RESOURCES is returned if logon session allocation
+ * has failed because of lack of memory pool resources.
+ */
static
NTSTATUS
SepRmCreateLogonSession(
@@ -627,7 +678,19 @@ Leave:
return Status;
}
-
+/**
+ * @brief
+ * References a logon session.
+ *
+ * @param[in,out] LogonLuid
+ * A valid LUID that points to the logon session in the database that
+ * we're going to reference it.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the logon has been referenced.
+ * STATUS_NO_SUCH_LOGON_SESSION is returned if the session couldn't be
+ * found otherwise.
+ */
NTSTATUS
SepRmReferenceLogonSession(
PLUID LogonLuid)
@@ -667,6 +730,22 @@ SepRmReferenceLogonSession(
return STATUS_NO_SUCH_LOGON_SESSION;
}
+/**
+ * @brief
+ * Cleans the DOS device map directory of a logon
+ * session.
+ *
+ * @param[in] LogonLuid
+ * A logon session ID where its DOS device map directory
+ * is to be cleaned.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the device map directory has been
+ * successfully cleaned from the logon session. STATUS_INVALID_PARAMETER
+ * is returned if the caller hasn't submitted any logon ID. STATUS_NO_MEMORY
+ * is returned if buffer allocation for links has failed. A failure
+ * NTSTATUS code is returned otherwise.
+ */
static
NTSTATUS
SepCleanupLUIDDeviceMapDirectory(
@@ -910,7 +989,21 @@ AllocateLinksAgain:
return Status;
}
-
+/**
+ * @brief
+ * De-references a logon session. If the session has a reference
+ * count of 0 by the time the function has de-referenced the logon,
+ * that means the session is no longer used and can be safely deleted
+ * from the logon sessions database.
+ *
+ * @param[in,out] LogonLuid
+ * A logon session ID to de-reference.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the logon session has been de-referenced
+ * without issues. STATUS_NO_SUCH_LOGON_SESSION is returned if no
+ * such logon exists otherwise.
+ */
NTSTATUS
SepRmDereferenceLogonSession(
PLUID LogonLuid)
@@ -965,7 +1058,18 @@ SepRmDereferenceLogonSession(
return STATUS_NO_SUCH_LOGON_SESSION;
}
-
+/**
+ * @brief
+ * Main SRM server thread initialization function. It deals
+ * with security manager and LSASS port connection, thus
+ * thereby allowing communication between the kernel side
+ * (the SRM) and user mode side (the LSASS) of the security
+ * world of the operating system.
+ *
+ * @return
+ * Returns TRUE if command server connection between SRM
+ * and LSASS has succeeded, FALSE otherwise.
+ */
BOOLEAN
NTAPI
SepRmCommandServerThreadInit(VOID)
@@ -1108,6 +1212,15 @@ Cleanup:
return Result;
}
+/**
+ * @brief
+ * Manages the SRM server API commands, that is, receiving such API
+ * command messages from the user mode side of the security standpoint,
+ * the LSASS.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepRmCommandServerThread(
@@ -1211,8 +1324,23 @@ SepRmCommandServerThread(
/* PUBLIC FUNCTIONS ***********************************************************/
-/*
- * @unimplemented
+/**
+ * @brief
+ * Retrieves the DOS device map from a logon session.
+ *
+ * @param[in] LogonId
+ * A valid logon session ID.
+ *
+ * @param[out] DeviceMap
+ * The returned device map buffer from the logon session.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the device map could be gathered
+ * from the logon session. STATUS_INVALID_PARAMETER is returned if
+ * one of the parameters aren't initialized (that is, the caller has
+ * submitted a NULL pointer variable). STATUS_NO_SUCH_LOGON_SESSION is
+ * returned if no such session could be found. A failure NTSTATUS code
+ * is returned otherwise.
*/
NTSTATUS
NTAPI
@@ -1425,9 +1553,20 @@ SeMarkLogonSessionForTerminationNotification(
return STATUS_SUCCESS;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Registers a callback that will be called once a logon session
+ * terminates.
+ *
+ * @param[in] CallbackRoutine
+ * Callback routine address.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the callback routine was registered
+ * successfully. STATUS_INVALID_PARAMETER is returned if the caller
+ * did not provide a callback routine. STATUS_INSUFFICIENT_RESOURCES
+ * is returned if the callback notification data couldn't be allocated
+ * because of lack of memory pool resources.
*/
NTSTATUS
NTAPI
@@ -1464,9 +1603,19 @@ SeRegisterLogonSessionTerminatedRoutine(
return STATUS_SUCCESS;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Un-registers a callback routine, previously registered by
+ * SeRegisterLogonSessionTerminatedRoutine function.
+ *
+ * @param[in] CallbackRoutine
+ * Callback routine address to un-register.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the callback routine was un-registered
+ * successfully. STATUS_INVALID_PARAMETER is returned if the caller
+ * did not provide a callback routine. STATUS_NOT_FOUND is returned
+ * if the callback notification item couldn't be found.
*/
NTSTATUS
NTAPI
@@ -1520,3 +1669,5 @@ SeUnregisterLogonSessionTerminatedRoutine(
return Status;
}
+
+/* EOF */
diff --git a/ntoskrnl/se/token.c b/ntoskrnl/se/token.c
index 46dbb725a89..3dd0cb0fd6e 100644
--- a/ntoskrnl/se/token.c
+++ b/ntoskrnl/se/token.c
@@ -467,6 +467,22 @@ SepImpersonateAnonymousToken(
return Status;
}
+/**
+ * @brief
+ * Updates the token's flags based upon the privilege that the token
+ * has been granted. The flag can either be taken out or given to the token
+ * if the attributes of the specified privilege is enabled or not.
+ *
+ * @param[in,out] Token
+ * The token where the flags are to be changed.
+ *
+ * @param[in] Index
+ * The index count which represents the total sum of privileges. The count in question
+ * MUST NOT exceed the expected privileges count of the token.
+ *
+ * @return
+ * Nothing.
+ */
static
VOID
SepUpdateSinglePrivilegeFlagToken(
@@ -518,6 +534,18 @@ SepUpdateSinglePrivilegeFlagToken(
}
}
+/**
+ * @brief
+ * Updates the token's flags based upon the privilege that the token
+ * has been granted. The function uses the private helper,
SepUpdateSinglePrivilegeFlagToken,
+ * in order to update the flags of a token.
+ *
+ * @param[in,out] Token
+ * The token where the flags are to be changed.
+ *
+ * @return
+ * Nothing.
+ */
static
VOID
SepUpdatePrivilegeFlagsToken(
@@ -528,11 +556,25 @@ SepUpdatePrivilegeFlagsToken(
/* Loop all privileges */
for (i = 0; i < Token->PrivilegeCount; i++)
{
- /* Updates the flags dor this privilege */
+ /* Updates the flags for this privilege */
SepUpdateSinglePrivilegeFlagToken(Token, i);
}
}
+/**
+ * @brief
+ * Removes a privilege from the token.
+ *
+ * @param[in,out] Token
+ * The token where the privilege is to be removed.
+ *
+ * @param[in] Index
+ * The index count which represents the number position of the privilege
+ * we want to remove.
+ *
+ * @return
+ * Nothing.
+ */
static
VOID
SepRemovePrivilegeToken(
@@ -556,6 +598,17 @@ SepRemovePrivilegeToken(
Token->PrivilegeCount--;
}
+/**
+ * @unimplemented
+ * @brief
+ * Frees (de-allocates) the proxy data memory block of a token.
+ *
+ * @param[in,out] ProxyData
+ * The proxy data to be freed.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepFreeProxyData(PVOID ProxyData)
@@ -563,6 +616,20 @@ SepFreeProxyData(PVOID ProxyData)
UNIMPLEMENTED;
}
+/**
+ * @unimplemented
+ * @brief
+ * Copies the proxy data from the source into the destination of a token.
+ *
+ * @param[out] Dest
+ * The destination path where the proxy data is to be copied to.
+ *
+ * @param[out] Src
+ * The source path where the proxy data is be copied from.
+ *
+ * @return
+ * To be added...
+ */
NTSTATUS
NTAPI
SepCopyProxyData(PVOID* Dest,
@@ -572,6 +639,27 @@ SepCopyProxyData(PVOID* Dest,
return STATUS_NOT_IMPLEMENTED;
}
+/**
+ * @brief
+ * Replaces the old access token of a process (pointed by the EPROCESS kernel structure)
with a
+ * new access token. The new access token must be a primary token for use.
+ *
+ * @param[in] Process
+ * The process instance where its access token is about to be replaced.
+ *
+ * @param[in] NewAccessToken
+ * The new token that it's going to replace the old one.
+ *
+ * @param[out] OldAccessToken
+ * The returned old token that's been replaced, which the caller can do anything.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the exchange operation between tokens has completed
successfully.
+ * STATUS_BAD_TOKEN_TYPE is returned if the new token is not a primary one so that we
cannot
+ * exchange it with the old one from the process. STATUS_TOKEN_ALREADY_IN_USE is returned
if
+ * both tokens aren't equal which means one of them has different properties (groups,
privileges, etc.)
+ * and as such one of them is currently in use. A failure NTSTATUS code is returned
otherwise.
+ */
NTSTATUS
NTAPI
SeExchangePrimaryToken(
@@ -652,6 +740,16 @@ SeExchangePrimaryToken(
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Removes the primary token of a process.
+ *
+ * @param[in, out] Process
+ * The process instance with the access token to be removed.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeDeassignPrimaryToken(PEPROCESS Process)
@@ -668,6 +766,19 @@ SeDeassignPrimaryToken(PEPROCESS Process)
ObDereferenceObject(OldToken);
}
+/**
+ * @brief
+ * Computes the length size of a SID.
+ *
+ * @param[in] Count
+ * Total count of entries that have SIDs in them (that being PSID_AND_ATTRIBUTES in this
context).
+ *
+ * @param[in] Src
+ * Source that points to the attributes and SID entry structure.
+ *
+ * @return
+ * Returns the total length of a SID size.
+ */
static ULONG
RtlLengthSidAndAttributes(ULONG Count,
PSID_AND_ATTRIBUTES Src)
@@ -684,7 +795,35 @@ RtlLengthSidAndAttributes(ULONG Count,
return uLength;
}
-
+/**
+ * @brief
+ * Finds the primary group and default owner entity based on the submitted primary group
instance
+ * and an access token.
+ *
+ * @param[in] Token
+ * Access token to begin the search query of primary group and default owner.
+ *
+ * @param[in] PrimaryGroup
+ * A primary group SID to be used for search query, determining if user & groups of a
token
+ * and the submitted primary group do match.
+ *
+ * @param[in] DefaultOwner
+ * The default owner. If specified, it's used to determine if the token belongs to
the actual user,
+ * that is, being the owner himself.
+ *
+ * @param[out] PrimaryGroupIndex
+ * Returns the primary group index.
+ *
+ * @param[out] DefaultOwnerIndex
+ * Returns the default owner index.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the find query operation has completed successfully and that
at least one
+ * search result is requested by the caller. STATUS_INVALID_PARAMETER is returned if the
caller hasn't requested
+ * any search result. STATUS_INVALID_OWNER is returned if the specified default user
owner does not match with the other
+ * user from the token. STATUS_INVALID_PRIMARY_GROUP is returned if the specified default
primary group does not match with the
+ * other group from the token.
+ */
static NTSTATUS
SepFindPrimaryGroupAndDefaultOwner(
_In_ PTOKEN Token,
@@ -779,7 +918,37 @@ SepFindPrimaryGroupAndDefaultOwner(
return STATUS_SUCCESS;
}
-
+/**
+ * @brief
+ * Duplicates an access token, from an existing valid token.
+ *
+ * @param[in] Token
+ * Access token to duplicate.
+ *
+ * @param[in] ObjectAttributes
+ * Object attributes for the new token.
+ *
+ * @param[in] EffectiveOnly
+ * If set to TRUE, the function removes all the disabled privileges and groups of the
token
+ * to duplicate.
+ *
+ * @param[in] TokenType
+ * Type of token.
+ *
+ * @param[in] Level
+ * Security impersonation level of a token.
+ *
+ * @param[in] PreviousMode
+ * The processor request level mode.
+ *
+ * @param[out] NewAccessToken
+ * The duplicated token.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the token has been duplicated. STATUS_INSUFFICIENT_RESOURCES
is returned
+ * if memory pool allocation of the dynamic part of the token for duplication has failed
due to the lack
+ * of memory resources. A failure NTSTATUS code is returned otherwise.
+ */
NTSTATUS
NTAPI
SepDuplicateToken(
@@ -1024,6 +1193,27 @@ Quit:
return Status;
}
+/**
+ * @brief
+ * Subtracts a token in exchange of duplicating a new one.
+ *
+ * @param[in] ParentToken
+ * The parent access token for duplication.
+ *
+ * @param[out] Token
+ * The new duplicated token.
+ *
+ * @param[in] InUse
+ * Set this to TRUE if the token is about to be used immediately after the call
execution
+ * of this function, FALSE otherwise.
+ *
+ * @param[in] SessionId
+ * Session ID for the token to be assigned.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if token subtracting and duplication have completed
successfully.
+ * A failure NTSTATUS code is returned otherwise.
+ */
NTSTATUS
NTAPI
SeSubProcessToken(IN PTOKEN ParentToken,
@@ -1068,6 +1258,21 @@ SeSubProcessToken(IN PTOKEN ParentToken,
return Status;
}
+/**
+ * @brief
+ * Checks if the token is a child of the other token
+ * of the current process that the calling thread is invoking this function.
+ *
+ * @param[in] Token
+ * An access token to determine if it's a child or not.
+ *
+ * @param[out] IsChild
+ * The returned boolean result.
+ *
+ * @return
+ * Returns STATUS_SUCCESS when the function finishes its operation. STATUS_UNSUCCESSFUL
is
+ * returned if primary token of the current calling process couldn't be referenced
otherwise.
+ */
NTSTATUS
NTAPI
SeIsTokenChild(IN PTOKEN Token,
@@ -1101,6 +1306,21 @@ SeIsTokenChild(IN PTOKEN Token,
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Checks if the token is a sibling of the other token of
+ * the current process that the calling thread is invoking this function.
+ *
+ * @param[in] Token
+ * An access token to determine if it's a sibling or not.
+ *
+ * @param[out] IsSibling
+ * The returned boolean result.
+ *
+ * @return
+ * Returns STATUS_SUCCESS when the function finishes its operation. STATUS_UNSUCCESSFUL
is
+ * returned if primary token of the current calling process couldn't be referenced
otherwise.
+ */
NTSTATUS
NTAPI
SeIsTokenSibling(IN PTOKEN Token,
@@ -1140,6 +1360,26 @@ SeIsTokenSibling(IN PTOKEN Token,
return STATUS_SUCCESS;
}
+/**
+ * @brief
+ * Copies an existing access token (technically duplicating a new one).
+ *
+ * @param[in] Token
+ * Token to copy.
+ *
+ * @param[in] Level
+ * Impersonation security level to assign to the newly copied token.
+ *
+ * @param[in] PreviousMode
+ * Processor request level mode.
+ *
+ * @param[out] NewToken
+ * The newly copied token.
+ *
+ * @return
+ * Returns STATUS_SUCCESS when token copying has finished successfully. A failure
+ * NTSTATUS code is returned otherwise.
+ */
NTSTATUS
NTAPI
SeCopyClientToken(IN PACCESS_TOKEN Token,
@@ -1169,6 +1409,18 @@ SeCopyClientToken(IN PACCESS_TOKEN Token,
return Status;
}
+/**
+ * @brief
+ * Internal function that deals with access token object destruction and deletion.
+ * The function is used solely by the object manager mechanism that handles the life
+ * management of a token object.
+ *
+ * @param[in] ObjectBody
+ * The object body that represents an access token object.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SepDeleteToken(PVOID ObjectBody)
@@ -1203,7 +1455,14 @@ SepDeleteToken(PVOID ObjectBody)
ExFreePoolWithTag(AccessToken->DynamicPart, TAG_TOKEN_DYNAMIC);
}
-
+/**
+ * @brief
+ * Internal function that initializes critical kernel data for access
+ * token implementation in SRM.
+ *
+ * @return
+ * Nothing.
+ */
CODE_SEG("INIT")
VOID
NTAPI
@@ -1229,6 +1488,19 @@ SepInitializeTokenImplementation(VOID)
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL,
&SeTokenObjectType);
}
+/**
+ * @brief
+ * Assigns a primary access token to a given process.
+ *
+ * @param[in] Process
+ * Process where the token is about to be assigned.
+ *
+ * @param[in] Token
+ * The token to be assigned.
+ *
+ * @return
+ * Nothing.
+ */
VOID
NTAPI
SeAssignPrimaryToken(IN PEPROCESS Process,
@@ -1249,6 +1521,80 @@ SeAssignPrimaryToken(IN PEPROCESS Process,
ObInitializeFastReference(&Process->Token, Token);
}
+/**
+ * @brief
+ * Internal function responsible for access token object creation in the kernel.
+ * A fully created token objected is inserted into the token handle, thus the handle
+ * becoming a valid handle to an access token object and ready for use.
+ *
+ * @param[out] TokenHandle
+ * Valid token handle that's ready for use after token creation and object
insertion.
+ *
+ * @param[in] PreviousMode
+ * Processor request level mode.
+ *
+ * @param[in] DesiredAccess
+ * Desired access right for the token object to be granted. This kind of access right
+ * impacts how the token can be used and who.
+ *
+ * @param[in] ObjectAttributes
+ * Object attributes for the token to be created.
+ *
+ * @param[in] TokenType
+ * Type of token to assign upon creation.
+ *
+ * @param[in] ImpersonationLevel
+ * Security impersonation level of token to assign upon creation.
+ *
+ * @param[in] AuthenticationId
+ * Authentication ID that represents the authentication information of the token.
+ *
+ * @param[in] ExpirationTime
+ * Expiration time of the token to assign. A value of -1 means that the token never
+ * expires and its life depends upon the amount of references this token object has.
+ *
+ * @param[in] User
+ * User entry to assign to the token.
+ *
+ * @param[in] GroupCount
+ * The total number of groups count for the token.
+ *
+ * @param[in] Groups
+ * The group entries for the token.
+ *
+ * @param[in] GroupsLength
+ * The length size of the groups array, pointed by the Groups parameter.
+ *
+ * @param[in] PrivilegeCount
+ * The total number of priivleges that the newly created token has.
+ *
+ * @param[in] Privileges
+ * The privileges for the token.
+ *
+ * @param[in] Owner
+ * The main user (or also owner) that represents the token that we create.
+ *
+ * @param[in] PrimaryGroup
+ * The main group that represents the token that we create.
+ *
+ * @param[in] DefaultDacl
+ * A discretionary access control list for the token.
+ *
+ * @param[in] TokenSource
+ * Source (or the origin) of the access token that creates it.
+ *
+ * @param[in] SystemToken
+ * If set to TRUE, the newly created token is a system token and only in charge
+ * by the internal system. The function directly returns a pointer to the
+ * created token object for system kernel use. Otherwise if set to FALSE, the
+ * function inserts the object to a handle making it a regular access token.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if token creation has completed successfully.
+ * STATUS_INSUFFICIENT_RESOURCES is returned if the dynamic area of memory of the
+ * token hasn't been allocated because of lack of memory resources. A failure
+ * NTSTATUS code is returned otherwise.
+ */
NTSTATUS
NTAPI
SepCreateToken(
@@ -1804,8 +2150,33 @@ SepCreateSystemAnonymousLogonTokenNoEveryone(VOID)
/* PUBLIC FUNCTIONS ***********************************************************/
-/*
+/**
* @unimplemented
+ * @brief
+ * Filters an access token from an existing token, making it more restricted
+ * than the previous one.
+ *
+ * @param[in] ExistingToken
+ * An existing token for filtering.
+ *
+ * @param[in] Flags
+ * Privilege flag options. This parameter argument influences how the token
+ * is filtered. Such parameter can be 0.
+ *
+ * @param[in] SidsToDisable
+ * Array of SIDs to disable.
+ *
+ * @param[in] PrivilegesToDelete
+ * Array of privileges to delete.
+ *
+ * @param[in] RestrictedSids
+ * An array of restricted SIDs for the new filtered token.
+ *
+ * @param[out] FilteredToken
+ * The newly filtered token, returned to the caller.
+ *
+ * @return
+ * To be added...
*/
NTSTATUS
NTAPI
@@ -2189,8 +2560,18 @@ SeQueryInformationToken(
return Status;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Queries the session ID of an access token.
+ *
+ * @param[in] Token
+ * A valid access token where the session ID has to be gathered.
+ *
+ * @param[out] pSessionId
+ * The returned pointer to a session ID to the caller.
+ *
+ * @return
+ * Returns STATUS_SUCCESS.
*/
NTSTATUS
NTAPI
@@ -2210,8 +2591,18 @@ SeQuerySessionIdToken(IN PACCESS_TOKEN Token,
return STATUS_SUCCESS;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Queries the authentication ID of an access token.
+ *
+ * @param[in] Token
+ * A valid access token where the authentication ID has to be gathered.
+ *
+ * @param[out] pSessionId
+ * The returned pointer to an authentication ID to the caller.
+ *
+ * @return
+ * Returns STATUS_SUCCESS.
*/
NTSTATUS
NTAPI
@@ -2225,9 +2616,15 @@ SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
return STATUS_SUCCESS;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Gathers the security impersonation level of an access token.
+ *
+ * @param[in] Token
+ * A valid access token where the impersonation level has to be gathered.
+ *
+ * @return
+ * Returns the security impersonation level from a valid token.
*/
SECURITY_IMPERSONATION_LEVEL
NTAPI
@@ -2238,9 +2635,16 @@ SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
return ((PTOKEN)Token)->ImpersonationLevel;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Gathers the token type of an access token. A token ca be either
+ * a primary token or impersonation token.
+ *
+ * @param[in] Token
+ * A valid access token where the token type has to be gathered.
+ *
+ * @return
+ * Returns the token type from a valid token.
*/
TOKEN_TYPE NTAPI
SeTokenType(IN PACCESS_TOKEN Token)
@@ -2250,9 +2654,18 @@ SeTokenType(IN PACCESS_TOKEN Token)
return ((PTOKEN)Token)->TokenType;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Determines if a token is either an admin token or not. Such
+ * condition is checked based upon TOKEN_HAS_ADMIN_GROUP flag,
+ * which means if the respective access token belongs to an
+ * administrator group or not.
+ *
+ * @param[in] Token
+ * A valid access token to determine if such token is admin or not.
+ *
+ * @return
+ * Returns TRUE if the token is an admin one, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -2265,8 +2678,16 @@ SeTokenIsAdmin(IN PACCESS_TOKEN Token)
return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_ADMIN_GROUP) != 0;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Determines if a token is restricted or not, based upon the token
+ * flags.
+ *
+ * @param[in] Token
+ * A valid access token to determine if such token is restricted.
+ *
+ * @return
+ * Returns TRUE if the token is restricted, FALSE otherwise.
*/
BOOLEAN
NTAPI
@@ -2277,10 +2698,20 @@ SeTokenIsRestricted(IN PACCESS_TOKEN Token)
return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
}
-/*
- * @implemented
- * @note First introduced in NT 5.1 SP2 x86 (5.1.2600.2622), absent in NT 5.2,
- * then finally re-introduced in Vista+.
+/**
+ * @brief
+ * Determines if a token is write restricted, that is, nobody can write anything
+ * to it.
+ *
+ * @param[in] Token
+ * A valid access token to determine if such token is write restricted.
+ *
+ * @return
+ * Returns TRUE if the token is write restricted, FALSE otherwise.
+ *
+ * @remarks
+ * First introduced in NT 5.1 SP2 x86 (5.1.2600.2622), absent in NT 5.2,
+ * then finally re-introduced in Vista+.
*/
BOOLEAN
NTAPI
@@ -2393,8 +2824,37 @@ Quit:
/* SYSTEM CALLS ***************************************************************/
-/*
- * @implemented
+/**
+ * @brief
+ * Queries a specific type of information in regard of an access token based upon
+ * the information class. The calling thread must have specific access rights in order
+ * to obtain specific information about the token.
+ *
+ * @param[in] TokenHandle
+ * A handle of a token where information is to be gathered.
+ *
+ * @param[in] TokenInformationClass
+ * Token information class.
+ *
+ * @param[out] TokenInformation
+ * A returned output buffer with token information, which information is arbitrarily
upon
+ * the information class chosen.
+ *
+ * @param[in] TokenInformationLength
+ * Length of the token information buffer, in bytes.
+ *
+ * @param[out] ReturnLength
+ * If specified in the call, the function returns the total length size of the token
+ * information buffer..
+ *
+ * @return
+ * Returns STATUS_SUCCESS if information querying has completed successfully.
+ * STATUS_BUFFER_TOO_SMALL is returned if the information length that represents
+ * the token information buffer is not greater than the required length.
+ * STATUS_INVALID_HANDLE is returned if the token handle is not a valid one.
+ * STATUS_INVALID_INFO_CLASS is returned if the information class is not a valid
+ * one (that is, the class doesn't belong to TOKEN_INFORMATION_CLASS). A failure
+ * NTSTATUS code is returned otherwise.
*/
_Must_inspect_result_
__kernel_entry
@@ -2966,11 +3426,37 @@ NtQueryInformationToken(
return Status;
}
-
-/*
- * NtSetTokenInformation: Partly implemented.
- * Unimplemented:
- * TokenOrigin, TokenDefaultDacl
+/**
+ * @unimplemented
+ * @brief
+ * Sets (modifies) some specific information in regard of an access token. The
+ * calling thread must have specific access rights in order to modify token's
+ * information data.
+ *
+ * @param[in] TokenHandle
+ * A handle of a token where information is to be modified.
+ *
+ * @param[in] TokenInformationClass
+ * Token information class.
+ *
+ * @param[in] TokenInformation
+ * An arbitrary pointer to a buffer with token information to set. Such
+ * arbitrary buffer depends on the information class chosen that the caller
+ * wants to modify such information data of a token.
+ *
+ * @param[in] TokenInformationLength
+ * Length of the token information buffer, in bytes.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if information setting has completed successfully.
+ * STATUS_INFO_LENGTH_MISMATCH is returned if the information length of the
+ * buffer is less than the required length. STATUS_INSUFFICIENT_RESOURCES is
+ * returned if memory pool allocation has failed. STATUS_PRIVILEGE_NOT_HELD
+ * is returned if the calling thread hasn't the required privileges to perform
+ * the operation in question. A failure NTSTATUS code is returned otherwise.
+ *
+ * @remarks
+ * The function is partly implemented, mainly TokenOrigin and TokenDefaultDacl.
*/
_Must_inspect_result_
__kernel_entry
@@ -3494,11 +3980,37 @@ Cleanup:
return Status;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Duplicates a token.
+ *
+ * @param[in] ExistingTokenHandle
+ * An existing token to duplicate.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights for the new duplicated token.
+ *
+ * @param[in] ObjectAttributes
+ * Object attributes for the new duplicated token.
+ *
+ * @param[in] EffectiveOnly
+ * If set to TRUE, the function removes all the disabled privileges and groups
+ * of the token to duplicate.
+ *
+ * @param[in] TokenType
+ * Type of token to assign to the duplicated token.
+ *
+ * @param[out] NewTokenHandle
+ * The returned duplicated token handle.
*
- * NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
+ * @return
+ * STATUS_SUCCESS is returned if token duplication has completed successfully.
+ * STATUS_BAD_IMPERSONATION_LEVEL is returned if the caller erroneously wants
+ * to raise the impersonation level even though the conditions do not permit
+ * it. A failure NTSTATUS code is returned otherwise.
+ *
+ * @remarks
+ * Some sources claim 4th param is ImpersonationLevel, but on W2K
* this is certainly NOT true, although I can't say for sure that EffectiveOnly
* is correct either. -Gunnar
* This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
@@ -3650,6 +4162,36 @@ NtDuplicateToken(
return Status;
}
+/**
+ * @brief
+ * Changes the groups list of SIDs of a token.
+ *
+ * @param[in] TokenHandle
+ * Token handle where the list of groups SIDs are to be adjusted.
+ *
+ * @param[in] ResetToDefault
+ * If set to TRUE, the function resets the list of groups SIDs to default.
+ * All the rest of parameters are ignored.
+ *
+ * @param[in] NewState
+ * A new list of groups SIDs that the function will use it accordingly to
+ * modify the current list of groups SIDs of a token.
+ *
+ * @param[in] BufferLength
+ * The length size of the buffer that is pointed by the NewState parameter
+ * argument, in bytes.
+ *
+ * @param[out] PreviousState
+ * If specified, the function will return to the caller the old list of groups
+ * SIDs.
+ *
+ * @param[out] ReturnLength
+ * If specified, the function will return the total size length of the old list
+ * of groups SIDs, in bytes.
+ *
+ * @return
+ * To be added...
+ */
NTSTATUS NTAPI
NtAdjustGroupsToken(IN HANDLE TokenHandle,
IN BOOLEAN ResetToDefault,
@@ -3662,7 +4204,43 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle,
return STATUS_NOT_IMPLEMENTED;
}
-
+/**
+ * @brief
+ * Removes a certain amount of privileges of a token based upon the request
+ * by the caller.
+ *
+ * @param[in,out] Token
+ * Token handle where the privileges are about to be modified.
+ *
+ * @param[in] DisableAllPrivileges
+ * If set to TRUE, the function disables all the privileges.
+ *
+ * @param[in] NewState
+ * A new list of privileges that the function will use it accordingly to
+ * either disable or enable the said privileges and change them.
+ *
+ * @param[in] NewStateCount
+ * The new total number count of privileges.
+ *
+ * @param[out] PreviousState
+ * If specified, the function will return the previous state list of privileges.
+ *
+ * @param[in] ApplyChanges
+ * If set to TRUE, the function will immediatelly apply the changes onto the
+ * token's privileges.
+ *
+ * @param[out] ChangedPrivileges
+ * The returned count number of changed privileges.
+ *
+ * @param[out] ChangesMade
+ * If TRUE, the function has made changes to the token's privileges. FALSE
+ * otherwise.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the function has successfully changed the list
+ * of privileges. STATUS_NOT_ALL_ASSIGNED is returned if not every privilege
+ * has been changed.
+ */
static
NTSTATUS
SepAdjustPrivileges(
@@ -3779,9 +4357,42 @@ SepAdjustPrivileges(
return STATUS_SUCCESS;
}
-
-/*
- * @implemented
+/**
+ * @brief
+ * Removes a certain amount of privileges of a token based upon the request
+ * by the caller.
+ *
+ * @param[in,out] Token
+ * Token handle where the privileges are about to be modified.
+ *
+ * @param[in] DisableAllPrivileges
+ * If set to TRUE, the function disables all the privileges.
+ *
+ * @param[in] NewState
+ * A new list of privileges that the function will use it accordingly to
+ * either disable or enable the said privileges and change them.
+ *
+ * @param[in] NewStateCount
+ * The new total number count of privileges.
+ *
+ * @param[out] PreviousState
+ * If specified, the function will return the previous state list of privileges.
+ *
+ * @param[in] ApplyChanges
+ * If set to TRUE, the function will immediatelly apply the changes onto the
+ * token's privileges.
+ *
+ * @param[out] ChangedPrivileges
+ * The returned count number of changed privileges.
+ *
+ * @param[out] ChangesMade
+ * If TRUE, the function has made changes to the token's privileges. FALSE
+ * otherwise.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the function has successfully changed the list
+ * of privileges. STATUS_NOT_ALL_ASSIGNED is returned if not every privilege
+ * has been changed.
*/
_Must_inspect_result_
__kernel_entry
@@ -3985,6 +4596,54 @@ Cleanup:
return Status;
}
+/**
+ * @brief
+ * Creates an access token.
+ *
+ * @param[out] TokenHandle
+ * The returned created token handle to the caller.
+ *
+ * @param[in] DesiredAccess
+ * The desired access rights for the token that we're creating.
+ *
+ * @param[in] ObjectAttributes
+ * The object attributes for the token object that we're creating.
+ *
+ * @param[in] TokenType
+ * The type of token to assign for the newly created token.
+ *
+ * @param[in] AuthenticationId
+ * Authentication ID that represents the token's identity.
+ *
+ * @param[in] ExpirationTime
+ * Expiration time for the token. If set to -1, the token never expires.
+ *
+ * @param[in] TokenUser
+ * The main user entity for the token to assign.
+ *
+ * @param[in] TokenGroups
+ * Group list of SIDs for the token to assign.
+ *
+ * @param[in] TokenPrivileges
+ * Privileges for the token.
+ *
+ * @param[in] TokenOwner
+ * The main user that owns the newly created token.
+ *
+ * @param[in] TokenPrimaryGroup
+ * The primary group that represents as the main group of the token.
+ *
+ * @param[in] TokenDefaultDacl
+ * Discretionary access control list for the token. This limits on how
+ * the token can be used, accessed and used by whom.
+ *
+ * @param[in] TokenSource
+ * The source origin of the token who creates it.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the function has successfully created the token.
+ * A failure NTSTATUS code is returned otherwise.
+ */
__kernel_entry
NTSTATUS
NTAPI
@@ -4258,8 +4917,32 @@ Cleanup:
return Status;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Opens a token that is tied to a thread handle.
+ *
+ * @param[out] ThreadHandle
+ * Thread handle where the token is about to be opened.
+ *
+ * @param[in] DesiredAccess
+ * The request access right for the token.
+ *
+ * @param[in] OpenAsSelf
+ * If set to TRUE, the access check will be made with the security context
+ * of the process of the calling thread (opening as self). Otherwise the access
+ * check will be made with the security context of the calling thread instead.
+ *
+ * @param[in] HandleAttributes
+ * Handle attributes for the opened thread token handle.
+ *
+ * @param[out] TokenHandle
+ * The opened token handle returned to the caller for use.
+ *
+ * @return
+ * Returns STATUS_SUCCESS if the function has successfully opened the thread
+ * token. STATUS_CANT_OPEN_ANONYMOUS is returned if a token has SecurityAnonymous
+ * as impersonation level and we cannot open it. A failure NTSTATUS code is returned
+ * otherwise.
*/
NTSTATUS
NTAPI
@@ -4441,8 +5124,26 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
return Status;
}
-/*
- * @implemented
+/**
+ * @brief
+ * Opens a token that is tied to a thread handle.
+ *
+ * @param[out] ThreadHandle
+ * Thread handle where the token is about to be opened.
+ *
+ * @param[in] DesiredAccess
+ * The request access right for the token.
+ *
+ * @param[in] OpenAsSelf
+ * If set to TRUE, the access check will be made with the security context
+ * of the process of the calling thread (opening as self). Otherwise the access
+ * check will be made with the security context of the calling thread instead.
+ *
+ * @param[out] TokenHandle
+ * The opened token handle returned to the caller for use.
+ *
+ * @return
+ * See NtOpenThreadTokenEx.
*/
NTSTATUS NTAPI
NtOpenThreadToken(IN HANDLE ThreadHandle,
@@ -4556,6 +5257,33 @@ NtCompareTokens(
return Status;
}
+/**
+ * @unimplemented
+ * @brief
+ * Opens a token that is tied to a thread handle.
+ *
+ * @param[in] ExistingTokenHandle
... 24 lines suppressed ...