-/* $Id: semgr.c,v 1.32 2004/07/13 16:59:35 ekohl Exp $
+/* $Id: semgr.c,v 1.33 2004/07/14 14:25:31 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#include <internal/ps.h>
#include <internal/se.h>
+#define NDEBUG
#include <internal/debug.h>
#define TAG_SXPT TAG('S', 'X', 'P', 'T')
#if 0
-VOID SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
- PSID* Owner,
- PSID* PrimaryGroup,
- PSID* ProcessOwner,
- PSID* ProcessPrimaryGroup,
- PACL* DefaultDacl)
+VOID
+SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ PSID* Owner,
+ PSID* PrimaryGroup,
+ PSID* ProcessOwner,
+ PSID* ProcessPrimaryGroup,
+ PACL* DefaultDacl)
{
- PACCESS_TOKEN Token;
-
- if (SubjectContext->ClientToken != NULL)
- {
+ PACCESS_TOKEN Token;
+
+ if (SubjectContext->ClientToken != NULL)
+ {
Token = SubjectContext->ClientToken;
- }
- else
- {
+ }
+ else
+ {
Token = SubjectContext->PrimaryToken;
- }
- *Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
- *PrimaryGroup = Token->PrimaryGroup;
- *DefaultDacl = Token->DefaultDacl;
- *ProcessOwner = SubjectContext->PrimaryToken->
- UserAndGroups[Token->DefaultOwnerIndex].Sid;
- *ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
+ }
+ *Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
+ *PrimaryGroup = Token->PrimaryGroup;
+ *DefaultDacl = Token->DefaultDacl;
+ *ProcessOwner = SubjectContext->PrimaryToken->
+ UserAndGroups[Token->DefaultOwnerIndex].Sid;
+ *ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
}
-NTSTATUS SepInheritAcl(PACL Acl,
- BOOLEAN IsDirectoryObject,
- PSID Owner,
- PSID PrimaryGroup,
- PACL DefaultAcl,
- PSID ProcessOwner,
- PSID ProcessGroup,
- PGENERIC_MAPPING GenericMapping)
+
+NTSTATUS
+SepInheritAcl(PACL Acl,
+ BOOLEAN IsDirectoryObject,
+ PSID Owner,
+ PSID PrimaryGroup,
+ PACL DefaultAcl,
+ PSID ProcessOwner,
+ PSID ProcessGroup,
+ PGENERIC_MAPPING GenericMapping)
{
- if (Acl == NULL)
- {
+ if (Acl == NULL)
+ {
return(STATUS_UNSUCCESSFUL);
- }
- if (Acl->AclRevision != 2 &&
- Acl->AclRevision != 3 )
- {
+ }
+
+ if (Acl->AclRevision != 2 &&
+ Acl->AclRevision != 3 )
+ {
return(STATUS_UNSUCCESSFUL);
- }
-
+ }
+
+
}
#endif
OUT PACCESS_MASK GrantedAccess,
OUT PNTSTATUS AccessStatus)
{
- ULONG i;
- PACL Dacl;
- BOOLEAN Present;
- BOOLEAN Defaulted;
- NTSTATUS Status;
- PACE CurrentAce;
- PSID Sid;
- ACCESS_MASK CurrentAccess;
-
- CurrentAccess = PreviouslyGrantedAccess;
-
- /*
- * Check the DACL
- */
- Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
- &Present,
- &Dacl,
- &Defaulted);
- if (!NT_SUCCESS(Status))
- {
- *AccessStatus = Status;
- return FALSE;
- }
-
- CurrentAce = (PACE)(Dacl + 1);
- for (i = 0; i < Dacl->AceCount; i++)
- {
- Sid = (PSID)(CurrentAce + 1);
- if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
- {
- if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
- {
- *AccessStatus = STATUS_ACCESS_DENIED;
- *GrantedAccess = 0;
- return(STATUS_SUCCESS);
- }
- }
-
- if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
- {
- if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
- {
- CurrentAccess |= CurrentAce->AccessMask;
- }
- }
- }
- if (!(CurrentAccess & DesiredAccess) &&
- !((~CurrentAccess) & DesiredAccess))
- {
- *AccessStatus = STATUS_ACCESS_DENIED;
- }
- else
- {
- *AccessStatus = STATUS_SUCCESS;
- }
- *GrantedAccess = CurrentAccess;
-
- return TRUE;
-}
-
-
-NTSTATUS STDCALL
-NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN HANDLE TokenHandle,
- IN ACCESS_MASK DesiredAccess,
- IN PGENERIC_MAPPING GenericMapping,
- OUT PPRIVILEGE_SET PrivilegeSet,
- OUT PULONG ReturnLength,
- OUT PACCESS_MASK GrantedAccess,
- OUT PNTSTATUS AccessStatus)
-{
- KPROCESSOR_MODE PreviousMode;
+ LUID_AND_ATTRIBUTES Privilege;
+ ACCESS_MASK CurrentAccess;
PACCESS_TOKEN Token;
+ ULONG i;
+ PACL Dacl;
BOOLEAN Present;
BOOLEAN Defaulted;
PACE CurrentAce;
- PACL Dacl;
PSID Sid;
- ACCESS_MASK CurrentAccess;
- ULONG i;
NTSTATUS Status;
- DPRINT("NtAccessCheck() called\n");
-
- PreviousMode = KeGetPreviousMode();
- if (PreviousMode == KernelMode)
- {
- *GrantedAccess = DesiredAccess;
- *AccessStatus = STATUS_SUCCESS;
- return STATUS_SUCCESS;
- }
-
- Status = ObReferenceObjectByHandle(TokenHandle,
- TOKEN_QUERY,
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference token (Status %lx)\n", Status);
- return Status;
- }
-
- /* Check token type */
- if (Token->TokenType != TokenImpersonation)
- {
- DPRINT1("No impersonation token\n");
- ObDereferenceObject(Token);
- return STATUS_ACCESS_VIOLATION;
- }
+ CurrentAccess = PreviouslyGrantedAccess;
- /* Check impersonation level */
- if (Token->ImpersonationLevel < SecurityAnonymous)
- {
- DPRINT1("Invalid impersonation level\n");
- ObDereferenceObject(Token);
- return STATUS_ACCESS_VIOLATION;
- }
+ Token = SubjectSecurityContext->ClientToken ?
+ SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
/* Get the DACL */
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
&Defaulted);
if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlGetDaclSecurityDescriptor() failed (Status %lx)\n", Status);
- ObDereferenceObject(Token);
- return Status;
- }
+ *AccessStatus = Status;
+ return FALSE;
+ }
/* RULE 1: Grant desired access if the object is unprotected */
if (Dacl == NULL)
{
*GrantedAccess = DesiredAccess;
*AccessStatus = STATUS_SUCCESS;
- return STATUS_SUCCESS;
+ return TRUE;
}
- CurrentAccess = 0;
+ CurrentAccess = PreviouslyGrantedAccess;
+
+ /* RULE 2: Check token for 'take ownership' privilege */
+ Privilege.Luid = SeTakeOwnershipPrivilege;
+ Privilege.Attributes = SE_PRIVILEGE_ENABLED;
- /* FIXME: RULE 2: Check token for 'take ownership' privilege */
+ if (SepPrivilegeCheck(Token,
+ &Privilege,
+ 1,
+ PRIVILEGE_SET_ALL_NECESSARY,
+ AccessMode))
+ {
+ CurrentAccess |= WRITE_OWNER;
+ if (DesiredAccess == CurrentAccess)
+ {
+ *GrantedAccess = CurrentAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
+ }
+ }
/* RULE 3: Check whether the token is the owner */
Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
- ObDereferenceObject(Token);
- return Status;
+ *AccessStatus = Status;
+ return FALSE;
}
if (SepSidInToken(Token, Sid))
CurrentAccess |= (READ_CONTROL | WRITE_DAC);
if (DesiredAccess == CurrentAccess)
{
- *AccessStatus = STATUS_SUCCESS;
*GrantedAccess = CurrentAccess;
- return STATUS_SUCCESS;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
}
}
{
if (SepSidInToken(Token, Sid))
{
- *AccessStatus = STATUS_ACCESS_DENIED;
*GrantedAccess = 0;
- return STATUS_SUCCESS;
+ *AccessStatus = STATUS_ACCESS_DENIED;
+ return TRUE;
}
}
DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
CurrentAccess, DesiredAccess);
- ObDereferenceObject(Token);
-
*GrantedAccess = CurrentAccess & DesiredAccess;
*AccessStatus =
(*GrantedAccess == DesiredAccess) ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
+ return TRUE;
+}
+
+
+NTSTATUS STDCALL
+NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN HANDLE TokenHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN PGENERIC_MAPPING GenericMapping,
+ OUT PPRIVILEGE_SET PrivilegeSet,
+ OUT PULONG ReturnLength,
+ OUT PACCESS_MASK GrantedAccess,
+ OUT PNTSTATUS AccessStatus)
+{
+ SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
+ KPROCESSOR_MODE PreviousMode;
+ PACCESS_TOKEN Token;
+ NTSTATUS Status;
+
+ DPRINT("NtAccessCheck() called\n");
+
+ PreviousMode = KeGetPreviousMode();
+ if (PreviousMode == KernelMode)
+ {
+ *GrantedAccess = DesiredAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
+ }
+
+ Status = ObReferenceObjectByHandle(TokenHandle,
+ TOKEN_QUERY,
+ SepTokenObjectType,
+ PreviousMode,
+ (PVOID*)&Token,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference token (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /* Check token type */
+ if (Token->TokenType != TokenImpersonation)
+ {
+ DPRINT1("No impersonation token\n");
+ ObDereferenceObject(Token);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ /* Check impersonation level */
+ if (Token->ImpersonationLevel < SecurityAnonymous)
+ {
+ DPRINT1("Invalid impersonation level\n");
+ ObDereferenceObject(Token);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ RtlZeroMemory(&SubjectSecurityContext,
+ sizeof(SECURITY_SUBJECT_CONTEXT));
+ SubjectSecurityContext.ClientToken = Token;
+ SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
+
+ /* FIXME: Lock subject context */
+
+ if (!SeAccessCheck(SecurityDescriptor,
+ &SubjectSecurityContext,
+ TRUE,
+ DesiredAccess,
+ 0,
+ &PrivilegeSet,
+ GenericMapping,
+ PreviousMode,
+ GrantedAccess,
+ AccessStatus))
+ {
+ Status = *AccessStatus;
+ }
+ else
+ {
+ Status = STATUS_SUCCESS;
+ }
+
+ /* FIXME: Unlock subject context */
+
+ ObDereferenceObject(Token);
+
DPRINT("NtAccessCheck() done\n");
- return STATUS_SUCCESS;
+ return Status;
}
/* EOF */