-/*
+/* $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
* PURPOSE: Security manager
/* 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')
-NTSTATUS STDCALL ZwQueryInformationToken(IN HANDLE TokenHandle,
- IN TOKEN_INFORMATION_CLASS TokenInformationClass,
- OUT PVOID TokenInformation,
- IN ULONG TokenInformationLength,
- OUT PULONG ReturnLength)
-{
- UNIMPLEMENTED;
-}
-NTSTATUS STDCALL NtQueryInformationToken(IN HANDLE TokenHandle,
- IN TOKEN_INFORMATION_CLASS TokenInformationClass,
- OUT PVOID TokenInformation,
- IN ULONG TokenInformationLength,
- OUT PULONG ReturnLength)
-{
- return(ZwQueryInformationToken(TokenHandle,
- TokenInformationClass,
- TokenInformation,
- TokenInformationLength,
- ReturnLength));
-}
+/* GLOBALS ******************************************************************/
-NTSTATUS STDCALL ZwQuerySecurityObject(IN HANDLE Object,
- IN CINT SecurityObjectInformationClass,
- OUT PVOID SecurityObjectInformation,
- IN ULONG Length,
- OUT PULONG ReturnLength)
-{
- UNIMPLEMENTED;
-}
+PSE_EXPORTS EXPORTED SeExports = NULL;
-NTSTATUS STDCALL NtQuerySecurityObject(IN HANDLE Object,
- IN CINT SecurityObjectInformationClass,
- OUT PVOID SecurityObjectInformation,
- IN ULONG Length,
- OUT PULONG ReturnLength)
-{
- return(ZwQuerySecurityObject(Object,
- SecurityObjectInformationClass,
- SecurityObjectInformation,
- Length,
- ReturnLength));
-}
-NTSTATUS
-STDCALL
-NtSetSecurityObject(
- IN HANDLE Handle,
- IN SECURITY_INFORMATION SecurityInformation,
- IN PSECURITY_DESCRIPTOR SecurityDescriptor
- )
-{
-}
+/* PROTOTYPES ***************************************************************/
-NTSTATUS
-STDCALL
-NtSetInformationToken(
- IN HANDLE TokenHandle,
- IN TOKEN_INFORMATION_CLASS TokenInformationClass,
- OUT PVOID TokenInformation,
- IN ULONG TokenInformationLength
- )
-{
-}
+static BOOLEAN SepInitExports(VOID);
-NTSTATUS
-STDCALL
-NtPrivilegeCheck(
- IN HANDLE ClientToken,
- IN PPRIVILEGE_SET RequiredPrivileges,
- IN PBOOLEAN Result
- )
-{
-}
+/* FUNCTIONS ****************************************************************/
-NTSTATUS
-STDCALL
-NtPrivilegedServiceAuditAlarm(
- IN PUNICODE_STRING SubsystemName,
- IN PUNICODE_STRING ServiceName,
- IN HANDLE ClientToken,
- IN PPRIVILEGE_SET Privileges,
- IN BOOLEAN AccessGranted
- )
-{
-}
-NTSTATUS
-STDCALL
-NtPrivilegeObjectAuditAlarm(
- IN PUNICODE_STRING SubsystemName,
- IN PVOID HandleId,
- IN HANDLE ClientToken,
- IN ULONG DesiredAccess,
- IN PPRIVILEGE_SET Privileges,
- IN BOOLEAN AccessGranted
- )
+BOOLEAN INIT_FUNCTION
+SeInit1(VOID)
{
-}
+ SepInitLuid();
-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
- )
-{
-}
+ if (!SepInitSecurityIDs())
+ return FALSE;
-NTSTATUS
-STDCALL
-NtOpenProcessToken(
- IN HANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE TokenHandle
- )
-{
-}
+ if (!SepInitDACLs())
+ return FALSE;
-NTSTATUS
-STDCALL
-NtOpenThreadToken(
- IN HANDLE ThreadHandle,
- IN ACCESS_MASK DesiredAccess,
- IN BOOLEAN OpenAsSelf,
- OUT PHANDLE TokenHandle
- )
-{
-}
+ if (!SepInitSDs())
+ return FALSE;
-NTSTATUS
-STDCALL
-NtDuplicateToken(
- IN HANDLE ExistingToken,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
- IN TOKEN_TYPE TokenType,
- OUT PHANDLE NewToken
- )
-{
-}
+ SepInitPrivileges();
+ if (!SepInitExports())
+ return FALSE;
-NTSTATUS STDCALL NtImpersonateClientOfPort(VOID)
-{
+ return TRUE;
}
-NTSTATUS
-STDCALL
-NtImpersonateThread(
- IN HANDLE ThreadHandle,
- IN HANDLE ThreadToImpersonate,
- IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService
- )
-{
-}
-NTSTATUS STDCALL NtCreateToken(VOID)
+BOOLEAN INIT_FUNCTION
+SeInit2(VOID)
{
-}
+ SepInitializeTokenImplementation();
-NTSTATUS
-STDCALL
-NtDeleteObjectAuditAlarm (
- IN PUNICODE_STRING SubsystemName,
- IN PVOID HandleId,
- IN BOOLEAN GenerateOnClose
- )
-{
+ return TRUE;
}
-NTSTATUS
-STDCALL
-NtAllocateLocallyUniqueId(
- OUT LUID *LocallyUniqueId
- )
+BOOLEAN
+SeInitSRM(VOID)
{
-}
+ 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;
+ }
-NTSTATUS
-STDCALL
-ZwAllocateLocallyUniqueId(
- OUT LUID *LocallyUniqueId
- )
-{
-}
+ /* 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;
+ }
-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
- )
-{
-}
+ NtClose(EventHandle);
+ NtClose(DirectoryHandle);
-NTSTATUS
-STDCALL
-NtAdjustGroupsToken(
- IN HANDLE TokenHandle,
- IN BOOLEAN ResetToDefault,
- IN PTOKEN_GROUPS NewState,
- IN ULONG BufferLength,
- OUT PTOKEN_GROUPS PreviousState OPTIONAL,
- OUT PULONG ReturnLength
- )
-{
+ /* FIXME: Create SRM port and listener thread */
+
+ return TRUE;
}
-NTSTATUS
-STDCALL
-NtAdjustPrivilegesToken(
- IN HANDLE TokenHandle,
- IN BOOLEAN DisableAllPrivileges,
- IN PTOKEN_PRIVILEGES NewState,
- IN ULONG BufferLength,
- OUT PTOKEN_PRIVILEGES PreviousState,
- OUT PULONG ReturnLength
- )
+
+static BOOLEAN INIT_FUNCTION
+SepInitExports(VOID)
{
-}
-NTSTATUS
-STDCALL
-ZwAdjustPrivilegesToken(
- IN HANDLE TokenHandle,
- IN BOOLEAN DisableAllPrivileges,
- IN PTOKEN_PRIVILEGES NewState,
- IN ULONG BufferLength,
- OUT PTOKEN_PRIVILEGES PreviousState,
- OUT PULONG ReturnLength
- )
+ 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;
+}
+
+
+VOID SepReferenceLogonSession(PLUID AuthenticationId)
{
+ UNIMPLEMENTED;
}
-NTSTATUS
-STDCALL
-NtAllocateUuids(
- PLARGE_INTEGER Time,
- PULONG Version, // ???
- PULONG ClockCycle
- )
+VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
{
+ UNIMPLEMENTED;
}
-NTSTATUS
-STDCALL
-ZwAllocateUuids(
- PLARGE_INTEGER Time,
- PULONG Version, // ???
- PULONG ClockCycle
- )
-{
-}
-NTSTATUS
-STDCALL
-NtCloseObjectAuditAlarm(
- IN PUNICODE_STRING SubsystemName,
- IN PVOID HandleId,
- IN BOOLEAN GenerateOnClose
- )
-{
-}
-NTSTATUS
-STDCALL
-NtAccessCheck(
- IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN HANDLE ClientToken,
- IN ACCESS_MASK DesiredAcces,
- IN PGENERIC_MAPPING GenericMapping,
- OUT PRIVILEGE_SET PrivilegeSet,
- OUT PULONG ReturnLength,
- OUT PULONG GrantedAccess,
- OUT PBOOLEAN AccessStatus
- )
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+NtAllocateUuids(PULARGE_INTEGER Time,
+ PULONG Range,
+ PULONG Sequence)
{
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
-NTSTATUS
-STDCALL
-ZwAccessCheck(
- IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN HANDLE ClientToken,
- IN ACCESS_MASK DesiredAcces,
- IN PGENERIC_MAPPING GenericMapping,
- OUT PRIVILEGE_SET PrivilegeSet,
- OUT PULONG ReturnLength,
- OUT PULONG GrantedAccess,
- OUT PBOOLEAN AccessStatus
- )
-{
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
+{
+ 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 RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- ULONG Revision)
+
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
}
-ULONG RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ if (SubjectContext->PrimaryToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->PrimaryToken);
+ }
+
+ if (SubjectContext->ClientToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->ClientToken);
+ }
}
-NTSTATUS RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- BOOLEAN DaclPresent,
- PACL Dacl,
- BOOLEAN DaclDefaulted)
+
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
}
-BOOLEAN RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
{
- UNIMPLEMENTED;
+ if (*SecurityDescriptor != NULL)
+ {
+ ExFreePool(*SecurityDescriptor);
+ *SecurityDescriptor = NULL;
+ }
+
+ return STATUS_SUCCESS;
}
-BOOLEAN SeSinglePrivilegeCheck(LUID PrivilegeValue,
- KPROCESSOR_MODE PreviousMode)
+
+#if 0
+VOID
+SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ PSID* Owner,
+ PSID* PrimaryGroup,
+ PSID* ProcessOwner,
+ PSID* ProcessPrimaryGroup,
+ PACL* DefaultDacl)
{
- UNIMPLEMENTED;
+ PACCESS_TOKEN Token;
+
+ if (SubjectContext->ClientToken != NULL)
+ {
+ Token = SubjectContext->ClientToken;
+ }
+ 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;
}
-NTSTATUS SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
+
+NTSTATUS
+SepInheritAcl(PACL Acl,
+ BOOLEAN IsDirectoryObject,
+ PSID Owner,
+ PSID PrimaryGroup,
+ PACL DefaultAcl,
+ PSID ProcessOwner,
+ PSID ProcessGroup,
+ PGENERIC_MAPPING GenericMapping)
{
- UNIMPLEMENTED;
+ if (Acl == NULL)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (Acl->AclRevision != 2 &&
+ Acl->AclRevision != 3 )
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
}
+#endif
-NTSTATUS SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
- PSECURITY_DESCRIPTOR ExplicitDescriptor,
- BOOLEAN IsDirectoryObject,
- PSECURITY_SUBJECT_CONTEXT SubjectContext,
- PGENERIC_MAPPING GenericMapping,
- POOL_TYPE PoolType)
-{
- UNIMPLEMENTED;
+
+/*
+ * @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
+ PSID Owner;
+ PSID PrimaryGroup;
+ PACL DefaultDacl;
+ PSID ProcessOwner;
+ PSID ProcessPrimaryGroup;
+ PACL Sacl;
+
+ if (ExplicitDescriptor == NULL)
+ {
+ RtlCreateSecurityDescriptor(&Descriptor, 1);
+ }
+ else
+ {
+ 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;
+ }
+ else
+ {
+ Sacl = Descriptor->Sacl;
+ if (Descriptor->Control & SE_SELF_RELATIVE)
+ {
+ Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)Descriptor);
+ }
+ }
+
+ SepInheritAcl(Sacl,
+ IsDirectoryObject,
+ Owner,
+ PrimaryGroup,
+ DefaultDacl,
+ ProcessOwner,
+ GenericMapping);
+ }
+#endif
+}
+
+
+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 (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ }
+
+ return FALSE;
}
-BOOLEAN SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN PSECURITY_DESCRIPTOR_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
* ARGUMENTS:
- * SecurityDescriptor = Security descriptor protected the object
+ * SecurityDescriptor = Security descriptor protecting the object
* SubjectSecurityContext = Subject's captured security context
* SubjectContextLocked = Indicates the user's subject context is locked
* DesiredAccess = Access rights the caller is trying to acquire
* PreviouslyGrantedAccess = Specified the access rights already granted
- * Priveleges = ?
+ * Privileges = ?
* GenericMapping = Generic mapping associated with the object
* AccessMode = Access mode used for the check
* GrantedAccess (OUT) = On return specifies the access granted
* AccessStatus (OUT) = Status indicating why access was denied
* RETURNS: If access was granted, returns TRUE
+ *
+ * @implemented
*/
-{
- UNIMPLEMENTED;
-}
-
-
+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)
+{
+ 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))
+ {
+ 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 */