* Implemented/fixed NtSetSecurityObject() and NtQuerySecurityObject().

* Updated object security method.
* Added security method for key objects.
* NtDeleteKey() deletes existing values but no subkeys.
* Calculate hive header checksum and increment hive update counters.

svn path=/trunk/; revision=4150
This commit is contained in:
Eric Kohl 2003-02-15 18:46:28 +00:00
parent e028c60886
commit d9dc30e0aa
10 changed files with 228 additions and 94 deletions

View file

@ -1,4 +1,4 @@
/* $Id: ntddk.h,v 1.33 2002/11/15 22:30:30 chorns Exp $
/* $Id: ntddk.h,v 1.34 2003/02/15 18:43:20 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -37,6 +37,7 @@ extern "C"
#include <ntos/disk.h>
#include <ntos/registry.h>
#include <ntos/port.h>
#include <ntos/synch.h>
#include <napi/types.h>
#include <pe.h>
@ -48,8 +49,8 @@ extern "C"
#include <ddk/cmtypes.h>
#include <ddk/ketypes.h>
#include <ntos/security.h>
#include <ddk/obtypes.h>
#include <ddk/setypes.h>
#include <ddk/obtypes.h>
#include <ddk/mmtypes.h>
#include <ddk/potypes.h>
#include <ddk/pnptypes.h>

View file

@ -1,6 +1,6 @@
#ifndef _INCLUDE_DDK_OBTYPES_H
#define _INCLUDE_DDK_OBTYPES_H
/* $Id: obtypes.h,v 1.19 2002/11/24 18:26:40 robd Exp $ */
/* $Id: obtypes.h,v 1.20 2003/02/15 18:43:20 ekohl Exp $ */
struct _DIRECTORY_OBJECT;
struct _OBJECT_ATTRIBUTES;
@ -94,13 +94,18 @@ typedef struct _OBJECT_TYPE
PUNICODE_STRING FullPath,
PWSTR *Path,
ULONG Attributes);
/*
*/
NTSTATUS STDCALL_FUNC (*Security)(PVOID Object,
ULONG InfoClass,
PVOID Info,
PULONG InfoLength);
/*
* PURPOSE: Called to set, query, delete or assign a security-descriptor
* to the object
* RETURNS
* STATUS_SUCCESS NextObject was found
*/
NTSTATUS STDCALL_FUNC (*Security)(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength);
/*
*/

View file

@ -1,4 +1,4 @@
/* $Id: setypes.h,v 1.10 2002/11/24 18:26:40 robd Exp $
/* $Id: setypes.h,v 1.11 2003/02/15 18:43:20 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory for details
* PROJECT: ReactOS kernel
@ -159,6 +159,15 @@ typedef struct _SE_EXPORTS
typedef NTSTATUS STDCALL_FUNC
(*PSE_LOGON_SESSION_TERMINATED_ROUTINE)(IN PLUID LogonId);
typedef enum _SECURITY_OPERATION_CODE
{
SetSecurityDescriptor,
QuerySecurityDescriptor,
DeleteSecurityDescriptor,
AssignSecurityDescriptor
} SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE;
#endif
/* EOF */

View file

