-/* $Id: semgr.c,v 1.34 2004/07/18 13:02:28 ekohl Exp $
+/* $Id$
*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * PURPOSE: Security manager
- * FILE: kernel/se/semgr.c
- * PROGRAMER: ?
- * REVISION HISTORY:
- * 26/07/98: Added stubs for security functions
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/se/semgr.c
+ * PURPOSE: Security manager
+ *
+ * PROGRAMMERS: No programmer listed.
*/
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <internal/ps.h>
-#include <internal/se.h>
-
+#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
-#define TAG_SXPT TAG('S', 'X', 'P', 'T')
-
-
/* GLOBALS ******************************************************************/
-PSE_EXPORTS EXPORTED SeExports = NULL;
+PSE_EXPORTS SeExports = NULL;
+SE_EXPORTS SepExports;
+
+static ERESOURCE SepSubjectContextLock;
/* PROTOTYPES ***************************************************************/
static BOOLEAN SepInitExports(VOID);
-/* FUNCTIONS ****************************************************************/
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, SeInit1)
+#pragma alloc_text(INIT, SeInit2)
+#pragma alloc_text(INIT, SepInitExports)
+#endif
+/* FUNCTIONS ****************************************************************/
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
+NTAPI
SeInit1(VOID)
{
SepInitLuid();
if (!SepInitExports())
return FALSE;
+ /* Initialize the subject context lock */
+ ExInitializeResource(&SepSubjectContextLock);
+
return TRUE;
}
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
+NTAPI
SeInit2(VOID)
{
SepInitializeTokenImplementation();
BOOLEAN
+NTAPI
SeInitSRM(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
OBJ_PERMANENT,
0,
NULL);
- Status = NtCreateDirectoryObject(&DirectoryHandle,
+ Status = ZwCreateDirectoryObject(&DirectoryHandle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
OBJ_PERMANENT,
DirectoryHandle,
SePublicDefaultSd);
- Status = NtCreateEvent(&EventHandle,
+ Status = ZwCreateEvent(&EventHandle,
EVENT_ALL_ACCESS,
&ObjectAttributes,
- FALSE,
+ SynchronizationEvent,
FALSE);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
- NtClose(EventHandle);
- NtClose(DirectoryHandle);
+ ZwClose(EventHandle);
+ ZwClose(DirectoryHandle);
/* FIXME: Create SRM port and listener thread */
static BOOLEAN INIT_FUNCTION
SepInitExports(VOID)
{
- 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;
-
+ SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege;
+ SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
+ SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege;
+ SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
+ SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
+ SepExports.SeTcbPrivilege = SeTcbPrivilege;
+ SepExports.SeSecurityPrivilege = SeSecurityPrivilege;
+ SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
+ SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege;
+ SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
+ SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
+ SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege;
+ SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege;
+ SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
+ SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
+ SepExports.SeBackupPrivilege = SeBackupPrivilege;
+ SepExports.SeRestorePrivilege = SeRestorePrivilege;
+ SepExports.SeShutdownPrivilege = SeShutdownPrivilege;
+ SepExports.SeDebugPrivilege = SeDebugPrivilege;
+ SepExports.SeAuditPrivilege = SeAuditPrivilege;
+ SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
+ SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
+ SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
+
+ SepExports.SeNullSid = SeNullSid;
+ SepExports.SeWorldSid = SeWorldSid;
+ SepExports.SeLocalSid = SeLocalSid;
+ SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
+ SepExports.SeCreatorGroupSid = SeCreatorGroupSid;
+ SepExports.SeNtAuthoritySid = SeNtAuthoritySid;
+ SepExports.SeDialupSid = SeDialupSid;
+ SepExports.SeNetworkSid = SeNetworkSid;
+ SepExports.SeBatchSid = SeBatchSid;
+ SepExports.SeInteractiveSid = SeInteractiveSid;
+ SepExports.SeLocalSystemSid = SeLocalSystemSid;
+ SepExports.SeAliasAdminsSid = SeAliasAdminsSid;
+ SepExports.SeAliasUsersSid = SeAliasUsersSid;
+ SepExports.SeAliasGuestsSid = SeAliasGuestsSid;
+ SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid;
+ SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid;
+ SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid;
+ SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid;
+ SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid;
+ SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
+ SepExports.SeRestrictedSid = SeRestrictedSid;
+ SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
+
+ SepExports.SeUndockPrivilege = SeUndockPrivilege;
+ SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
+ SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
+
+ SeExports = &SepExports;
return TRUE;
}
UNIMPLEMENTED;
}
+NTSTATUS
+STDCALL
+SeDefaultObjectMethod(PVOID Object,
+ SECURITY_OPERATION_CODE OperationType,
+ SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR _SecurityDescriptor,
+ PULONG ReturnLength,
+ PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+ POOL_TYPE PoolType,
+ PGENERIC_MAPPING GenericMapping)
+{
+ PISECURITY_DESCRIPTOR ObjectSd;
+ PISECURITY_DESCRIPTOR NewSd;
+ PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+ POBJECT_HEADER Header = BODY_TO_HEADER(Object);
+ PSID Owner = 0;
+ PSID Group = 0;
+ PACL Dacl = 0;
+ PACL Sacl = 0;
+ ULONG OwnerLength = 0;
+ ULONG GroupLength = 0;
+ ULONG DaclLength = 0;
+ ULONG SaclLength = 0;
+ ULONG Control = 0;
+ ULONG_PTR Current;
+ NTSTATUS Status;
+ if (OperationType == SetSecurityDescriptor)
+ {
+ ObjectSd = Header->SecurityDescriptor;
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-NtAllocateUuids(PULARGE_INTEGER Time,
- PULONG Range,
- PULONG Sequence)
-{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-}
+ /* Get owner and owner size */
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ {
+ if (SecurityDescriptor->Owner != NULL)
+ {
+ if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+ Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
+ (ULONG_PTR)SecurityDescriptor);
+ else
+ Owner = (PSID)SecurityDescriptor->Owner;
+ OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+ }
+ Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
+ }
+ else
+ {
+ if (ObjectSd->Owner != NULL)
+ {
+ Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
+ OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+ }
+ Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
+ }
+
+ /* Get group and group size */
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ {
+ if (SecurityDescriptor->Group != NULL)
+ {
+ if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+ Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
+ (ULONG_PTR)SecurityDescriptor);
+ else
+ Group = (PSID)SecurityDescriptor->Group;
+ GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+ }
+ Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
+ }
+ else
+ {
+ if (ObjectSd->Group != NULL)
+ {
+ Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
+ GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+ }
+ Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
+ }
+
+ /* Get DACL and DACL size */
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ {
+ if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
+ (SecurityDescriptor->Dacl != NULL))
+ {
+ if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+ Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
+ (ULONG_PTR)SecurityDescriptor);
+ else
+ Dacl = (PACL)SecurityDescriptor->Dacl;
+
+ DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
+ }
+ Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
+ }
+ else
+ {
+ if ((ObjectSd->Control & SE_DACL_PRESENT) &&
+ (ObjectSd->Dacl != NULL))
+ {
+ Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
+ DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
+ }
+ Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
+ }
+
+ /* Get SACL and SACL size */
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ {
+ if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
+ (SecurityDescriptor->Sacl != NULL))
+ {
+ if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+ Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
+ (ULONG_PTR)SecurityDescriptor);
+ else
+ Sacl = (PACL)SecurityDescriptor->Sacl;
+ SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
+ }
+ Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
+ }
+ else
+ {
+ if ((ObjectSd->Control & SE_SACL_PRESENT) &&
+ (ObjectSd->Sacl != NULL))
+ {
+ Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
+ SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
+ }
+ Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
+ }
+
+ NewSd = ExAllocatePool(NonPagedPool,
+ sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength +
+ DaclLength + SaclLength);
+ if (NewSd == NULL)
+ {
+ ObDereferenceObject(Object);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlCreateSecurityDescriptor(NewSd,
+ SECURITY_DESCRIPTOR_REVISION1);
+ /* We always build a self-relative descriptor */
+ NewSd->Control = Control | SE_SELF_RELATIVE;
+
+ Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR);
+
+ if (OwnerLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Owner,
+ OwnerLength);
+ NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
+ Current += OwnerLength;
+ }
+ if (GroupLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Group,
+ GroupLength);
+ NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
+ Current += GroupLength;
+ }
+
+ if (DaclLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Dacl,
+ DaclLength);
+ NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
+ Current += DaclLength;
+ }
+
+ if (SaclLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Sacl,
+ SaclLength);
+ NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
+ Current += SaclLength;
+ }
+
+ /* Add the new SD */
+ Status = ObpAddSecurityDescriptor(NewSd,
+ &Header->SecurityDescriptor);
+ if (NT_SUCCESS(Status))
+ {
+ /* Remove the old security descriptor */
+ ObpRemoveSecurityDescriptor(ObjectSd);
+ }
+ else
+ {
+ /* Restore the old security descriptor */
+ Header->SecurityDescriptor = ObjectSd;
+ }
+
+ ExFreePool(NewSd);
+ }
+ else if (OperationType == QuerySecurityDescriptor)
+ {
+ Status = SeQuerySecurityDescriptorInfo(&SecurityInformation,
+ SecurityDescriptor,
+ ReturnLength,
+ &Header->SecurityDescriptor);
+ }
+ else if (OperationType == AssignSecurityDescriptor)
+ {
+ /* Assign the security descriptor to the object header */
+ Status = ObpAddSecurityDescriptor(SecurityDescriptor,
+ &Header->SecurityDescriptor);
+ }
+
+
+ return STATUS_SUCCESS;
+}
/*
* @implemented
VOID STDCALL
SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- PEPROCESS Process;
+ PETHREAD Thread;
BOOLEAN CopyOnOpen;
BOOLEAN EffectiveOnly;
- Process = PsGetCurrentThread ()->ThreadsProcess;
+ PAGED_CODE();
- SubjectContext->ProcessAuditId = Process;
- SubjectContext->ClientToken =
- PsReferenceImpersonationToken (PsGetCurrentThread(),
- &CopyOnOpen,
- &EffectiveOnly,
- &SubjectContext->ImpersonationLevel);
- SubjectContext->PrimaryToken = PsReferencePrimaryToken (Process);
+ 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);
+ }
}
/*
- * @unimplemented
+ * @implemented
*/
VOID STDCALL
SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ PAGED_CODE();
+
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE);
}
* @implemented
*/
VOID STDCALL
-SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
+SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- ObDereferenceObject (SubjectContext->PrimaryToken);
- if (SubjectContext->ClientToken != NULL)
- {
- ObDereferenceObject (SubjectContext->ClientToken);
- }
+ PAGED_CODE();
+
+ ExReleaseResourceLite(&SepSubjectContextLock);
+ KeLeaveCriticalRegion();
}
/*
- * @unimplemented
+ * @implemented
*/
VOID STDCALL
-SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
+SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ PAGED_CODE();
+
+ if (SubjectContext->PrimaryToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->PrimaryToken);
+ }
+
+ if (SubjectContext->ClientToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->ClientToken);
+ }
}
* @implemented
*/
NTSTATUS STDCALL
-SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
+SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
{
- if ((*SecurityDescriptor) != NULL)
+ PAGED_CODE();
+
+ if (*SecurityDescriptor != NULL)
{
ExFreePool(*SecurityDescriptor);
- (*SecurityDescriptor) = NULL;
+ *SecurityDescriptor = NULL;
}
- return(STATUS_SUCCESS);
+
+ return STATUS_SUCCESS;
}
-#if 0
-VOID
-SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
- PSID* Owner,
- PSID* PrimaryGroup,
- PSID* ProcessOwner,
- PSID* ProcessPrimaryGroup,
- PACL* DefaultDacl)
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
+ IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
+ OUT PSECURITY_DESCRIPTOR *NewDescriptor,
+ IN GUID *ObjectType OPTIONAL,
+ IN BOOLEAN IsDirectoryObject,
+ IN ULONG AutoInheritFlags,
+ IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ IN PGENERIC_MAPPING GenericMapping,
+ IN POOL_TYPE PoolType)
{
- PACCESS_TOKEN Token;
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ * FUNCTION: Creates a security descriptor for a new object.
+ * ARGUMENTS:
+ * ParentDescriptor =
+ * ExplicitDescriptor =
+ * NewDescriptor =
+ * IsDirectoryObject =
+ * SubjectContext =
+ * GeneralMapping =
+ * PoolType =
+ * RETURNS: Status
+ *
+ * @implemented
+ */
+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)
+{
+ PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor;
+ PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor;
+ PISECURITY_DESCRIPTOR Descriptor;
+ PTOKEN Token;
+ ULONG OwnerLength = 0;
+ ULONG GroupLength = 0;
+ ULONG DaclLength = 0;
+ ULONG SaclLength = 0;
+ ULONG Length = 0;
+ ULONG Control = 0;
+ ULONG_PTR Current;
+ PSID Owner = NULL;
+ PSID Group = NULL;
+ PACL Dacl = NULL;
+ PACL Sacl = NULL;
+
+ PAGED_CODE();
+
+ /* Lock subject context */
+ SeLockSubjectContext(SubjectContext);
if (SubjectContext->ClientToken != NULL)
{
- Token = SubjectContext->ClientToken;
+ Token = SubjectContext->ClientToken;
}
else
{
- Token = SubjectContext->PrimaryToken;
+ 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
-SepInheritAcl(PACL Acl,
- BOOLEAN IsDirectoryObject,
- PSID Owner,
- PSID PrimaryGroup,
- PACL DefaultAcl,
- PSID ProcessOwner,
- PSID ProcessGroup,
- PGENERIC_MAPPING GenericMapping)
-{
- if (Acl == NULL)
+ /* Inherit the Owner SID */
+ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL)
{
- return(STATUS_UNSUCCESSFUL);
+ DPRINT("Use explicit owner sid!\n");
+ Owner = ExplicitDescriptor->Owner;
+
+ if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
+ {
+ Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
+
+ }
}
+ else
+ {
+ if (Token != NULL)
+ {
+ DPRINT("Use token owner sid!\n");
+ Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
+ }
+ else
+ {
+ DPRINT("Use default owner sid!\n");
+ Owner = SeLocalSystemSid;
+ }
+
+ Control |= SE_OWNER_DEFAULTED;
+ }
+
+ OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+
- if (Acl->AclRevision != 2 &&
- Acl->AclRevision != 3 )
+ /* Inherit the Group SID */
+ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL)
{
- return(STATUS_UNSUCCESSFUL);
+ DPRINT("Use explicit group sid!\n");
+ Group = ExplicitDescriptor->Group;
+ if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
+ {
+ Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor);
+ }
+ }
+ else
+ {
+ if (Token != NULL)
+ {
+ DPRINT("Use token group sid!\n");
+ Group = Token->PrimaryGroup;
+ }
+ else
+ {
+ DPRINT("Use default group sid!\n");
+ Group = SeLocalSystemSid;
+ }
+
+ Control |= SE_OWNER_DEFAULTED;
}
-}
-#endif
+ GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
-/*
- * @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;
+ /* Inherit the DACL */
+ if (ExplicitDescriptor != NULL &&
+ (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
+ !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
+ {
+ DPRINT("Use explicit DACL!\n");
+ Dacl = ExplicitDescriptor->Dacl;
+ if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
+ {
+ Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor);
+ }
- if (ExplicitDescriptor != NULL)
+ Control |= SE_DACL_PRESENT;
+ }
+ else if (ParentDescriptor != NULL &&
+ (ParentDescriptor->Control & SE_DACL_PRESENT))
+ {
+ DPRINT("Use parent DACL!\n");
+ /* FIXME: Inherit */
+ Dacl = ParentDescriptor->Dacl;
+ if (Dacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
+ {
+ Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor);
+ }
+ Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
+ }
+ else if (Token != NULL && Token->DefaultDacl != NULL)
{
- Length = RtlLengthSecurityDescriptor(ExplicitDescriptor);
+ DPRINT("Use token default DACL!\n");
+ /* FIXME: Inherit */
+ Dacl = Token->DefaultDacl;
+ Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
}
else
{
- DPRINT("No explicit security descriptor\n");
- return STATUS_UNSUCCESSFUL;
+ DPRINT("Use NULL DACL!\n");
+ Dacl = NULL;
+ Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
}
- Descriptor = ExAllocatePool(NonPagedPool,
+ DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0;
+
+
+ /* Inherit the SACL */
+ if (ExplicitDescriptor != NULL &&
+ (ExplicitDescriptor->Control & SE_SACL_PRESENT) &&
+ !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED))
+ {
+ DPRINT("Use explicit SACL!\n");
+ Sacl = ExplicitDescriptor->Sacl;
+ if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
+ {
+ Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor);
+ }
+
+ Control |= SE_SACL_PRESENT;
+ }
+ else if (ParentDescriptor != NULL &&
+ (ParentDescriptor->Control & SE_SACL_PRESENT))
+ {
+ DPRINT("Use parent SACL!\n");
+ /* FIXME: Inherit */
+ Sacl = ParentDescriptor->Sacl;
+ if (Sacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
+ {
+ Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor);
+ }
+ Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED);
+ }
+
+ SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0;
+
+
+ /* Allocate and initialize the new security descriptor */
+ Length = sizeof(SECURITY_DESCRIPTOR) +
+ OwnerLength + GroupLength + DaclLength + SaclLength;
+
+ DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
+ sizeof(SECURITY_DESCRIPTOR),
+ OwnerLength,
+ GroupLength,
+ DaclLength,
+ SaclLength);
+
+ Descriptor = ExAllocatePool(PagedPool,
Length);
if (Descriptor == NULL)
{
DPRINT1("ExAlloctePool() failed\n");
- return STATUS_UNSUCCESSFUL;
+ /* FIXME: Unlock subject context */
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- Status = RtlMakeSelfRelativeSD(ExplicitDescriptor,
- Descriptor,
- &Length);
- if (!NT_SUCCESS(Status))
+ RtlZeroMemory( Descriptor, Length );
+ RtlCreateSecurityDescriptor(Descriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+
+ Descriptor->Control = Control | SE_SELF_RELATIVE;
+
+ Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR);
+
+ if (SaclLength != 0)
{
- DPRINT1("RtlMakeSelfRelativeSD() failed (Status %lx)\n", Status);
- return Status;
+ RtlCopyMemory((PVOID)Current,
+ Sacl,
+ SaclLength);
+ Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ Current += SaclLength;
}
- *NewDescriptor = Descriptor;
+ if (DaclLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Dacl,
+ DaclLength);
+ Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ Current += DaclLength;
+ }
- return STATUS_SUCCESS;
+ if (OwnerLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Owner,
+ OwnerLength);
+ Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ Current += OwnerLength;
+ DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner);
+ }
+ else
+ DPRINT("Owner of %x is zero length\n", Descriptor);
-#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 (GroupLength != 0)
+ {
+ memmove((PVOID)Current,
+ Group,
+ GroupLength);
+ Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ }
- 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);
- }
- }
+ /* Unlock subject context */
+ SeUnlockSubjectContext(SubjectContext);
- SepInheritAcl(Sacl,
- IsDirectoryObject,
- Owner,
- PrimaryGroup,
- DefaultDacl,
- ProcessOwner,
- GenericMapping);
- }
-#endif
+ *NewDescriptor = Descriptor;
+
+ DPRINT("Descrptor %x\n", Descriptor);
+ ASSERT(RtlLengthSecurityDescriptor(Descriptor));
+
+ return STATUS_SUCCESS;
}
static BOOLEAN
-SepSidInToken(PACCESS_TOKEN Token,
+SepSidInToken(PACCESS_TOKEN _Token,
PSID Sid)
{
ULONG i;
+ PTOKEN Token = (PTOKEN)_Token;
+
+ PAGED_CODE();
if (Token->UserAndGroupCount == 0)
{
PSID Sid;
NTSTATUS Status;
+ PAGED_CODE();
+
CurrentAccess = PreviouslyGrantedAccess;
+ if (SubjectContextLocked == FALSE)
+ {
+ SeLockSubjectContext(SubjectSecurityContext);
+ }
+
Token = SubjectSecurityContext->ClientToken ?
SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
&Defaulted);
if (!NT_SUCCESS(Status))
{
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
*AccessStatus = Status;
return FALSE;
}
/* RULE 1: Grant desired access if the object is unprotected */
- if (Dacl == NULL)
+ if (Present == TRUE && Dacl == NULL)
{
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
*GrantedAccess = DesiredAccess;
*AccessStatus = STATUS_SUCCESS;
return TRUE;
CurrentAccess |= WRITE_OWNER;
if (DesiredAccess == CurrentAccess)
{
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
*GrantedAccess = CurrentAccess;
*AccessStatus = STATUS_SUCCESS;
return TRUE;
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
*AccessStatus = Status;
return FALSE;
}
CurrentAccess |= (READ_CONTROL | WRITE_DAC);
if (DesiredAccess == CurrentAccess)
{
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
*GrantedAccess = CurrentAccess;
*AccessStatus = STATUS_SUCCESS;
return TRUE;
}
}
+ /* Fail if DACL is absent */
+ if (Present == FALSE)
+ {
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ *GrantedAccess = 0;
+ *AccessStatus = STATUS_ACCESS_DENIED;
+ return TRUE;
+ }
+
/* RULE 4: Grant rights according to the DACL */
CurrentAce = (PACE)(Dacl + 1);
for (i = 0; i < Dacl->AceCount; i++)
{
if (SepSidInToken(Token, Sid))
{
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
*GrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED;
return TRUE;
}
}
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
CurrentAccess, DesiredAccess);
{
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
KPROCESSOR_MODE PreviousMode;
- PACCESS_TOKEN Token;
+ PTOKEN Token;
NTSTATUS Status;
+ PAGED_CODE();
+
DPRINT("NtAccessCheck() called\n");
PreviousMode = KeGetPreviousMode();
SubjectSecurityContext.ClientToken = Token;
SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
- /* FIXME: Lock subject context */
-
- if (!SeAccessCheck(SecurityDescriptor,
- &SubjectSecurityContext,
- TRUE,
- DesiredAccess,
- 0,
- &PrivilegeSet,
- GenericMapping,
- PreviousMode,
- GrantedAccess,
- AccessStatus))
+ /* Lock subject context */
+ SeLockSubjectContext(&SubjectSecurityContext);
+
+ if (SeAccessCheck(SecurityDescriptor,
+ &SubjectSecurityContext,
+ TRUE,
+ DesiredAccess,
+ 0,
+ &PrivilegeSet,
+ GenericMapping,
+ PreviousMode,
+ GrantedAccess,
+ AccessStatus))
{
Status = *AccessStatus;
}
else
{
- Status = STATUS_SUCCESS;
+ Status = STATUS_ACCESS_DENIED;
}
- /* FIXME: Unlock subject context */
+ /* Unlock subject context */
+ SeUnlockSubjectContext(&SubjectSecurityContext);
ObDereferenceObject(Token);