From 93db306b0e07df7932bd3201e21cb934f33ec23b Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 25 May 2006 04:17:29 +0000 Subject: [PATCH] - Fix ObReferenceObjectByName and ObOpenObjectByName not to blissfully ignore the AccessState and ParseContext parameters. - Change ObFindObject's prototype to be able to accomodate these two parameters so that they can be sent to the parse routine. svn path=/trunk/; revision=22037 --- reactos/ntoskrnl/cm/ntfunc.c | 8 +- reactos/ntoskrnl/cm/registry.c | 4 +- reactos/ntoskrnl/include/internal/ob.h | 4 +- reactos/ntoskrnl/ob/obhandle.c | 133 ++++++++++++++----------- reactos/ntoskrnl/ob/obname.c | 4 +- reactos/ntoskrnl/ob/obref.c | 75 ++++++++------ 6 files changed, 137 insertions(+), 91 deletions(-) diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 2f870829c4e..f675a945bd2 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -264,7 +264,9 @@ NtCreateKey(OUT PHANDLE KeyHandle, (PVOID*)&Object, &RemainingPath, CmiKeyType, - &Context); + &Context, + NULL, + NULL); if (!NT_SUCCESS(Status)) { PostCreateKeyInfo.Object = NULL; @@ -1333,7 +1335,9 @@ NtOpenKey(OUT PHANDLE KeyHandle, (PVOID*)&Object, &RemainingPath, CmiKeyType, - &Context); + &Context, + NULL, + NULL); if (!NT_SUCCESS(Status)) { DPRINT("CmpFindObject() returned 0x%08lx\n", Status); diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 59cdd5d646b..f6ab4fd097c 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -727,7 +727,9 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, (PVOID*)&ParentKey, &RemainingPath, CmiKeyType, - &Context); + &Context, + NULL, + NULL); ObpReleaseCapturedAttributes(&ObjectCreateInfo); if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); if (!NT_SUCCESS(Status)) diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 51fd332ef04..10028f3c2a8 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -118,7 +118,9 @@ ObFindObject( PVOID* ReturnedObject, PUNICODE_STRING RemainingPath, POBJECT_TYPE ObjectType, - POBP_LOOKUP_CONTEXT Context + POBP_LOOKUP_CONTEXT Context, + IN PACCESS_STATE AccessState, + IN PVOID ParseContext ); NTSTATUS diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index 5e0cf631bff..b8a71b2b6f3 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -752,7 +752,8 @@ ObGetObjectHandleCount(PVOID Object) return Header->HandleCount; } -NTSTATUS STDCALL +NTSTATUS +NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN OUT PVOID ParseContext, @@ -767,43 +768,54 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, OBJECT_CREATE_INFORMATION ObjectCreateInfo; NTSTATUS Status; OBP_LOOKUP_CONTEXT Context; - + AUX_DATA AuxData; + PGENERIC_MAPPING GenericMapping = NULL; + ACCESS_STATE AccessState; PAGED_CODE(); - DPRINT("ObOpenObjectByName(...)\n"); - /* Capture all the info */ - DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(ObjectAttributes, - AccessMode, - ObjectType, - &ObjectCreateInfo, - &ObjectName); - if (!NT_SUCCESS(Status)) + AccessMode, + ObjectType, + &ObjectCreateInfo, + &ObjectName); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if we didn't get an access state */ + if (!PassedAccessState) { - DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); - return Status; + /* Try to get the generic mapping if we can */ + if (ObjectType) GenericMapping = &ObjectType->TypeInfo.GenericMapping; + + /* Use our built-in access state */ + PassedAccessState = &AccessState; + Status = SeCreateAccessState(&AccessState, + &AuxData, + DesiredAccess, + GenericMapping); + if (!NT_SUCCESS(Status)) goto Quickie; } + /* Get the security descriptor */ + if (ObjectCreateInfo.SecurityDescriptor) + { + /* Save it in the access state */ + PassedAccessState->SecurityDescriptor = + ObjectCreateInfo.SecurityDescriptor; + } + + /* Now do the lookup */ Status = ObFindObject(&ObjectCreateInfo, - &ObjectName, - &Object, - &RemainingPath, - ObjectType, - &Context); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT("ObFindObject() failed (Status %lx)\n", Status); - goto Cleanup; - } + &ObjectName, + &Object, + &RemainingPath, + ObjectType, + &Context, // Temporary Hack + PassedAccessState, + ParseContext); + if (!NT_SUCCESS(Status)) goto Cleanup; - DPRINT("OBject: %p, Remaining Path: %wZ\n", Object, &RemainingPath); - if (Object == NULL) - { - Status = STATUS_UNSUCCESSFUL; - goto Cleanup; - } + /* ROS Hack */ if (RemainingPath.Buffer != NULL) { if (wcschr(RemainingPath.Buffer + 1, L'\\') == NULL) @@ -813,26 +825,37 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, goto Cleanup; } + /* Create the actual handle now */ Status = ObpCreateHandle(Object, - DesiredAccess, - ObjectCreateInfo.Attributes, - Handle); + DesiredAccess, + ObjectCreateInfo.Attributes, + Handle); Cleanup: - if (Object != NULL) - { - ObDereferenceObject(Object); - } - RtlFreeUnicodeString(&RemainingPath); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); + /* Dereference the object */ + if (Object) ObDereferenceObject(Object); + /* ROS Hacl: Free the remaining path */ + RtlFreeUnicodeString(&RemainingPath); + + /* Delete the access state */ + if (PassedAccessState == &AccessState) + { + SeDeleteAccessState(PassedAccessState); + } + + /* Release the object attributes and return status */ +Quickie: + ObpReleaseCapturedAttributes(&ObjectCreateInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); return Status; } /* * @implemented */ -NTSTATUS STDCALL +NTSTATUS +NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, @@ -842,28 +865,24 @@ ObOpenObjectByPointer(IN PVOID Object, OUT PHANDLE Handle) { NTSTATUS Status; - PAGED_CODE(); - DPRINT("ObOpenObjectByPointer()\n"); - + /* Reference the object */ Status = ObReferenceObjectByPointer(Object, - 0, - ObjectType, - AccessMode); - if (!NT_SUCCESS(Status)) - { - return Status; - } + 0, + ObjectType, + AccessMode); + if (!NT_SUCCESS(Status)) return Status; + /* Create the handle */ Status = ObpCreateHandle(Object, - DesiredAccess, - HandleAttributes, - Handle); + DesiredAccess, + HandleAttributes, + Handle); + /* ROS Hack: Dereference the object and return */ ObDereferenceObject(Object); - - return STATUS_SUCCESS; + return Status; } NTSTATUS STDCALL @@ -921,11 +940,9 @@ ObInsertObject(IN PVOID Object, PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL; SECURITY_SUBJECT_CONTEXT SubjectContext; OBP_LOOKUP_CONTEXT Context; - PAGED_CODE(); /* Get the Header and Create Info */ - DPRINT("ObInsertObject: %x\n", Object); Header = BODY_TO_HEADER(Object); ObjectCreateInfo = Header->ObjectCreateInfo; ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header); @@ -939,7 +956,9 @@ ObInsertObject(IN PVOID Object, &FoundObject, &RemainingPath, NULL, - &Context); + &Context, + NULL, + NULL); DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject, &RemainingPath); if (!NT_SUCCESS(Status)) { diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index 04af96aafd8..fcd44c44fe2 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -27,7 +27,9 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, PVOID* ReturnedObject, PUNICODE_STRING RemainingPath, POBJECT_TYPE ObjectType, - POBP_LOOKUP_CONTEXT Context) + POBP_LOOKUP_CONTEXT Context, + IN PACCESS_STATE AccessState, + IN PVOID ParseContext) { PVOID NextObject; PVOID CurrentObject; diff --git a/reactos/ntoskrnl/ob/obref.c b/reactos/ntoskrnl/ob/obref.c index 79c2b968fca..01ceb4e2dd2 100644 --- a/reactos/ntoskrnl/ob/obref.c +++ b/reactos/ntoskrnl/ob/obref.c @@ -188,7 +188,8 @@ ObReferenceObjectByPointer(IN PVOID Object, return(STATUS_SUCCESS); } -NTSTATUS STDCALL +NTSTATUS +NTAPI ObReferenceObjectByName(PUNICODE_STRING ObjectPath, ULONG Attributes, PACCESS_STATE PassedAccessState, @@ -204,50 +205,66 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, OBJECT_CREATE_INFORMATION ObjectCreateInfo; NTSTATUS Status; OBP_LOOKUP_CONTEXT Context; - - PAGED_CODE(); + AUX_DATA AuxData; + ACCESS_STATE AccessState; /* Capture the name */ - DPRINT("Capturing Name\n"); Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode); - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) return Status; + + /* Check if we didn't get an access state */ + if (!PassedAccessState) { - DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status); - return Status; + /* Use our built-in access state */ + PassedAccessState = &AccessState; + Status = SeCreateAccessState(&AccessState, + &AuxData, + DesiredAccess, + &ObjectType->TypeInfo.GenericMapping); + if (!NT_SUCCESS(Status)) goto Quickie; } - /* - * Create a fake ObjectCreateInfo structure. Note that my upcoming - * ObFindObject refactoring will remove the need for this hack. - */ + /* + * 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, - &ObjectName, - &Object, - &RemainingPath, - ObjectType, - &Context); - - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); - - if (!NT_SUCCESS(Status)) - { - return(Status); - } - DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object); + &ObjectName, + &Object, + &RemainingPath, + ObjectType, + &Context, + PassedAccessState, + ParseContext); + if (!NT_SUCCESS(Status)) goto Quickie; + /* ROS Hack */ if (RemainingPath.Buffer != NULL || Object == NULL) { - DPRINT("Object %p\n", Object); *ObjectPtr = NULL; RtlFreeUnicodeString (&RemainingPath); - return(STATUS_OBJECT_NAME_NOT_FOUND); + Status = STATUS_OBJECT_NAME_NOT_FOUND; + goto Quickie; } + + /* Return the object */ *ObjectPtr = Object; - RtlFreeUnicodeString (&RemainingPath); - return(STATUS_SUCCESS); + + /* ROS Hack: Free the remaining path */ + RtlFreeUnicodeString(&RemainingPath); + + /* Free the access state */ + if (PassedAccessState == &AccessState) + { + SeDeleteAccessState(PassedAccessState); + } + +Quickie: + /* Free the captured name if we had one, and return status */ + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + return Status; } NTSTATUS STDCALL