- Add SecurityQoS and PreviousMode parameters to ObFindObject, so that these can be sent to the parse routine. Also don't send OBJECT_CREATE_INFORMATION to it, but each needed member separately. This avoids having to create a "Fake" structure in some calls which don't actually use capture the information.

- Also remove RemainingPath and stop exposing it to public APIs. Move all ObInsertObject/ObOpen,ReferenceByName hacks to ObFindObject, and add a small one there. We basically trade 4 hacks for 1.

svn path=/trunk/; revision=22090
This commit is contained in:
Alex Ionescu 2006-05-28 19:05:19 +00:00
parent 19daffae13
commit 0dd1e9a2af
5 changed files with 196 additions and 146 deletions

View file

@ -84,14 +84,17 @@ ObCreateHandleTable(
NTSTATUS
NTAPI
ObFindObject(
POBJECT_CREATE_INFORMATION ObjectCreateInfo,
PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
POBJECT_TYPE ObjectType,
POBP_LOOKUP_CONTEXT Context,
IN HANDLE RootHandle,
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN KPROCESSOR_MODE PreviousMode,
IN PVOID *ReturnedObject,
IN POBJECT_TYPE ObjectType,
IN POBP_LOOKUP_CONTEXT Context,
IN PACCESS_STATE AccessState,
IN PVOID ParseContext
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
IN PVOID ParseContext,
IN PVOID Insert
);
NTSTATUS

View file

@ -754,7 +754,6 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
IN OUT PVOID ParseContext,
OUT PHANDLE Handle)
{
UNICODE_STRING RemainingPath;
PVOID Object = NULL;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
@ -797,26 +796,19 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
}
/* Now do the lookup */
Status = ObFindObject(&ObjectCreateInfo,
Status = ObFindObject(ObjectCreateInfo.RootDirectory,
&ObjectName,
ObjectCreateInfo.Attributes,
AccessMode,
&Object,
&RemainingPath,
ObjectType,
&Context, // Temporary Hack
&Context,
PassedAccessState,
ParseContext);
ObjectCreateInfo.SecurityQos,
ParseContext,
NULL);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* ROS Hack */
if (RemainingPath.Buffer != NULL)
{
if (wcschr(RemainingPath.Buffer + 1, L'\\') == NULL)
Status = STATUS_OBJECT_NAME_NOT_FOUND;
else
Status =STATUS_OBJECT_PATH_NOT_FOUND;
goto Cleanup;
}
/* Create the actual handle now */
Status = ObpCreateHandle(Object,
DesiredAccess,
@ -827,9 +819,6 @@ Cleanup:
/* Dereference the object */
if (Object) ObDereferenceObject(Object);
/* ROS Hacl: Free the remaining path */
RtlFreeUnicodeString(&RemainingPath);
/* Delete the access state */
if (PassedAccessState == &AccessState)
{
@ -923,15 +912,13 @@ ObInsertObject(IN PVOID Object,
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
POBJECT_HEADER Header;
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
PVOID FoundObject = NULL;
POBJECT_HEADER FoundHeader = NULL;
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING RemainingPath;
BOOLEAN ObjectAttached = FALSE;
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
SECURITY_SUBJECT_CONTEXT SubjectContext;
OBP_LOOKUP_CONTEXT Context;
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
PAGED_CODE();
/* Get the Header and Create Info */
@ -942,111 +929,69 @@ ObInsertObject(IN PVOID Object,
/* First try to find the Object */
if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
{
DPRINT("Object has a name. Trying to find it: %wZ.\n", &ObjectNameInfo->Name);
Status = ObFindObject(ObjectCreateInfo,
Status = ObFindObject(ObjectCreateInfo->RootDirectory,
&ObjectNameInfo->Name,
ObjectCreateInfo->Attributes,
KernelMode,
&FoundObject,
&RemainingPath,
NULL,
Header->Type,
&Context,
NULL,
NULL);
DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject, &RemainingPath);
if (!NT_SUCCESS(Status))
{
DPRINT1("ObFindObject() failed! (Status 0x%x)\n", Status);
return Status;
}
ObjectCreateInfo->SecurityQos,
NULL,
Object);
if (!NT_SUCCESS(Status)) return Status;
if (FoundObject)
{
DPRINT("Getting header: %x\n", FoundObject);
FoundHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
}
if (FoundHeader && RemainingPath.Buffer == NULL)
{
DPRINT("Object exists\n");
ObDereferenceObject(FoundObject);
return STATUS_OBJECT_NAME_COLLISION;
}
}
else
{
DPRINT("No name, empty remaining path\n");
RtlInitUnicodeString(&RemainingPath, NULL);
}
if (FoundHeader && FoundHeader->Type == ObDirectoryType &&
RemainingPath.Buffer)
{
/* The name was changed so let's update it */
/* FIXME: TEMPORARY HACK This will go in ObFindObject in the next commit */
PVOID NewName;
PWSTR BufferPos = RemainingPath.Buffer;
ULONG Delta = 0;
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
if (BufferPos[0] == L'\\')
/*
* OK, if we got here then that means we don't have a name,
* so RemainingPath.Buffer/RemainingPath would've been NULL
* under the old implemetantation, so just use NULL.
* If remaining path wouldn't have been NULL, then we would've
* called ObFindObject which already has this code.
* We basically kill 3-4 hacks and add 2 new ones.
*/
if ((Header->Type == IoFileObjectType) ||
(Header->Type->TypeInfo.OpenProcedure != NULL))
{
BufferPos++;
Delta = sizeof(WCHAR);
}
NewName = ExAllocatePool(NonPagedPool, RemainingPath.MaximumLength - Delta);
RtlMoveMemory(NewName, BufferPos, RemainingPath.MaximumLength - Delta);
if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer);
ObjectNameInfo->Name.Buffer = NewName;
ObjectNameInfo->Name.Length = RemainingPath.Length - Delta;
ObjectNameInfo->Name.MaximumLength = RemainingPath.MaximumLength - Delta;
ObpInsertEntryDirectory(FoundObject, &Context, Header);
ObjectAttached = TRUE;
}
if ((Header->Type == IoFileObjectType) ||
(Header->Type->TypeInfo.OpenProcedure != NULL))
{
DPRINT("About to call Open Routine\n");
if (Header->Type == IoFileObjectType)
{
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */
DPRINT("Calling IopCreateFile: %x\n", FoundObject);
Status = IopCreateFile(&Header->Body,
FoundObject,
RemainingPath.Buffer,
ObjectCreateInfo);
DPRINT("Called IopCreateFile: %x\n", Status);
}
else if (Header->Type->TypeInfo.OpenProcedure != NULL)
{
DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure);
Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle,
NULL,
&Header->Body,
0,
0);
}
if (!NT_SUCCESS(Status))
{
DPRINT("Create Failed\n");
if (ObjectAttached == TRUE)
DPRINT("About to call Open Routine\n");
if (Header->Type == IoFileObjectType)
{
ObpDeleteEntryDirectory(&Context);
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */
DPRINT("Calling IopCreateFile: %x\n", FoundObject);
Status = IopCreateFile(&Header->Body,
FoundObject,
NULL,
NULL);
DPRINT("Called IopCreateFile: %x\n", Status);
}
if (FoundObject)
else if (Header->Type->TypeInfo.OpenProcedure)
{
ObDereferenceObject(FoundObject);
DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure);
Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle,
NULL,
&Header->Body,
0,
0);
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Create Failed\n");
if (FoundObject) ObDereferenceObject(FoundObject);
return Status;
}
RtlFreeUnicodeString(&RemainingPath);
return Status;
}
}
RtlFreeUnicodeString(&RemainingPath);
DPRINT("Security Assignment in progress\n");
DPRINT("Security Assignment in progress\n");
SeCaptureSubjectContext(&SubjectContext);
/* Build the new security descriptor */

