mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
[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 svn path=/trunk/; revision=62245
This commit is contained in:
parent
ea1508451e
commit
5ebaa3c3dd
5 changed files with 157 additions and 29 deletions
|
@ -143,6 +143,8 @@ extern PSID SeAliasBackupOpsSid;
|
|||
extern PSID SeAuthenticatedUsersSid;
|
||||
extern PSID SeRestrictedSid;
|
||||
extern PSID SeAnonymousLogonSid;
|
||||
extern PSID SeLocalServiceSid;
|
||||
extern PSID SeNetworkServiceSid;
|
||||
|
||||
/* Privileges */
|
||||
extern const LUID SeCreateTokenPrivilege;
|
||||
|
@ -531,6 +533,20 @@ SeFastTraverseCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|||
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 */
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#define SEP_PRIVILEGE_SET_MAX_COUNT 60
|
||||
|
||||
UNICODE_STRING SeSubsystemName = RTL_CONSTANT_STRING(L"Security");
|
||||
|
||||
/* PRIVATE FUNCTIONS***********************************************************/
|
||||
|
||||
BOOLEAN
|
||||
|
@ -202,11 +204,59 @@ SepAdtPrivilegedServiceAuditAlarm(
|
|||
_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
|
||||
SeCaptureObjectTypeList(
|
||||
|
@ -477,7 +527,7 @@ SepAccessCheckAndAuditAlarm(
|
|||
}
|
||||
|
||||
/* 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 @@ NtCloseObjectAuditAlarm(
|
|||
PVOID HandleId,
|
||||
BOOLEAN GenerateOnClose)
|
||||
{
|
||||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||
UNICODE_STRING CapturedSubsystemName;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
BOOLEAN UseImpersonationToken;
|
||||
|
@ -832,11 +883,15 @@ NtCloseObjectAuditAlarm(
|
|||
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 @@ NtCloseObjectAuditAlarm(
|
|||
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 @@ NtCloseObjectAuditAlarm(
|
|||
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;
|
||||
}
|
||||
|
||||
/* Capture the security subject context */
|
||||
SeCaptureSubjectContext(&SubjectContext);
|
||||
|
||||
/* Validate the token's impersonation level */
|
||||
if ((ClientToken->TokenType == TokenImpersonation) &&
|
||||
(ClientToken->ImpersonationLevel < SecurityIdentification))
|
||||
|
@ -996,7 +1061,7 @@ NtOpenObjectAuditAlarm(
|
|||
}
|
||||
|
||||
/* Check for audit privilege */
|
||||
if (!SeSinglePrivilegeCheck(SeAuditPrivilege, UserMode))
|
||||
if (!SeCheckAuditPrivilege(&SubjectContext, UserMode))
|
||||
{
|
||||
DPRINT1("Caller does not have SeAuditPrivilege\n");
|
||||
Status = STATUS_PRIVILEGE_NOT_HELD;
|
||||
|
@ -1106,9 +1171,6 @@ NtOpenObjectAuditAlarm(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Capture the security subject context */
|
||||
SeCaptureSubjectContext(&SubjectContext);
|
||||
|
||||
/* Call the internal function */
|
||||
SepOpenObjectAuditAlarm(&SubjectContext,
|
||||
&CapturedSubsystemName,
|
||||
|
@ -1124,9 +1186,6 @@ NtOpenObjectAuditAlarm(
|
|||
AccessGranted,
|
||||
&LocalGenerateOnClose);
|
||||
|
||||
/* Release the security subject context */
|
||||
SeReleaseSubjectContext(&SubjectContext);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* Enter SEH to copy the data back to user mode */
|
||||
|
@ -1158,6 +1217,9 @@ Cleanup:
|
|||
if (CapturedPrivilegeSet != NULL)
|
||||
ExFreePoolWithTag(CapturedPrivilegeSet, 'rPeS');
|
||||
|
||||
/* Release the security subject context */
|
||||
SeReleaseSubjectContext(&SubjectContext);
|
||||
|
||||
ObDereferenceObject(ClientToken);
|
||||
|
||||
return Status;
|
||||
|
@ -1213,12 +1275,15 @@ NtPrivilegedServiceAuditAlarm(
|
|||
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 @@ NtPrivilegedServiceAuditAlarm(
|
|||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Capture the security subject context */
|
||||
SeCaptureSubjectContext(&SubjectContext);
|
||||
|
||||
/* Call the internal function */
|
||||
SepAdtPrivilegedServiceAuditAlarm(&SubjectContext,
|
||||
SubsystemName ? &CapturedSubsystemName : NULL,
|
||||
|
@ -1302,9 +1364,6 @@ NtPrivilegedServiceAuditAlarm(
|
|||
CapturedPrivileges,
|
||||
AccessGranted);
|
||||
|
||||
/* Release the security subject context */
|
||||
SeReleaseSubjectContext(&SubjectContext);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
|
@ -1318,6 +1377,9 @@ Cleanup:
|
|||
if (CapturedPrivileges != NULL)
|
||||
ExFreePoolWithTag(CapturedPrivileges, 'rPeS');
|
||||
|
||||
/* Release the security subject context */
|
||||
SeReleaseSubjectContext(&SubjectContext);
|
||||
|
||||
ObDereferenceObject(ClientToken);
|
||||
|
||||
return Status;
|
||||
|
|
|
@ -252,6 +252,40 @@ SePrivilegePolicyCheck(
|
|||
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 @@ SeSinglePrivilegeCheck(IN LUID PrivilegeValue,
|
|||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
#if 0
|
||||
SePrivilegedServiceAuditAlarm(0,
|
||||
SePrivilegedServiceAuditAlarm(NULL,
|
||||
&SubjectContext,
|
||||
&PrivilegeValue);
|
||||
#endif
|
||||
&Priv,
|
||||
Result);
|
||||
|
||||
}
|
||||
|
||||
SeReleaseSubjectContext(&SubjectContext);
|
||||
|
|
|
@ -74,10 +74,15 @@ SepInitExports(VOID)
|
|||
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;
|
||||
|
|
|
@ -55,6 +55,8 @@ PSID SeAliasBackupOpsSid = NULL;
|
|||
PSID SeAuthenticatedUsersSid = NULL;
|
||||
PSID SeRestrictedSid = NULL;
|
||||
PSID SeAnonymousLogonSid = NULL;
|
||||
PSID SeLocalServiceSid = NULL;
|
||||
PSID SeNetworkServiceSid = NULL;
|
||||
|
||||
/* 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);
|
||||
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 @@ SepInitSecurityIDs(VOID)
|
|||
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 @@ SepInitSecurityIDs(VOID)
|
|||
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 @@ SepInitSecurityIDs(VOID)
|
|||
*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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue