[NTOSKRNL]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 18 Feb 2014 17:51:45 +0000 (17:51 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 18 Feb 2014 17:51:45 +0000 (17:51 +0000)
- 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

svn path=/trunk/; revision=62245

reactos/ntoskrnl/include/internal/se.h
reactos/ntoskrnl/se/audit.c
reactos/ntoskrnl/se/priv.c
reactos/ntoskrnl/se/semgr.c
reactos/ntoskrnl/se/sid.c

index ec516eb..8c80fac 100644 (file)
@@ -143,6 +143,8 @@ extern PSID SeAliasBackupOpsSid;
 extern PSID SeAuthenticatedUsersSid;
 extern PSID SeRestrictedSid;
 extern PSID SeAnonymousLogonSid;
 extern PSID SeAuthenticatedUsersSid;
 extern PSID SeRestrictedSid;
 extern PSID SeAnonymousLogonSid;
+extern PSID SeLocalServiceSid;
+extern PSID SeNetworkServiceSid;
 
 /* Privileges */
 extern const LUID SeCreateTokenPrivilege;
 
 /* Privileges */
 extern const LUID SeCreateTokenPrivilege;
@@ -531,6 +533,20 @@ SeFastTraverseCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
                     IN ACCESS_MASK DesiredAccess,
                     IN KPROCESSOR_MODE AccessMode);
 
                     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 */
 #endif
 
 /* EOF */
index 1e583e8..f3d826e 100644 (file)
@@ -16,6 +16,8 @@
 
 #define SEP_PRIVILEGE_SET_MAX_COUNT 60
 
 
 #define SEP_PRIVILEGE_SET_MAX_COUNT 60
 
+UNICODE_STRING SeSubsystemName = RTL_CONSTANT_STRING(L"Security");
+
 /* PRIVATE FUNCTIONS***********************************************************/
 
 BOOLEAN
 /* PRIVATE FUNCTIONS***********************************************************/
 
 BOOLEAN
@@ -202,11 +204,59 @@ SepAdtPrivilegedServiceAuditAlarm(
     _In_ PTOKEN Token,
     _In_ PTOKEN PrimaryToken,
     _In_ PPRIVILEGE_SET Privileges,
     _In_ PTOKEN Token,
     _In_ PTOKEN PrimaryToken,
     _In_ PPRIVILEGE_SET Privileges,
-    _In_ BOOLEAN AccessGranted )
+    _In_ BOOLEAN AccessGranted)
 {
     UNIMPLEMENTED;
 }
 
 {
     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
 SeCaptureObjectTypeList(
 static
 NTSTATUS
 SeCaptureObjectTypeList(
@@ -477,7 +527,7 @@ SepAccessCheckAndAuditAlarm(
     }
 
     /* Check for audit privilege */
     }
 
     /* 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");
     if (!HaveAuditPrivilege && !(Flags & AUDIT_ALLOW_NO_PRIVILEGE))
     {
         DPRINT1("Caller does not have SeAuditPrivilege\n");
@@ -811,6 +861,7 @@ NtCloseObjectAuditAlarm(
     PVOID HandleId,
     BOOLEAN GenerateOnClose)
 {
     PVOID HandleId,
     BOOLEAN GenerateOnClose)
 {
+    SECURITY_SUBJECT_CONTEXT SubjectContext;
     UNICODE_STRING CapturedSubsystemName;
     KPROCESSOR_MODE PreviousMode;
     BOOLEAN UseImpersonationToken;
     UNICODE_STRING CapturedSubsystemName;
     KPROCESSOR_MODE PreviousMode;
     BOOLEAN UseImpersonationToken;
@@ -832,11 +883,15 @@ NtCloseObjectAuditAlarm(
         return STATUS_SUCCESS;
     }
 
         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");
     {
         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 */
     }
 
     /* Probe and capture the subsystem name */
@@ -846,7 +901,7 @@ NtCloseObjectAuditAlarm(
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to capture subsystem name!\n");
     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 */
     }
 
     /* Get the current thread and check if it's impersonating */
@@ -887,7 +942,14 @@ NtCloseObjectAuditAlarm(
         PsDereferencePrimaryToken(Token);
     }
 
         PsDereferencePrimaryToken(Token);
     }
 
-    return STATUS_SUCCESS;
+    Status = STATUS_SUCCESS;
+
+Cleanup:
+
+    /* Release the security subject context */
+    SeReleaseSubjectContext(&SubjectContext);
+
+    return Status;
 }
 
 
 }
 
 
