Implement security descriptor cache.

svn path=/trunk/; revision=10142
This commit is contained in:
Eric Kohl 2004-07-16 17:20:23 +00:00
parent 243d59c9e6
commit 9d87061713
6 changed files with 450 additions and 71 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.129 2004/07/02 21:02:54 royce Exp $
# $Id: Makefile,v 1.130 2004/07/16 17:20:23 ekohl Exp $
#
# ReactOS Operating System
#
@ -130,7 +130,7 @@ OBJECTS_KE = \
ke/catch.o \
ke/critical.o \
ke/dpc.o \
ke/device.o \
ke/device.o \
ke/error.o \
ke/event.o \
ke/kqueue.o \
@ -138,7 +138,7 @@ OBJECTS_KE = \
ke/main.o \
ke/mutex.o \
ke/process.o \
ke/profile.o \
ke/profile.o \
ke/queue.o \
ke/sem.o \
ke/spinlock.o \
@ -223,9 +223,9 @@ OBJECTS_IO = \
io/timer.o \
io/vpb.o \
io/wdm.o \
io/wmi.o \
io/xhaldisp.o \
io/xhaldrv.o \
io/wmi.o
io/xhaldrv.o
# Object Manager (Ob)
OBJECTS_OB = \
@ -234,6 +234,7 @@ OBJECTS_OB = \
ob/namespc.o \
ob/ntobj.o \
ob/object.o \
ob/sdcache.o \
ob/security.o \
ob/symlink.o
@ -265,12 +266,12 @@ OBJECTS_EX = \
ex/napi.o \
ex/power.o \
ex/resource.o \
ex/rundown.o \
ex/rundown.o \
ex/stree.o \
ex/synch.o \
ex/synch.o \
ex/sysinfo.o \
ex/time.o \
ex/util.o \
ex/time.o \
ex/util.o \
ex/win32k.o \
ex/work.o \
ex/zone.o
@ -359,9 +360,9 @@ OBJECTS_CC = \
# Kernel Debugger Support (Kd)
OBJECTS_KD = \
kd/dlog.o \
kd/gdbstub.o \
kd/gdbstub.o \
kd/kdebug.o \
kd/mda.o \
kd/mda.o \
kd/service.o
# Boot video (Inbv)

View file

@ -133,8 +133,21 @@ ObDuplicateObject(PEPROCESS SourceProcess,
BOOLEAN InheritHandle,
ULONG Options);
ULONG
ObpGetHandleCountbyHandleTable(PHANDLE_TABLE HandleTable);
ULONG
ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable);
/* Security descriptor cache functions */
NTSTATUS
ObpInitSdCache(VOID);
NTSTATUS
ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD,
OUT PSECURITY_DESCRIPTOR *DestinationSD);
NTSTATUS
ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
#endif /* __INCLUDE_INTERNAL_OBJMGR_H */

View file

@ -1,4 +1,4 @@
/* $Id: namespc.c,v 1.44 2003/11/17 02:12:51 hyperion Exp $
/* $Id: namespc.c,v 1.45 2004/07/16 17:19:15 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -349,6 +349,9 @@ ObInit(VOID)
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
/* Initialize the security descriptor cache */
ObpInitSdCache();
/* create 'directory' object type */
ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));

View file