@ -1,5 +1,5 @@
/* $Id: zw.h,v 1.5 2003/01/05 19:23:20 robd Exp $
/* $Id: zw.h,v 1.6 2003/02/15 18:44:15 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -3466,21 +3466,15 @@ ZwSetLowWaitHighEventPair(
HANDLE EventPair
);
NTSTATUS
STDCALL
NtSetSecurityObject(
IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
NTSTATUS STDCALL
NtSetSecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor);
NTSTATUS
STDCALL
ZwSetSecurityObject(
IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
NTSTATUS STDCALL
ZwSetSecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor);
/*
@ -4963,25 +4957,19 @@ ZwQueryObject(
OUT PULONG ResultLength
);
NTSTATUS
STDCALL
NtQuerySecurityObject(
IN HANDLE Object,
IN CINT SecurityObjectInformationClass,
OUT PVOID SecurityObjectInformation,
IN ULONG Length,
OUT PULONG ReturnLength
);
NTSTATUS STDCALL
NtQuerySecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG Length,
OUT PULONG ResultLength);
NTSTATUS
STDCALL
ZwQuerySecurityObject(
IN HANDLE Object,
IN CINT SecurityObjectInformationClass,
OUT PVOID SecurityObjectInformation,
IN ULONG Length,
OUT PULONG ReturnLength
);
NTSTATUS STDCALL
ZwQuerySecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG Length,
OUT PULONG ResultLength);
/*
* FUNCTION: Queries the virtual memory information.

View file

@ -371,11 +371,18 @@ NTSTATUS STDCALL
CmiObjectCreate(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes);
POBJECT_ATTRIBUTES ObjectAttributes);
VOID STDCALL
CmiObjectDelete(PVOID DeletedObject);
NTSTATUS STDCALL
CmiObjectSecurity(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength);
VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey,
IN PKEY_OBJECT NewKey);

View file

@ -198,7 +198,6 @@ NtDeleteKey(IN HANDLE KeyHandle)
DPRINT("KeyHandle %x\n", KeyHandle);
/* Verify that the handle is valid and is a registry key */
CHECKPOINT1;
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_WRITE,
CmiKeyType,
@ -207,20 +206,25 @@ CHECKPOINT1;
NULL);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
return(Status);
}
CHECKPOINT1;
/* Acquire hive lock */
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
CHECKPOINT1;
VERIFY_KEY_OBJECT(KeyObject);
/* Set the marked for delete bit in the key object */
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
CHECKPOINT1;
/* Check for subkeys */
if (KeyObject->NumberOfSubKeys != 0)
{
Status = STATUS_CANNOT_DELETE;
}
else
{
/* Set the marked for delete bit in the key object */
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
Status = STATUS_SUCCESS;
}
/* Release hive lock */
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
@ -241,7 +245,7 @@ CHECKPOINT1;
* have been released.
*/
return(STATUS_SUCCESS);
return(Status);
}

View file

