Author: tkreuzer
Date: Tue Feb 18 17:51:45 2014
New Revision: 62245
URL:
http://svn.reactos.org/svn/reactos?rev=62245&view=rev
Log:
[NTOSKRNL]
- Implement SeCheckAuditPrivilege and use it instead of SeSinglePrivilegeCheck, because
the latter uses the effective token and we want the primary token
- Implement SePrivilegedServiceAuditAlarm
- Add and initialize missing SeLocalServiceSid and SeNetworkServiceSid
Modified:
trunk/reactos/ntoskrnl/include/internal/se.h
trunk/reactos/ntoskrnl/se/audit.c
trunk/reactos/ntoskrnl/se/priv.c
trunk/reactos/ntoskrnl/se/semgr.c
trunk/reactos/ntoskrnl/se/sid.c
Modified: trunk/reactos/ntoskrnl/include/internal/se.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] Tue Feb 18 17:51:45 2014
@@ -143,6 +143,8 @@
extern PSID SeAuthenticatedUsersSid;
extern PSID SeRestrictedSid;
extern PSID SeAnonymousLogonSid;
+extern PSID SeLocalServiceSid;
+extern PSID SeNetworkServiceSid;
/* Privileges */
extern const LUID SeCreateTokenPrivilege;
@@ -531,6 +533,20 @@
IN ACCESS_MASK DesiredAccess,
IN KPROCESSOR_MODE AccessMode);
+BOOLEAN
+NTAPI
+SeCheckAuditPrivilege(
+ _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ _In_ KPROCESSOR_MODE PreviousMode);
+
+VOID
+NTAPI
+SePrivilegedServiceAuditAlarm(
+ _In_opt_ PUNICODE_STRING ServiceName,
+ _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ _In_ PPRIVILEGE_SET PrivilegeSet,
+ _In_ BOOLEAN AccessGranted);
+
#endif
/* EOF */
Modified: trunk/reactos/ntoskrnl/se/audit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/audit.c?rev=62…
==============================================================================
--- trunk/reactos/ntoskrnl/se/audit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/se/audit.c [iso-8859-1] Tue Feb 18 17:51:45 2014
@@ -15,6 +15,8 @@
#include <debug.h>
#define SEP_PRIVILEGE_SET_MAX_COUNT 60
+
+UNICODE_STRING SeSubsystemName = RTL_CONSTANT_STRING(L"Security");
/* PRIVATE FUNCTIONS***********************************************************/
@@ -202,10 +204,58 @@
_In_ PTOKEN Token,
_In_ PTOKEN PrimaryToken,
_In_ PPRIVILEGE_SET Privileges,
- _In_ BOOLEAN AccessGranted )
+ _In_ BOOLEAN AccessGranted)
{
UNIMPLEMENTED;
}
+
+VOID
+NTAPI
+SePrivilegedServiceAuditAlarm(
+ _In_opt_ PUNICODE_STRING ServiceName,
+ _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ _In_ PPRIVILEGE_SET PrivilegeSet,
+ _In_ BOOLEAN AccessGranted)
+{
+ PTOKEN EffectiveToken;
+ PSID UserSid;
+ PAGED_CODE();
+
+ /* Get the effective token */
+ if (SubjectContext->ClientToken != NULL)
+ EffectiveToken = SubjectContext->ClientToken;
+ else
+ EffectiveToken = SubjectContext->PrimaryToken;
+
+ /* Get the user SID */
+ UserSid = EffectiveToken->UserAndGroups->Sid;
+
+ /* Check if this is the local system SID */
+ if (RtlEqualSid(UserSid, SeLocalSystemSid))
+ {
+ /* Nothing to do */
+ return;
+ }
+
+ /* Check if this is the network service or local service SID */
+ if (RtlEqualSid(UserSid, SeExports->SeNetworkServiceSid) ||
+ RtlEqualSid(UserSid, SeExports->SeLocalServiceSid))
+ {
+ // FIXME: should continue for a certain set of privileges
+ return;
+ }
+
+ /* Call the worker function */
+ SepAdtPrivilegedServiceAuditAlarm(SubjectContext,
+ &SeSubsystemName,
+ ServiceName,
+ SubjectContext->ClientToken,
+ SubjectContext->PrimaryToken,
+ PrivilegeSet,
+ AccessGranted);
+
+}
+
static
NTSTATUS
@@ -477,7 +527,7 @@
}
/* Check for audit privilege */
- HaveAuditPrivilege = SeSinglePrivilegeCheck(SeAuditPrivilege, UserMode);
+ HaveAuditPrivilege = SeCheckAuditPrivilege(&SubjectContext, UserMode);
if (!HaveAuditPrivilege && !(Flags & AUDIT_ALLOW_NO_PRIVILEGE))
{
DPRINT1("Caller does not have SeAuditPrivilege\n");
@@ -811,6 +861,7 @@
PVOID HandleId,
BOOLEAN GenerateOnClose)
{
+ SECURITY_SUBJECT_CONTEXT SubjectContext;
UNICODE_STRING CapturedSubsystemName;
KPROCESSOR_MODE PreviousMode;
BOOLEAN UseImpersonationToken;
@@ -832,11 +883,15 @@
return STATUS_SUCCESS;
}
- /* Validate privilege */
- if (!SeSinglePrivilegeCheck(SeAuditPrivilege, PreviousMode))
+ /* Capture the security subject context */
+ SeCaptureSubjectContext(&SubjectContext);
+
+ /* Check for audit privilege */
+ if (!SeCheckAuditPrivilege(&SubjectContext, PreviousMode))
{
DPRINT1("Caller does not have SeAuditPrivilege\n");
- return STATUS_PRIVILEGE_NOT_HELD;
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ goto Cleanup;
}
/* Probe and capture the subsystem name */
@@ -846,7 +901,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to capture subsystem name!\n");
- return Status;
+ goto Cleanup;
}
/* Get the current thread and check if it's impersonating */
@@ -887,7 +942,14 @@
PsDereferencePrimaryToken(Token);
}
- return STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
+
+Cleanup:
+
+ /* Release the security subject context */
+ SeReleaseSubjectContext(&SubjectContext);
+
+ return Status;
}
@@ -986,6 +1048,9 @@
return Status;
}
+ /* Capture the security subject context */
+ SeCaptureSubjectContext(&SubjectContext);
+
/* Validate the token's impersonation level */
if ((ClientToken->TokenType == TokenImpersonation) &&
(ClientToken->ImpersonationLevel < SecurityIdentification))
@@ -996,7 +1061,7 @@
}
/* Check for audit privilege */
- if (!SeSinglePrivilegeCheck(SeAuditPrivilege, UserMode))
+ if (!SeCheckAuditPrivilege(&SubjectContext, UserMode))
{
DPRINT1("Caller does not have SeAuditPrivilege\n");
Status = STATUS_PRIVILEGE_NOT_HELD;
@@ -1105,9 +1170,6 @@
DPRINT1("Failed to capture object name!\n");
goto Cleanup;
}
-
- /* Capture the security subject context */
- SeCaptureSubjectContext(&SubjectContext);
/* Call the internal function */
SepOpenObjectAuditAlarm(&SubjectContext,
@@ -1124,39 +1186,39 @@
AccessGranted,
&LocalGenerateOnClose);
+ Status = STATUS_SUCCESS;
+
+ /* Enter SEH to copy the data back to user mode */
+ _SEH2_TRY
+ {
+ *GenerateOnClose = LocalGenerateOnClose;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ DPRINT1("Exception while copying back data: 0x%lx\n", Status);
+ }
+ _SEH2_END;
+
+Cleanup:
+
+ if (CapturedObjectName.Buffer != NULL)
+ ReleaseCapturedUnicodeString(&CapturedObjectName, UserMode);
+
+ if (CapturedObjectTypeName.Buffer != NULL)
+ ReleaseCapturedUnicodeString(&CapturedObjectTypeName, UserMode);
+
+ if (CapturedSubsystemName.Buffer != NULL)
+ ReleaseCapturedUnicodeString(&CapturedSubsystemName, UserMode);
+
+ if (CapturedSecurityDescriptor != NULL)
+ SeReleaseSecurityDescriptor(CapturedSecurityDescriptor, UserMode, FALSE);
+
+ if (CapturedPrivilegeSet != NULL)
+ ExFreePoolWithTag(CapturedPrivilegeSet, 'rPeS');
+
/* Release the security subject context */
SeReleaseSubjectContext(&SubjectContext);
-
- Status = STATUS_SUCCESS;
-
- /* Enter SEH to copy the data back to user mode */
- _SEH2_TRY
- {
- *GenerateOnClose = LocalGenerateOnClose;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- DPRINT1("Exception while copying back data: 0x%lx\n", Status);
- }
- _SEH2_END;
-
-Cleanup:
-
- if (CapturedObjectName.Buffer != NULL)
- ReleaseCapturedUnicodeString(&CapturedObjectName, UserMode);
-
- if (CapturedObjectTypeName.Buffer != NULL)
- ReleaseCapturedUnicodeString(&CapturedObjectTypeName, UserMode);
-
- if (CapturedSubsystemName.Buffer != NULL)
- ReleaseCapturedUnicodeString(&CapturedSubsystemName, UserMode);
-
- if (CapturedSecurityDescriptor != NULL)
- SeReleaseSecurityDescriptor(CapturedSecurityDescriptor, UserMode, FALSE);
-
- if (CapturedPrivilegeSet != NULL)
- ExFreePoolWithTag(CapturedPrivilegeSet, 'rPeS');
ObDereferenceObject(ClientToken);
@@ -1213,12 +1275,15 @@
return STATUS_BAD_IMPERSONATION_LEVEL;
}
- /* Validate privilege */
- if (!SeSinglePrivilegeCheck(SeAuditPrivilege, PreviousMode))
+ /* Capture the security subject context */
+ SeCaptureSubjectContext(&SubjectContext);
+
+ /* Check for audit privilege */
+ if (!SeCheckAuditPrivilege(&SubjectContext, PreviousMode))
{
DPRINT1("Caller does not have SeAuditPrivilege\n");
- ObDereferenceObject(ClientToken);
- return STATUS_PRIVILEGE_NOT_HELD;
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ goto Cleanup;
}
/* Do we have a subsystem name? */
@@ -1290,9 +1355,6 @@
}
_SEH2_END;
- /* Capture the security subject context */
- SeCaptureSubjectContext(&SubjectContext);
-
/* Call the internal function */
SepAdtPrivilegedServiceAuditAlarm(&SubjectContext,
SubsystemName ? &CapturedSubsystemName : NULL,
@@ -1302,9 +1364,6 @@
CapturedPrivileges,
AccessGranted);
- /* Release the security subject context */
- SeReleaseSubjectContext(&SubjectContext);
-
Status = STATUS_SUCCESS;
Cleanup:
@@ -1317,6 +1376,9 @@
if (CapturedPrivileges != NULL)
ExFreePoolWithTag(CapturedPrivileges, 'rPeS');
+
+ /* Release the security subject context */
+ SeReleaseSubjectContext(&SubjectContext);
ObDereferenceObject(ClientToken);
Modified: trunk/reactos/ntoskrnl/se/priv.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/priv.c?rev=622…
==============================================================================
--- trunk/reactos/ntoskrnl/se/priv.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/se/priv.c [iso-8859-1] Tue Feb 18 17:51:45 2014
@@ -252,6 +252,40 @@
return STATUS_SUCCESS;
}
+BOOLEAN
+NTAPI
+SeCheckAuditPrivilege(
+ _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ _In_ KPROCESSOR_MODE PreviousMode)
+{
+ PRIVILEGE_SET PrivilegeSet;
+ BOOLEAN Result;
+ PAGED_CODE();
+
+ /* Initialize the privilege set with the single privilege */
+ PrivilegeSet.PrivilegeCount = 1;
+ PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
+ PrivilegeSet.Privilege[0].Luid = SeAuditPrivilege;
+ PrivilegeSet.Privilege[0].Attributes = 0;
+
+ /* Check against the primary token! */
+ Result = SepPrivilegeCheck(SubjectContext->PrimaryToken,
+ &PrivilegeSet.Privilege[0],
+ 1,
+ PRIVILEGE_SET_ALL_NECESSARY,
+ PreviousMode);
+
+ if (PreviousMode != KernelMode)
+ {
+ SePrivilegedServiceAuditAlarm(NULL,
+ SubjectContext,
+ &PrivilegeSet,
+ Result);
+ }
+
+ return Result;
+}
+
NTSTATUS
NTAPI
SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src,
@@ -506,11 +540,11 @@
if (PreviousMode != KernelMode)
{
-#if 0
- SePrivilegedServiceAuditAlarm(0,
+ SePrivilegedServiceAuditAlarm(NULL,
&SubjectContext,
- &PrivilegeValue);
-#endif
+ &Priv,
+ Result);
+
}
SeReleaseSubjectContext(&SubjectContext);
Modified: trunk/reactos/ntoskrnl/se/semgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/semgr.c?rev=62…
==============================================================================
--- trunk/reactos/ntoskrnl/se/semgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/se/semgr.c [iso-8859-1] Tue Feb 18 17:51:45 2014
@@ -74,10 +74,15 @@
SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
SepExports.SeRestrictedSid = SeRestrictedSid;
SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
+ SepExports.SeLocalServiceSid = SeLocalServiceSid;
+ SepExports.SeNetworkServiceSid = SeNetworkServiceSid;
SepExports.SeUndockPrivilege = SeUndockPrivilege;
SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
+ SepExports.SeManageVolumePrivilege = SeManageVolumePrivilege;
+ SepExports.SeImpersonatePrivilege = SeImpersonatePrivilege;
+ SepExports.SeCreateGlobalPrivilege = SeCreateGlobalPrivilege;
SeExports = &SepExports;
return TRUE;
Modified: trunk/reactos/ntoskrnl/se/sid.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/sid.c?rev=6224…
==============================================================================
--- trunk/reactos/ntoskrnl/se/sid.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/se/sid.c [iso-8859-1] Tue Feb 18 17:51:45 2014
@@ -55,6 +55,8 @@
PSID SeAuthenticatedUsersSid = NULL;
PSID SeRestrictedSid = NULL;
PSID SeAnonymousLogonSid = NULL;
+PSID SeLocalServiceSid = NULL;
+PSID SeNetworkServiceSid = NULL;
/* FUNCTIONS ******************************************************************/
@@ -135,6 +137,8 @@
SeAuthenticatedUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
SeRestrictedSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
SeAnonymousLogonSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
+ SeLocalServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
+ SeNetworkServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
if (SeNullSid == NULL || SeWorldSid == NULL ||
SeLocalSid == NULL || SeCreatorOwnerSid == NULL ||
@@ -149,7 +153,8 @@
SeAliasAccountOpsSid == NULL || SeAliasSystemOpsSid == NULL ||
SeAliasPrintOpsSid == NULL || SeAliasBackupOpsSid == NULL ||
SeAuthenticatedUsersSid == NULL || SeRestrictedSid == NULL ||
- SeAnonymousLogonSid == NULL)
+ SeAnonymousLogonSid == NULL || SeLocalServiceSid == NULL ||
+ SeNetworkServiceSid == NULL)
{
FreeInitializedSids();
return FALSE;
@@ -183,6 +188,8 @@
RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1);
RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1);
RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1);
+ RtlInitializeSid(SeLocalServiceSid, &SeNtSidAuthority, 1);
+ RtlInitializeSid(SeNetworkServiceSid, &SeNtSidAuthority, 1);
SubAuthority = RtlSubAuthoritySid(SeNullSid, 0);
*SubAuthority = SECURITY_NULL_RID;
@@ -254,6 +261,10 @@
*SubAuthority = SECURITY_RESTRICTED_CODE_RID;
SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0);
*SubAuthority = SECURITY_ANONYMOUS_LOGON_RID;
+ SubAuthority = RtlSubAuthoritySid(SeLocalServiceSid, 0);
+ *SubAuthority = SECURITY_LOCAL_SERVICE_RID;
+ SubAuthority = RtlSubAuthoritySid(SeNetworkServiceSid, 0);
+ *SubAuthority = SECURITY_NETWORK_SERVICE_RID;
return TRUE;
}