@ -1,4 +1,4 @@
/* $Id: object.c,v 1.77 2004/03/12 00:46:35 dwelch Exp $
/* $Id: object.c,v 1.78 2004/07/16 17:19:15 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -36,14 +36,14 @@ typedef struct _RETENTION_CHECK_PARAMS
PVOID HEADER_TO_BODY(POBJECT_HEADER obj)
{
return(((char*)obj)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER));
return(((char*)obj)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER));
}
POBJECT_HEADER BODY_TO_HEADER(PVOID body)
{
PCOMMON_BODY_HEADER chdr = (PCOMMON_BODY_HEADER)body;
return(CONTAINING_RECORD((&(chdr->Type)),OBJECT_HEADER,Type));
PCOMMON_BODY_HEADER chdr = (PCOMMON_BODY_HEADER)body;
return(CONTAINING_RECORD((&(chdr->Type)),OBJECT_HEADER,Type));
}
@ -76,44 +76,44 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
PUNICODE_STRING RemainingPath,
POBJECT_TYPE ObjectType)
{
PVOID NextObject;
PVOID CurrentObject;
PVOID RootObject;
POBJECT_HEADER CurrentHeader;
NTSTATUS Status;
PWSTR current;
UNICODE_STRING PathString;
ULONG Attributes;
PUNICODE_STRING ObjectName;
PVOID NextObject;
PVOID CurrentObject;
PVOID RootObject;
POBJECT_HEADER CurrentHeader;
NTSTATUS Status;
PWSTR current;
UNICODE_STRING PathString;
ULONG Attributes;
PUNICODE_STRING ObjectName;
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
DPRINT("ObjectAttributes->ObjectName %wZ\n",
ObjectAttributes->ObjectName);
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
DPRINT("ObjectAttributes->ObjectName %wZ\n",
ObjectAttributes->ObjectName);
RtlInitUnicodeString (RemainingPath, NULL);
RtlInitUnicodeString (RemainingPath, NULL);
if (ObjectAttributes->RootDirectory == NULL)
{
ObReferenceObjectByPointer(NameSpaceRoot,
DIRECTORY_TRAVERSE,
NULL,
UserMode);
CurrentObject = NameSpaceRoot;
}
else
{
Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
DIRECTORY_TRAVERSE,
NULL,
UserMode,
&CurrentObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
if (ObjectAttributes->RootDirectory == NULL)
{
ObReferenceObjectByPointer(NameSpaceRoot,
DIRECTORY_TRAVERSE,
NULL,
UserMode);
CurrentObject = NameSpaceRoot;
}
else
{
Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
DIRECTORY_TRAVERSE,
NULL,
UserMode,
&CurrentObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
}
ObjectName = ObjectAttributes->ObjectName;
if (ObjectName->Length == 0 ||
@ -148,13 +148,13 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
current = PathString.Buffer;
RootObject = CurrentObject;
Attributes = ObjectAttributes->Attributes;
if (ObjectType == ObSymbolicLinkType)
Attributes |= OBJ_OPENLINK;
RootObject = CurrentObject;
Attributes = ObjectAttributes->Attributes;
if (ObjectType == ObSymbolicLinkType)
Attributes |= OBJ_OPENLINK;
while (TRUE)
{
while (TRUE)
{
DPRINT("current %S\n",current);
CurrentHeader = BODY_TO_HEADER(CurrentObject);
@ -189,14 +189,14 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
}
ObDereferenceObject(CurrentObject);
CurrentObject = NextObject;
}
if (current)
RtlCreateUnicodeString (RemainingPath, current);
RtlFreeUnicodeString (&PathString);
*ReturnedObject = CurrentObject;
return(STATUS_SUCCESS);
}
if (current)
RtlCreateUnicodeString (RemainingPath, current);
RtlFreeUnicodeString (&PathString);
*ReturnedObject = CurrentObject;
return STATUS_SUCCESS;
}
@ -451,6 +451,30 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
}
RtlFreeUnicodeString( &RemainingPath );
if (Header->ObjectType != NULL)
{
/* FIXME: Call SeAssignSecurity() to create a new security descriptor */
if (Header->ObjectType->Security != NULL)
{
/* FIXME: Call the security method */
Status = STATUS_SUCCESS;
}
else
{
/* Assign the security descriptor to the object header */
if (ObjectAttributes != NULL && ObjectAttributes->SecurityDescriptor != NULL)
{
Status = ObpAddSecurityDescriptor(ObjectAttributes->SecurityDescriptor,
&Header->SecurityDescriptor);
}
else
{
Status = STATUS_SUCCESS;
}
}
}
if (Object != NULL)
{
*Object = HEADER_TO_BODY(Header);
@ -574,6 +598,11 @@ ObpDeleteObject(POBJECT_HEADER Header)
KEBUGCHECK(0);
}
if (Header->SecurityDescriptor != NULL)
{
ObpRemoveSecurityDescriptor(Header->SecurityDescriptor);
}
if (Header->ObjectType != NULL &&
Header->ObjectType->Delete != NULL)
{

View file

@ -0,0 +1,312 @@
/* $Id: sdcache.c,v 1.1 2004/07/16 17:19:15 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/kill.c
* PURPOSE: Terminating a thread
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ob.h>
#define NDEBUG
#include <internal/debug.h>
/* TYPES ********************************************************************/
typedef struct _SD_CACHE_ENTRY
{
LIST_ENTRY ListEntry;
ULONG HashValue;
ULONG Index;
ULONG RefCount;
} SD_CACHE_ENTRY, *PSD_CACHE_ENTRY;
/* GLOBALS ******************************************************************/
PLIST_ENTRY ObpSdCache;
KSPIN_LOCK ObpSdCacheSpinLock;
KIRQL ObpSdCacheIrql;
#define SD_CACHE_ENTRIES 0x100
/* FUNCTIONS ****************************************************************/
NTSTATUS
ObpInitSdCache(VOID)
{
ULONG i;
ObpSdCache = ExAllocatePool(NonPagedPool,
SD_CACHE_ENTRIES * sizeof(LIST_ENTRY));
if (ObpSdCache == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
for (i = 0; i < SD_CACHE_ENTRIES; i++)
{
InitializeListHead(&ObpSdCache[i]);
}
KeInitializeSpinLock(&ObpSdCacheSpinLock);
return STATUS_SUCCESS;
}
static VOID
ObpSdCacheLock(VOID)
{
KeAcquireSpinLock(&ObpSdCacheSpinLock,
&ObpSdCacheIrql);
}
static VOID
ObpSdCacheUnlock(VOID)
{
KeReleaseSpinLock(&ObpSdCacheSpinLock,
ObpSdCacheIrql);
}
static ULONG
ObpHash(PVOID Buffer,
ULONG Length)
{
PUCHAR Ptr;
ULONG Value;
ULONG i;
Ptr = (PUCHAR)Buffer;
Value = 0;
for (i = 0; i < Length; i++)
{
Value += *Ptr;
Ptr++;
}
return Value;
}
static ULONG
ObpHashSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
ULONG Value;
BOOLEAN Defaulted;
BOOLEAN DaclPresent;
BOOLEAN SaclPresent;
PSID Owner = NULL;
PSID Group = NULL;
PACL Dacl = NULL;
PACL Sacl = NULL;
RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
&Owner,
&Defaulted);
RtlGetGroupSecurityDescriptor(SecurityDescriptor,
&Group,
&Defaulted);
RtlGetDaclSecurityDescriptor(SecurityDescriptor,
&DaclPresent,
&Dacl,
&Defaulted);
RtlGetSaclSecurityDescriptor(SecurityDescriptor,
&SaclPresent,
&Sacl,
&Defaulted);
Value = 0;
if (Owner != NULL)
{
Value += ObpHash(Owner, RtlLengthSid(Owner));
}
if (Group != NULL)
{
Value += ObpHash(Group, RtlLengthSid(Group));
}
if (DaclPresent == TRUE && Dacl != NULL)
{
Value += ObpHash(Dacl, Dacl->AclSize);
}
if (SaclPresent == TRUE && Sacl != NULL)
{
Value += ObpHash(Sacl, Sacl->AclSize);
}
return Value;
}
static PSD_CACHE_ENTRY
ObpCreateCacheEntry(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG HashValue,
IN ULONG Index,
OUT PSECURITY_DESCRIPTOR *NewSD)
{
PSECURITY_DESCRIPTOR Sd;
PSD_CACHE_ENTRY CacheEntry;
ULONG Length;
DPRINT("ObpCreateCacheEntry() called\n");
Length = RtlLengthSecurityDescriptor(SecurityDescriptor);
CacheEntry = ExAllocatePool(NonPagedPool,
sizeof(SD_CACHE_ENTRY) + Length);
if (CacheEntry == NULL)
{
DPRINT1("ExAllocatePool() failed\n");
return NULL;
}
CacheEntry->HashValue = HashValue;
CacheEntry->Index = Index;
CacheEntry->RefCount = 1;
Sd = (PSECURITY_DESCRIPTOR)(CacheEntry + 1);
RtlCopyMemory(Sd,
SecurityDescriptor,
Length);
*NewSD = Sd;
DPRINT("ObpCreateCacheEntry() done\n");
return CacheEntry;
}
static BOOLEAN
ObpCompareSecurityDescriptors(IN PSECURITY_DESCRIPTOR Sd1,
IN PSECURITY_DESCRIPTOR Sd2)
{
ULONG Length1;
ULONG Length2;
Length1 = RtlLengthSecurityDescriptor(Sd1);
Length2 = RtlLengthSecurityDescriptor(Sd2);
if (Length1 != Length2)
return FALSE;
if (RtlCompareMemory(Sd1, Sd2, Length1) != Length1)
return FALSE;
return TRUE;
}
NTSTATUS
ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD,
OUT PSECURITY_DESCRIPTOR *DestinationSD)
{
PSECURITY_DESCRIPTOR Sd;
PLIST_ENTRY CurrentEntry;
PSD_CACHE_ENTRY CacheEntry;
ULONG HashValue;
ULONG Index;
NTSTATUS Status;
DPRINT("ObpAddSecurityDescriptor() called\n");
HashValue = ObpHashSecurityDescriptor(SourceSD);
Index = HashValue & 0xFF;
ObpSdCacheLock();
if (!IsListEmpty(&ObpSdCache[Index]))
{
CurrentEntry = ObpSdCache[Index].Flink;
while (CurrentEntry != &ObpSdCache[Index])
{
CacheEntry = CONTAINING_RECORD(CurrentEntry,
SD_CACHE_ENTRY,
ListEntry);
Sd = (PSECURITY_DESCRIPTOR)(CacheEntry + 1);
if (CacheEntry->HashValue == HashValue &&
ObpCompareSecurityDescriptors(SourceSD, Sd))
{
CacheEntry->RefCount++;
DPRINT("RefCount %lu\n", CacheEntry->RefCount);
*DestinationSD = Sd;
ObpSdCacheUnlock();
DPRINT("ObpAddSecurityDescriptor() done\n");
return STATUS_SUCCESS;
}
CurrentEntry = CurrentEntry->Flink;
}
}
CacheEntry = ObpCreateCacheEntry(SourceSD,
HashValue,
Index,
DestinationSD);
if (CacheEntry == NULL)
{
DPRINT1("ObpCreateCacheEntry() failed\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DPRINT("RefCount 1\n");
InsertTailList(&ObpSdCache[Index], &CacheEntry->ListEntry);
Status = STATUS_SUCCESS;
}
ObpSdCacheUnlock();
DPRINT("ObpAddSecurityDescriptor() done\n");
return Status;
}
NTSTATUS
ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
PSD_CACHE_ENTRY CacheEntry;
DPRINT("ObpRemoveSecurityDescriptor() called\n");
ObpSdCacheLock();
CacheEntry = (PSD_CACHE_ENTRY)((ULONG_PTR)SecurityDescriptor - sizeof(SD_CACHE_ENTRY));
CacheEntry->RefCount--;
DPRINT("RefCount %lu\n", CacheEntry->RefCount);
if (CacheEntry->RefCount == 0)
{
DPRINT("Remove cache entry\n");
RemoveEntryList(&CacheEntry->ListEntry);
ExFreePool(CacheEntry);
}
ObpSdCacheUnlock();
DPRINT("ObpRemoveSecurityDescriptor() done\n");
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -56,7 +56,7 @@ ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
/*
* @unimplemented
* @implemented
*/
NTSTATUS STDCALL
NtQuerySecurityObject(IN HANDLE Handle,
@ -81,7 +81,7 @@ NtQuerySecurityObject(IN HANDLE Handle,
}
Header = BODY_TO_HEADER(Object);
if (Header->ObjectType != NULL &&
if (Header->ObjectType == NULL &&
Header->ObjectType->Security != NULL)
{
Status = Header->ObjectType->Security(Object,
@ -93,12 +93,33 @@ NtQuerySecurityObject(IN HANDLE Handle,
}
else
{
Status = STATUS_NOT_IMPLEMENTED;
if (Header->SecurityDescriptor != NULL)
{
/* FIXME: Use SecurityInformation */
*ResultLength = RtlLengthSecurityDescriptor(Header->SecurityDescriptor);
if (Length >= *ResultLength)
{
RtlCopyMemory(SecurityDescriptor,
Header->SecurityDescriptor,
*ResultLength);
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_BUFFER_TOO_SMALL;
}
}
else
{
*ResultLength = 0;
Status = STATUS_UNSUCCESSFUL;
}
}
ObDereferenceObject(Object);
return(Status);
return Status;
}