-/* $Id: semgr.c,v 1.15 2000/01/26 10:07:30 dwelch Exp $
+/* $Id: semgr.c,v 1.35 2004/07/19 12:45:56 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <internal/se.h>
+#define NDEBUG
#include <internal/debug.h>
-/* FUNCTIONS ***************************************************************/
+#define TAG_SXPT TAG('S', 'X', 'P', 'T')
-VOID SepReferenceLogonSession(PLUID AuthenticationId)
-{
- UNIMPLEMENTED;
-}
-VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
+/* GLOBALS ******************************************************************/
+
+PSE_EXPORTS EXPORTED SeExports = NULL;
+
+
+/* PROTOTYPES ***************************************************************/
+
+static BOOLEAN SepInitExports(VOID);
+
+/* FUNCTIONS ****************************************************************/
+
+
+BOOLEAN INIT_FUNCTION
+SeInit1(VOID)
{
- UNIMPLEMENTED;
+ SepInitLuid();
+
+ if (!SepInitSecurityIDs())
+ return FALSE;
+
+ if (!SepInitDACLs())
+ return FALSE;
+
+ if (!SepInitSDs())
+ return FALSE;
+
+ SepInitPrivileges();
+
+ if (!SepInitExports())
+ return FALSE;
+
+ return TRUE;
}
-NTSTATUS STDCALL NtPrivilegedServiceAuditAlarm(
- IN PUNICODE_STRING SubsystemName,
- IN PUNICODE_STRING ServiceName,
- IN HANDLE ClientToken,
- IN PPRIVILEGE_SET Privileges,
- IN BOOLEAN AccessGranted)
+
+BOOLEAN INIT_FUNCTION
+SeInit2(VOID)
{
- UNIMPLEMENTED;
+ SepInitializeTokenImplementation();
+
+ return TRUE;
}
-NTSTATUS
-STDCALL
-NtPrivilegeObjectAuditAlarm (
- IN PUNICODE_STRING SubsystemName,
- IN PVOID HandleId,
- IN HANDLE ClientToken,
- IN ULONG DesiredAccess,
- IN PPRIVILEGE_SET Privileges,
- IN BOOLEAN AccessGranted
- )
+BOOLEAN
+SeInitSRM(VOID)
{
- UNIMPLEMENTED;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING Name;
+ HANDLE DirectoryHandle;
+ HANDLE EventHandle;
+ NTSTATUS Status;
+
+ /* Create '\Security' directory */
+ RtlInitUnicodeString(&Name,
+ L"\\Security");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_PERMANENT,
+ 0,
+ NULL);
+ Status = NtCreateDirectoryObject(&DirectoryHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create 'Security' directory!\n");
+ return FALSE;
+ }
+
+ /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
+ RtlInitUnicodeString(&Name,
+ L"\\LSA_AUTHENTICATION_INITALIZED");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_PERMANENT,
+ DirectoryHandle,
+ SePublicDefaultSd);
+ Status = NtCreateEvent(&EventHandle,
+ EVENT_ALL_ACCESS,
+ &ObjectAttributes,
+ FALSE,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
+ NtClose(DirectoryHandle);
+ return FALSE;
+ }
+
+ NtClose(EventHandle);
+ NtClose(DirectoryHandle);
+
+ /* FIXME: Create SRM port and listener thread */
+
+ return TRUE;
}
-NTSTATUS
-STDCALL
-NtOpenObjectAuditAlarm (
- IN PUNICODE_STRING SubsystemName,
- IN PVOID HandleId,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN HANDLE ClientToken,
- IN ULONG DesiredAccess,
- IN ULONG GrantedAccess,
- IN PPRIVILEGE_SET Privileges,
- IN BOOLEAN ObjectCreation,
- IN BOOLEAN AccessGranted,
- OUT PBOOLEAN GenerateOnClose
- )
+static BOOLEAN INIT_FUNCTION
+SepInitExports(VOID)
{
- UNIMPLEMENTED;
+ SeExports = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(SE_EXPORTS),
+ TAG_SXPT);
+ if (SeExports == NULL)
+ return FALSE;
+
+ SeExports->SeCreateTokenPrivilege = SeCreateTokenPrivilege;
+ SeExports->SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
+ SeExports->SeLockMemoryPrivilege = SeLockMemoryPrivilege;
+ SeExports->SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
+ SeExports->SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
+ SeExports->SeTcbPrivilege = SeTcbPrivilege;
+ SeExports->SeSecurityPrivilege = SeSecurityPrivilege;
+ SeExports->SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
+ SeExports->SeLoadDriverPrivilege = SeLoadDriverPrivilege;
+ SeExports->SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
+ SeExports->SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
+ SeExports->SeSystemProfilePrivilege = SeSystemProfilePrivilege;
+ SeExports->SeSystemtimePrivilege = SeSystemtimePrivilege;
+ SeExports->SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
+ SeExports->SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
+ SeExports->SeBackupPrivilege = SeBackupPrivilege;
+ SeExports->SeRestorePrivilege = SeRestorePrivilege;
+ SeExports->SeShutdownPrivilege = SeShutdownPrivilege;
+ SeExports->SeDebugPrivilege = SeDebugPrivilege;
+ SeExports->SeAuditPrivilege = SeAuditPrivilege;
+ SeExports->SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
+ SeExports->SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
+ SeExports->SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
+
+ SeExports->SeNullSid = SeNullSid;
+ SeExports->SeWorldSid = SeWorldSid;
+ SeExports->SeLocalSid = SeLocalSid;
+ SeExports->SeCreatorOwnerSid = SeCreatorOwnerSid;
+ SeExports->SeCreatorGroupSid = SeCreatorGroupSid;
+ SeExports->SeNtAuthoritySid = SeNtAuthoritySid;
+ SeExports->SeDialupSid = SeDialupSid;
+ SeExports->SeNetworkSid = SeNetworkSid;
+ SeExports->SeBatchSid = SeBatchSid;
+ SeExports->SeInteractiveSid = SeInteractiveSid;
+ SeExports->SeLocalSystemSid = SeLocalSystemSid;
+ SeExports->SeAliasAdminsSid = SeAliasAdminsSid;
+ SeExports->SeAliasUsersSid = SeAliasUsersSid;
+ SeExports->SeAliasGuestsSid = SeAliasGuestsSid;
+ SeExports->SeAliasPowerUsersSid = SeAliasPowerUsersSid;
+ SeExports->SeAliasAccountOpsSid = SeAliasAccountOpsSid;
+ SeExports->SeAliasSystemOpsSid = SeAliasSystemOpsSid;
+ SeExports->SeAliasPrintOpsSid = SeAliasPrintOpsSid;
+ SeExports->SeAliasBackupOpsSid = SeAliasBackupOpsSid;
+
+ return TRUE;
}
-NTSTATUS
-STDCALL
-NtAccessCheckAndAuditAlarm (
- IN PUNICODE_STRING SubsystemName,
- IN PHANDLE ObjectHandle,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN ACCESS_MASK DesiredAccess,
- IN PGENERIC_MAPPING GenericMapping,
- IN BOOLEAN ObjectCreation,
- OUT PULONG GrantedAccess,
- OUT PBOOLEAN AccessStatus,
- OUT PBOOLEAN GenerateOnClose
- )
+
+VOID SepReferenceLogonSession(PLUID AuthenticationId)
{
UNIMPLEMENTED;
}
-
-NTSTATUS
-STDCALL
-NtAllocateUuids (
- PLARGE_INTEGER Time,
- PULONG Version, // ???
- PULONG ClockCycle
- )
+VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
{
UNIMPLEMENTED;
}
-NTSTATUS STDCALL NtCloseObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
- IN PVOID HandleId,
- IN BOOLEAN GenerateOnClose)
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+NtAllocateUuids(PULARGE_INTEGER Time,
+ PULONG Range,
+ PULONG Sequence)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
-NTSTATUS STDCALL NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN HANDLE ClientToken,
- IN ACCESS_MASK DesiredAccess,
- IN PGENERIC_MAPPING GenericMapping,
- OUT PPRIVILEGE_SET PrivilegeSet,
- OUT PULONG ReturnLength,
- OUT PULONG GrantedAccess,
- OUT PBOOLEAN AccessStatus)
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ PETHREAD Thread;
+ BOOLEAN CopyOnOpen;
+ BOOLEAN EffectiveOnly;
+
+ Thread = PsGetCurrentThread();
+ if (Thread == NULL)
+ {
+ SubjectContext->ProcessAuditId = 0;
+ SubjectContext->PrimaryToken = NULL;
+ SubjectContext->ClientToken = NULL;
+ SubjectContext->ImpersonationLevel = 0;
+ }
+ else
+ {
+ SubjectContext->ProcessAuditId = Thread->ThreadsProcess;
+ SubjectContext->ClientToken =
+ PsReferenceImpersonationToken(Thread,
+ &CopyOnOpen,
+ &EffectiveOnly,
+ &SubjectContext->ImpersonationLevel);
+ SubjectContext->PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
+ }
}
-NTSTATUS
-STDCALL
-NtDeleteObjectAuditAlarm (
- IN PUNICODE_STRING SubsystemName,
- IN PVOID HandleId,
- IN BOOLEAN GenerateOnClose
- )
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
}
-
-VOID STDCALL SeReleaseSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
+/*
+ * @implemented
+ */
+VOID STDCALL
+SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- ObDereferenceObject(SubjectContext->PrimaryToken);
- if (SubjectContext->ClientToken != NULL)
- {
- ObDereferenceObject(SubjectContext->ClientToken);
- }
+ if (SubjectContext->PrimaryToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->PrimaryToken);
+ }
+
+ if (SubjectContext->ClientToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->ClientToken);
+ }
}
-VOID STDCALL SeCaptureSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
+
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- PEPROCESS Process;
- ULONG a;
- ULONG b;
-
- Process = PsGetCurrentThread()->ThreadsProcess;
-
- SubjectContext->ProcessAuditId = Process;
- SubjectContext->ClientToken =
- PsReferenceImpersonationToken(PsGetCurrentThread(),
- &a,
- &b,
- &SubjectContext->ImpersonationLevel);
- SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
+ UNIMPLEMENTED;
}
-
-NTSTATUS STDCALL SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
+
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
{
- if ((*SecurityDescriptor) != NULL)
- {
- ExFreePool(*SecurityDescriptor);
- (*SecurityDescriptor) = NULL;
- }
- return(STATUS_SUCCESS);
+ if (*SecurityDescriptor != NULL)
+ {
+ ExFreePool(*SecurityDescriptor);
+ *SecurityDescriptor = NULL;
+ }
+
+ return STATUS_SUCCESS;
}
+
#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
-NTSTATUS STDCALL SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
- PSECURITY_DESCRIPTOR ExplicitDescriptor,
- PSECURITY_DESCRIPTOR* NewDescriptor,
- BOOLEAN IsDirectoryObject,
- PSECURITY_SUBJECT_CONTEXT SubjectContext,
- PGENERIC_MAPPING GenericMapping,
- POOL_TYPE PoolType)
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
+ PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
+ PSECURITY_DESCRIPTOR *NewDescriptor,
+ BOOLEAN IsDirectoryObject,
+ PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ PGENERIC_MAPPING GenericMapping,
+ POOL_TYPE PoolType)
{
+ PSECURITY_DESCRIPTOR Descriptor;
+ ULONG Length;
+ NTSTATUS Status;
+
+ if (ExplicitDescriptor != NULL)
+ {
+ Length = RtlLengthSecurityDescriptor(ExplicitDescriptor);
+ }
+ else
+ {
+ DPRINT("No explicit security descriptor\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Descriptor = ExAllocatePool(NonPagedPool,
+ Length);
+ if (Descriptor == NULL)
+ {
+ DPRINT1("ExAlloctePool() failed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Status = RtlMakeSelfRelativeSD(ExplicitDescriptor,
+ Descriptor,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlMakeSelfRelativeSD() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ *NewDescriptor = Descriptor;
+
+ return STATUS_SUCCESS;
+
#if 0
- PSECURITY_DESCRIPTOR Descriptor;
PSID Owner;
PSID PrimaryGroup;
PACL DefaultDacl;
PSID ProcessOwner;
PSID ProcessPrimaryGroup;
PACL Sacl;
-
+
if (ExplicitDescriptor == NULL)
{
RtlCreateSecurityDescriptor(&Descriptor, 1);
{
Descriptor = ExplicitDescriptor;
}
+
SeLockSubjectContext(SubjectContext);
+
SepGetDefaultsSubjectContext(SubjectContext,
&Owner,
&PrimaryGroup,
&DefaultDacl,
&ProcessOwner,
&ProcessPrimaryGroup);
+
if (Descriptor->Control & SE_SACL_PRESENT ||
Descriptor->Control & SE_SACL_DEFAULTED)
{
if (ParentDescriptor == NULL)
{
}
+
if (Descriptor->Control & SE_SACL_PRESENT ||
Descriptor->Sacl == NULL ||)
{
- Sacl = NULL;
+ Sacl = NULL;
}
else
{
Sacl = Descriptor->Sacl;
if (Descriptor->Control & SE_SELF_RELATIVE)
{
- Sacl = (PACL)(((PVOID)Sacl) + (PVOID)Descriptor);
+ Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)Descriptor);
}
}
+
SepInheritAcl(Sacl,
IsDirectoryObject,
Owner,
ProcessOwner,
GenericMapping);
}
-#else
- UNIMPLEMENTED;
#endif
}
-BOOLEAN SepSidInToken(PACCESS_TOKEN Token,
- PSID Sid)
+
+static BOOLEAN
+SepSidInToken(PACCESS_TOKEN Token,
+ PSID Sid)
{
- ULONG i;
-
- if (Token->UserAndGroupCount == 0)
- {
- return(FALSE);
- }
-
- for (i=0; i<Token->UserAndGroupCount; i++)
- {
- if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
- {
- if (i == 0 ||
- (!(Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)))
- {
- return(TRUE);
- }
- return(FALSE);
- }
- }
- return(FALSE);
+ ULONG i;
+
+ if (Token->UserAndGroupCount == 0)
+ {
+ return FALSE;
+ }
+
+ for (i=0; i<Token->UserAndGroupCount; i++)
+ {
+ if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
+ {
+ if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ }
+
+ return FALSE;
}
-BOOLEAN STDCALL SeAccessCheck (IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
- IN BOOLEAN SubjectContextLocked,
- IN ACCESS_MASK DesiredAccess,
- IN ACCESS_MASK PreviouslyGrantedAccess,
- OUT PPRIVILEGE_SET* Privileges,
- IN PGENERIC_MAPPING GenericMapping,
- IN KPROCESSOR_MODE AccessMode,
- OUT PACCESS_MODE GrantedAccess,
- OUT PNTSTATUS AccessStatus)
+
/*
* FUNCTION: Determines whether the requested access rights can be granted
* to an object protected by a security descriptor and an object owner
* GrantedAccess (OUT) = On return specifies the access granted
* AccessStatus (OUT) = Status indicating why access was denied
* RETURNS: If access was granted, returns TRUE
+ *
+ * @implemented
*/
+BOOLEAN STDCALL
+SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
+ IN BOOLEAN SubjectContextLocked,
+ IN ACCESS_MASK DesiredAccess,
+ IN ACCESS_MASK PreviouslyGrantedAccess,
+ OUT PPRIVILEGE_SET* Privileges,
+ IN PGENERIC_MAPPING GenericMapping,
+ IN KPROCESSOR_MODE AccessMode,
+ 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;
-
- /*
- * Ignore the SACL for now
- */
-
- /*
- * Check the DACL
- */
- Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
- &Present,
- &Dacl,
+ LUID_AND_ATTRIBUTES Privilege;
+ ACCESS_MASK CurrentAccess;
+ PACCESS_TOKEN Token;
+ ULONG i;
+ PACL Dacl;
+ BOOLEAN Present;
+ BOOLEAN Defaulted;
+ PACE CurrentAce;
+ PSID Sid;
+ NTSTATUS Status;
+
+ CurrentAccess = PreviouslyGrantedAccess;
+
+ Token = SubjectSecurityContext->ClientToken ?
+ SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
+
+ /* Get the DACL */
+ Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
+ &Present,
+ &Dacl,
+ &Defaulted);
+ if (!NT_SUCCESS(Status))
+ {
+ *AccessStatus = Status;
+ return FALSE;
+ }
+
+ /* RULE 1: Grant desired access if the object is unprotected */
+ if (Dacl == NULL)
+ {
+ *GrantedAccess = DesiredAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
+ }
+
+ CurrentAccess = PreviouslyGrantedAccess;
+
+ /* RULE 2: Check token for 'take ownership' privilege */
+ Privilege.Luid = SeTakeOwnershipPrivilege;
+ Privilege.Attributes = SE_PRIVILEGE_ENABLED;
+
+ 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,
+ &Sid,
&Defaulted);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- 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 = CurrentAccess |
- CurrentAce->Header.AccessMask;
- }
- }
- }
- if (!(CurrentAccess & DesiredAccess) &&
- !((~CurrentAccess) & DesiredAccess))
- {
- *AccessStatus = STATUS_ACCESS_DENIED;
- }
- else
- {
- *AccessStatus = STATUS_SUCCESS;
- }
- *GrantedAccess = CurrentAccess;
-
- return(STATUS_SUCCESS);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
+ *AccessStatus = Status;
+ return FALSE;
+ }
+
+ if (SepSidInToken(Token, Sid))
+ {
+ CurrentAccess |= (READ_CONTROL | WRITE_DAC);
+ if (DesiredAccess == CurrentAccess)
+ {
+ *GrantedAccess = CurrentAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
+ }
+ }
+
+ /* RULE 4: Grant rights according to the DACL */
+ 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(Token, Sid))
+ {
+ *GrantedAccess = 0;
+ *AccessStatus = STATUS_ACCESS_DENIED;
+ return TRUE;
+ }
+ }
+
+ if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+ {
+ if (SepSidInToken(Token, Sid))
+ {
+ CurrentAccess |= CurrentAce->AccessMask;
+ }
+ }
+ }
+
+ DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
+ CurrentAccess, DesiredAccess);
+
+ *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;
+}
+
/* EOF */