@ -1021,6 +1021,13 @@ CmiStartHiveUpdate(PREGISTRY_HIVE RegistryHive)
BlockIndex++;
}
Status = NtFlushBuffersFile(FileHandle,
&IoStatusBlock);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtFlushBuffersFile() failed (Status %lx)\n", Status);
}
NtClose(FileHandle);
return(Status);
@ -1030,6 +1037,7 @@ CmiStartHiveUpdate(PREGISTRY_HIVE RegistryHive)
static NTSTATUS
CmiFinishHiveUpdate(PREGISTRY_HIVE RegistryHive)
{
#if 0
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER FileOffset;
@ -1079,13 +1087,25 @@ CmiFinishHiveUpdate(PREGISTRY_HIVE RegistryHive)
sizeof(HIVE_HEADER),
&FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
NtClose(FileHandle);
return(Status);
}
Status = NtFlushBuffersFile(FileHandle,
&IoStatusBlock);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtFlushBuffersFile() failed (Status %lx)\n", Status);
}
NtClose(FileHandle);
return(Status);
#endif
return(STATUS_SUCCESS);
}
@ -1533,9 +1553,62 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive,
PKEY_OBJECT SubKey)
{
PHASH_TABLE_CELL HashBlock;
PVALUE_LIST_CELL ValueList;
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
ULONG i;
DPRINT1("CmiRemoveSubKey() called\n");
/* Remove all values */
if (SubKey->KeyCell->NumberOfValues != 0)
{
/* Get pointer to the value list cell */
ValueList = CmiGetBlock(RegistryHive,
SubKey->KeyCell->ValuesOffset,
NULL);
if (ValueList != NULL)
{
/* Enumerate all values */
for (i = 0; i < SubKey->KeyCell->NumberOfValues; i++)
{
/* Get pointer to value cell */
ValueCell = CmiGetBlock(RegistryHive,
ValueList->Values[i],
NULL);
if (ValueCell != NULL)
{
if (ValueCell->DataSize > 4)
{
DataCell = CmiGetBlock(RegistryHive,
ValueCell->DataOffset,
NULL);
if (DataCell != NULL)
{
/* Destroy data cell */
CmiDestroyBlock(RegistryHive,
DataCell,
ValueCell->DataOffset);
}
}
/* Destroy value cell */
CmiDestroyBlock(RegistryHive,
ValueCell,
ValueList->Values[i]);
}
}
}
/* Destroy value list cell */
CmiDestroyBlock(RegistryHive,
ValueList,
SubKey->KeyCell->ValuesOffset);
SubKey->KeyCell->NumberOfValues = 0;
SubKey->KeyCell->ValuesOffset = -1;
}
/* Remove the key from the parent key's hash block */
if (ParentKey->KeyCell->HashTableOffset != -1)
{

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.84 2003/02/14 17:48:54 ekohl Exp $
/* $Id: registry.c,v 1.85 2003/02/15 18:46:28 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -280,7 +280,7 @@ CmInitializeRegistry(VOID)
CmiKeyType->Close = NULL;
CmiKeyType->Delete = CmiObjectDelete;
CmiKeyType->Parse = CmiObjectParse;
CmiKeyType->Security = NULL;
CmiKeyType->Security = CmiObjectSecurity;
CmiKeyType->QueryName = NULL;
CmiKeyType->OkayToClose = NULL;
CmiKeyType->Create = CmiObjectCreate;

View file

@ -234,7 +234,7 @@ NTSTATUS STDCALL
CmiObjectCreate(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes)
POBJECT_ATTRIBUTES ObjectAttributes)
{
PKEY_OBJECT pKey = ObjectBody;
@ -293,6 +293,19 @@ CmiObjectDelete(PVOID DeletedObject)
}
NTSTATUS STDCALL
CmiObjectSecurity(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength)
{
DPRINT1("CmiObjectSecurity() called\n");
return(STATUS_SUCCESS);
}
VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey,
PKEY_OBJECT NewKey)

View file

@ -45,44 +45,46 @@ ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
NTSTATUS STDCALL
NtQuerySecurityObject(IN HANDLE ObjectHandle,
IN CINT SecurityObjectInformationClass,
OUT PVOID SecurityObjectInformation,
NtQuerySecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG Length,
OUT PULONG ReturnLength)
OUT PULONG ResultLength)
{
NTSTATUS Status;
PVOID Object;
OBJECT_HANDLE_INFORMATION HandleInfo;
POBJECT_HEADER Header;
Status = ObReferenceObjectByHandle(ObjectHandle,
0,
NULL,
KeGetPreviousMode(),
&Object,
&HandleInfo);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Header = BODY_TO_HEADER(Object);
if (Header->ObjectType != NULL &&
Header->ObjectType->Security != NULL)
{
Status = Header->ObjectType->Security(Object,
SecurityObjectInformationClass,
SecurityObjectInformation,
&Length);
*ReturnLength = Length;
}
else
{
Status = STATUS_NOT_IMPLEMENTED;
}
ObDereferenceObject(Object);
return(Status);
POBJECT_HEADER Header;
PVOID Object;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(Handle,
0,
NULL,
KeGetPreviousMode(),
&Object,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Header = BODY_TO_HEADER(Object);
if (Header->ObjectType != NULL &&
Header->ObjectType->Security != NULL)
{
Status = Header->ObjectType->Security(Object,
QuerySecurityDescriptor,
SecurityInformation,
SecurityDescriptor,
&Length);
*ResultLength = Length;
}
else
{
Status = STATUS_NOT_IMPLEMENTED;
}
ObDereferenceObject(Object);
return(Status);
}
@ -91,7 +93,39 @@ NtSetSecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
UNIMPLEMENTED;
POBJECT_HEADER Header;
PVOID Object;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(Handle,
0,
NULL,
KeGetPreviousMode(),
&Object,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Header = BODY_TO_HEADER(Object);
if (Header->ObjectType != NULL &&
Header->ObjectType->Security != NULL)
{
Status = Header->ObjectType->Security(Object,
SetSecurityDescriptor,
SecurityInformation,
SecurityDescriptor,
NULL);
}
else
{
Status = STATUS_NOT_IMPLEMENTED;
}
ObDereferenceObject(Object);
return(Status);
}
/* EOF */