@@ -986,6 +1048,9 @@ NtOpenObjectAuditAlarm(
         return Status;
     }
 
         return Status;
     }
 
+    /* Capture the security subject context */
+    SeCaptureSubjectContext(&SubjectContext);
+
     /* Validate the token's impersonation level */
     if ((ClientToken->TokenType == TokenImpersonation) &&
         (ClientToken->ImpersonationLevel < SecurityIdentification))
     /* Validate the token's impersonation level */
     if ((ClientToken->TokenType == TokenImpersonation) &&
         (ClientToken->ImpersonationLevel < SecurityIdentification))
@@ -996,7 +1061,7 @@ NtOpenObjectAuditAlarm(
     }
 
     /* Check for audit privilege */
     }
 
     /* Check for audit privilege */
-    if (!SeSinglePrivilegeCheck(SeAuditPrivilege, UserMode))
+    if (!SeCheckAuditPrivilege(&SubjectContext, UserMode))
     {
         DPRINT1("Caller does not have SeAuditPrivilege\n");
         Status = STATUS_PRIVILEGE_NOT_HELD;
     {
         DPRINT1("Caller does not have SeAuditPrivilege\n");
         Status = STATUS_PRIVILEGE_NOT_HELD;
@@ -1106,9 +1171,6 @@ NtOpenObjectAuditAlarm(
         goto Cleanup;
     }
 
         goto Cleanup;
     }
 
-    /* Capture the security subject context */
-    SeCaptureSubjectContext(&SubjectContext);
-
     /* Call the internal function */
     SepOpenObjectAuditAlarm(&SubjectContext,
                             &CapturedSubsystemName,
     /* Call the internal function */
     SepOpenObjectAuditAlarm(&SubjectContext,
                             &CapturedSubsystemName,
@@ -1124,9 +1186,6 @@ NtOpenObjectAuditAlarm(
                             AccessGranted,
                             &LocalGenerateOnClose);
 
                             AccessGranted,
                             &LocalGenerateOnClose);
 
-    /* Release the security subject context */
-    SeReleaseSubjectContext(&SubjectContext);
-
     Status = STATUS_SUCCESS;
 
     /* Enter SEH to copy the data back to user mode */
     Status = STATUS_SUCCESS;
 
     /* Enter SEH to copy the data back to user mode */
@@ -1158,6 +1217,9 @@ Cleanup:
     if (CapturedPrivilegeSet != NULL)
         ExFreePoolWithTag(CapturedPrivilegeSet, 'rPeS');
 
     if (CapturedPrivilegeSet != NULL)
         ExFreePoolWithTag(CapturedPrivilegeSet, 'rPeS');
 
+    /* Release the security subject context */
+    SeReleaseSubjectContext(&SubjectContext);
+
     ObDereferenceObject(ClientToken);
 
     return Status;
     ObDereferenceObject(ClientToken);
 
     return Status;
@@ -1213,12 +1275,15 @@ NtPrivilegedServiceAuditAlarm(
         return STATUS_BAD_IMPERSONATION_LEVEL;
     }
 
         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");
     {
         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? */
     }
 
     /* Do we have a subsystem name? */
@@ -1290,9 +1355,6 @@ NtPrivilegedServiceAuditAlarm(
     }
     _SEH2_END;
 
     }
     _SEH2_END;
 
-    /* Capture the security subject context */
-    SeCaptureSubjectContext(&SubjectContext);
-
     /* Call the internal function */
     SepAdtPrivilegedServiceAuditAlarm(&SubjectContext,
                                       SubsystemName ? &CapturedSubsystemName : NULL,
     /* Call the internal function */
     SepAdtPrivilegedServiceAuditAlarm(&SubjectContext,
                                       SubsystemName ? &CapturedSubsystemName : NULL,
@@ -1302,9 +1364,6 @@ NtPrivilegedServiceAuditAlarm(
                                       CapturedPrivileges,
                                       AccessGranted);
 
                                       CapturedPrivileges,
                                       AccessGranted);
 
-    /* Release the security subject context */
-    SeReleaseSubjectContext(&SubjectContext);
-
     Status = STATUS_SUCCESS;
 
 Cleanup:
     Status = STATUS_SUCCESS;
 
 Cleanup:
@@ -1318,6 +1377,9 @@ Cleanup:
     if (CapturedPrivileges != NULL)
         ExFreePoolWithTag(CapturedPrivileges, 'rPeS');
 
     if (CapturedPrivileges != NULL)
         ExFreePoolWithTag(CapturedPrivileges, 'rPeS');
 
+    /* Release the security subject context */
+    SeReleaseSubjectContext(&SubjectContext);
+
     ObDereferenceObject(ClientToken);
 
     return Status;
     ObDereferenceObject(ClientToken);
 
     return Status;
index 292da12..9014fa8 100644 (file)
@@ -252,6 +252,40 @@ SePrivilegePolicyCheck(
     return STATUS_SUCCESS;
 }
 
     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,
 NTSTATUS
 NTAPI
 SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src,
@@ -506,11 +540,11 @@ SeSinglePrivilegeCheck(IN LUID PrivilegeValue,
 
     if (PreviousMode != KernelMode)
     {
 
     if (PreviousMode != KernelMode)
     {
-#if 0
-        SePrivilegedServiceAuditAlarm(0,
+        SePrivilegedServiceAuditAlarm(NULL,
                                       &SubjectContext,
                                       &SubjectContext,
-                                      &PrivilegeValue);
-#endif
+                                      &Priv,
+                                      Result);
+
     }
 
     SeReleaseSubjectContext(&SubjectContext);
     }
 
     SeReleaseSubjectContext(&SubjectContext);
index 4d7c776..2c14c93 100644 (file)
@@ -74,10 +74,15 @@ SepInitExports(VOID)
     SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
     SepExports.SeRestrictedSid = SeRestrictedSid;
     SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
     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.SeUndockPrivilege = SeUndockPrivilege;
     SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
     SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
+    SepExports.SeManageVolumePrivilege = SeManageVolumePrivilege;
+    SepExports.SeImpersonatePrivilege = SeImpersonatePrivilege;
+    SepExports.SeCreateGlobalPrivilege = SeCreateGlobalPrivilege;
 
     SeExports = &SepExports;
     return TRUE;
 
     SeExports = &SepExports;
     return TRUE;
index 2ccbdf3..6cf3c19 100644 (file)
@@ -55,6 +55,8 @@ PSID SeAliasBackupOpsSid = NULL;
 PSID SeAuthenticatedUsersSid = NULL;
 PSID SeRestrictedSid = NULL;
 PSID SeAnonymousLogonSid = NULL;
 PSID SeAuthenticatedUsersSid = NULL;
 PSID SeRestrictedSid = NULL;
 PSID SeAnonymousLogonSid = NULL;
+PSID SeLocalServiceSid = NULL;
+PSID SeNetworkServiceSid = NULL;
 
 /* FUNCTIONS ******************************************************************/
 
 
 /* FUNCTIONS ******************************************************************/
 
@@ -135,6 +137,8 @@ SepInitSecurityIDs(VOID)
     SeAuthenticatedUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
     SeRestrictedSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
     SeAnonymousLogonSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
     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 ||
 
     if (SeNullSid == NULL || SeWorldSid == NULL ||
         SeLocalSid == NULL || SeCreatorOwnerSid == NULL ||
@@ -149,7 +153,8 @@ SepInitSecurityIDs(VOID)
         SeAliasAccountOpsSid == NULL || SeAliasSystemOpsSid == NULL ||
         SeAliasPrintOpsSid == NULL || SeAliasBackupOpsSid == NULL ||
         SeAuthenticatedUsersSid == NULL || SeRestrictedSid == NULL ||
         SeAliasAccountOpsSid == NULL || SeAliasSystemOpsSid == NULL ||
         SeAliasPrintOpsSid == NULL || SeAliasBackupOpsSid == NULL ||
         SeAuthenticatedUsersSid == NULL || SeRestrictedSid == NULL ||
-        SeAnonymousLogonSid == NULL)
+        SeAnonymousLogonSid == NULL || SeLocalServiceSid == NULL ||
+        SeNetworkServiceSid == NULL)
     {
         FreeInitializedSids();
         return FALSE;
     {
         FreeInitializedSids();
         return FALSE;
@@ -183,6 +188,8 @@ SepInitSecurityIDs(VOID)
     RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1);
     RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1);
     RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1);
     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;
 
     SubAuthority = RtlSubAuthoritySid(SeNullSid, 0);
     *SubAuthority = SECURITY_NULL_RID;
@@ -254,6 +261,10 @@ SepInitSecurityIDs(VOID)
     *SubAuthority = SECURITY_RESTRICTED_CODE_RID;
     SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0);
     *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID;
     *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;
 }
 
     return TRUE;
 }