-# $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
#
ke/catch.o \
ke/critical.o \
ke/dpc.o \
- ke/device.o \
+ ke/device.o \
ke/error.o \
ke/event.o \
ke/kqueue.o \
ke/main.o \
ke/mutex.o \
ke/process.o \
- ke/profile.o \
+ ke/profile.o \
ke/queue.o \
ke/sem.o \
ke/spinlock.o \
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 = \
ob/namespc.o \
ob/ntobj.o \
ob/object.o \
+ ob/sdcache.o \
ob/security.o \
ob/symlink.o
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
# 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)
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 */
-/* $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
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
+ /* Initialize the security descriptor cache */
+ ObpInitSdCache();
+
/* create 'directory' object type */
ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-/* $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
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));
}
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 ||
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);
}
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;
}
}
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);
KEBUGCHECK(0);
}
+ if (Header->SecurityDescriptor != NULL)
+ {
+ ObpRemoveSecurityDescriptor(Header->SecurityDescriptor);
+ }
+
if (Header->ObjectType != NULL &&
Header->ObjectType->Delete != NULL)
{
--- /dev/null
+/* $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 */
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS STDCALL
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,
}
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;
}