View file

@ -22,24 +22,28 @@ POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
NTSTATUS
NTAPI
ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
POBJECT_TYPE ObjectType,
POBP_LOOKUP_CONTEXT Context,
ObFindObject(IN HANDLE RootHandle,
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN KPROCESSOR_MODE PreviousMode,
IN PVOID *ReturnedObject,
IN POBJECT_TYPE ObjectType,
IN POBP_LOOKUP_CONTEXT Context,
IN PACCESS_STATE AccessState,
IN PVOID ParseContext)
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
IN PVOID ParseContext,
IN PVOID Insert)
{
PVOID NextObject;
PVOID CurrentObject;
PVOID RootObject;
POBJECT_HEADER CurrentHeader;
NTSTATUS Status;
NTSTATUS Status = STATUS_SUCCESS;
PWSTR current;
UNICODE_STRING PathString;
ULONG Attributes;
UNICODE_STRING CurrentUs;
UNICODE_STRING Path;
PUNICODE_STRING RemainingPath = &Path;
PAGED_CODE();
@ -48,20 +52,20 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
RtlInitUnicodeString (RemainingPath, NULL);
if (ObjectCreateInfo->RootDirectory == NULL)
if (RootHandle == NULL)
{
ObReferenceObjectByPointer(NameSpaceRoot,
DIRECTORY_TRAVERSE,
NULL,
ObjectCreateInfo->ProbeMode);
PreviousMode);
CurrentObject = NameSpaceRoot;
}
else
{
Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
Status = ObReferenceObjectByHandle(RootHandle,
0,
NULL,
ObjectCreateInfo->ProbeMode,
PreviousMode,
&CurrentObject,
NULL);
if (!NT_SUCCESS(Status))
@ -77,7 +81,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
return STATUS_SUCCESS;
}
if (ObjectCreateInfo->RootDirectory == NULL &&
if (RootHandle == NULL &&
ObjectName->Buffer[0] != L'\\')
{
ObDereferenceObject (CurrentObject);
@ -104,7 +108,6 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
current = PathString.Buffer;
RootObject = CurrentObject;
Attributes = ObjectCreateInfo->Attributes;
if (ObjectType == ObSymbolicLinkType)
Attributes |= OBJ_OPENLINK;
@ -194,7 +197,7 @@ Next:
ObReferenceObjectByPointer(NextObject,
DIRECTORY_TRAVERSE,
NULL,
ObjectCreateInfo->ProbeMode);
PreviousMode);
}
@ -214,7 +217,114 @@ Next:
RtlFreeUnicodeString (&PathString);
*ReturnedObject = CurrentObject;
return STATUS_SUCCESS;
/*
* Icky hack: put the code that was in ObInsertObject here so that
* we can get rid of the "RemainingPath" stuff, which shouldn't
* be exposed outside of here.
* Also makes the interface closer to NT parsing, and will make the
* eventual changes easier to deal with
*/
if (Insert)
{
PVOID FoundObject = NULL;
POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Insert);
POBJECT_HEADER FoundHeader = NULL;
BOOLEAN ObjectAttached = FALSE;
FoundObject = *ReturnedObject;
if (FoundObject)
{
FoundHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
}
if (FoundHeader && RemainingPath->Buffer == NULL)
{
DPRINT("Object exists\n");
ObDereferenceObject(FoundObject);
return STATUS_OBJECT_NAME_COLLISION;
}
if (FoundHeader && FoundHeader->Type == ObDirectoryType &&
RemainingPath->Buffer)
{
/* The name was changed so let's update it */
PVOID NewName;
PWSTR BufferPos = RemainingPath->Buffer;
ULONG Delta = 0;
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
if (BufferPos[0] == L'\\')
{
BufferPos++;
Delta = sizeof(WCHAR);
}
NewName = ExAllocatePool(NonPagedPool, RemainingPath->MaximumLength - Delta);
RtlMoveMemory(NewName, BufferPos, RemainingPath->MaximumLength - Delta);
if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer);
ObjectNameInfo->Name.Buffer = NewName;
ObjectNameInfo->Name.Length = RemainingPath->Length - Delta;
ObjectNameInfo->Name.MaximumLength = RemainingPath->MaximumLength - Delta;
ObpInsertEntryDirectory(FoundObject, Context, Header);
ObjectAttached = TRUE;
}
if ((Header->Type == IoFileObjectType) ||
(Header->Type->TypeInfo.OpenProcedure != NULL))
{
DPRINT("About to call Open Routine\n");
if (Header->Type == IoFileObjectType)
{
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */
DPRINT("Calling IopCreateFile: %x\n", FoundObject);
Status = IopCreateFile(&Header->Body,
FoundObject,
RemainingPath->Buffer,
NULL);
DPRINT("Called IopCreateFile: %x\n", Status);
}
else if (Header->Type->TypeInfo.OpenProcedure != NULL)
{
DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure);
Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle,
NULL,
&Header->Body,
0,
0);
}
if (!NT_SUCCESS(Status))
{
DPRINT("Create Failed\n");
if (ObjectAttached == TRUE)
{
ObpDeleteEntryDirectory(Context);
}
if (FoundObject)
{
ObDereferenceObject(FoundObject);
}
RtlFreeUnicodeString(RemainingPath);
return Status;
}
}
RtlFreeUnicodeString(RemainingPath);
}
else
{
/* ROS Hack */
DPRINT("REmaining path: %wZ\n", RemainingPath);
if (RemainingPath->Buffer != NULL)
{
if (wcschr(RemainingPath->Buffer + 1, L'\\') == NULL)
Status = STATUS_OBJECT_NAME_NOT_FOUND;
else
Status =STATUS_OBJECT_PATH_NOT_FOUND;
}
}
return Status;
}
/* PUBLIC FUNCTIONS *********************************************************/

View file

@ -200,9 +200,7 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
PVOID* ObjectPtr)
{
PVOID Object = NULL;
UNICODE_STRING RemainingPath;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
OBP_LOOKUP_CONTEXT Context;
AUX_DATA AuxData;
@ -224,27 +222,24 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
if (!NT_SUCCESS(Status)) goto Quickie;
}
/*
* Create a fake ObjectCreateInfo structure. Note that my upcoming
* ObFindObject refactoring will remove the need for this hack.
*/
ObjectCreateInfo.RootDirectory = NULL;
ObjectCreateInfo.Attributes = Attributes;
Status = ObFindObject(&ObjectCreateInfo,
/* Find the object */
Status = ObFindObject(NULL,
&ObjectName,
Attributes,
AccessMode,
&Object,
&RemainingPath,
ObjectType,
&Context,
PassedAccessState,
ParseContext);
NULL,
ParseContext,
NULL);
if (!NT_SUCCESS(Status)) goto Quickie;
/* ROS Hack */
if (RemainingPath.Buffer != NULL || Object == NULL)
if (Object == NULL)
{
*ObjectPtr = NULL;
RtlFreeUnicodeString (&RemainingPath);
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
@ -252,9 +247,6 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
/* Return the object */
*ObjectPtr = Object;
/* ROS Hack: Free the remaining path */
RtlFreeUnicodeString(&RemainingPath);
/* Free the access state */
if (PassedAccessState == &AccessState)
{

View file

@ -150,7 +150,7 @@ IntDesktopObjectParse(IN PVOID ParseObject,
Status = ObCreateObject(KernelMode,
ExDesktopObjectType,
&ObjectAttributes,
UserMode,
KernelMode,
NULL,
sizeof(DESKTOP_OBJECT),
0,