Author: ekohl
Date: Sun Jan 20 10:22:15 2013
New Revision: 58196
URL:
http://svn.reactos.org/svn/reactos?rev=58196&view=rev
Log:
[SAMSRV]
- Add a generic delete function for database objects.
- Do not create Members sub keys for group objects.
- Get rid of the SamDbContainerObject object type.
- Implement SamrDeleteGroup.
Modified:
trunk/reactos/dll/win32/samsrv/database.c
trunk/reactos/dll/win32/samsrv/samrpc.c
trunk/reactos/dll/win32/samsrv/samsrv.h
Modified: trunk/reactos/dll/win32/samsrv/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/database.…
==============================================================================
--- trunk/reactos/dll/win32/samsrv/database.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/database.c [iso-8859-1] Sun Jan 20 10:22:15 2013
@@ -157,8 +157,7 @@
0,
NULL);
- if ((ObjectType == SamDbAliasObject) ||
- (ObjectType == SamDbGroupObject))
+ if (ObjectType == SamDbAliasObject)
{
/* Open the object key */
RtlInitUnicodeString(&KeyName,
@@ -244,9 +243,6 @@
NewObject->RelativeId = RelativeId;
NewObject->ParentObject = ParentObject;
- if (ParentObject != NULL)
- ParentObject->RefCount++;
-
*DbObject = NewObject;
return STATUS_SUCCESS;
@@ -313,8 +309,7 @@
KEY_ALL_ACCESS,
&ObjectAttributes);
- if ((ObjectType == SamDbAliasObject) ||
- (ObjectType == SamDbGroupObject))
+ if (ObjectType == SamDbAliasObject)
{
/* Open the object key */
RtlInitUnicodeString(&KeyName,
@@ -396,9 +391,6 @@
NewObject->RelativeId = RelativeId;
NewObject->ParentObject = ParentObject;
- if (ParentObject != NULL)
- ParentObject->RefCount++;
-
*DbObject = NewObject;
return STATUS_SUCCESS;
@@ -475,13 +467,143 @@
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
- if (ParentObject != NULL)
- {
- ParentObject->RefCount--;
-
- if (ParentObject->RefCount == 0)
- Status = SampCloseDbObject(ParentObject);
- }
+ return Status;
+}
+
+
+NTSTATUS
+SampDeleteAccountDbObject(PSAM_DB_OBJECT DbObject)
+{
+ LPCWSTR ContainerName;
+ LPWSTR AccountName = NULL;
+ HKEY ContainerKey;
+ HKEY NamesKey;
+ ULONG Length = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ TRACE("(%p)\n", DbObject);
+
+ /* Server and Domain objects cannot be deleted */
+ switch (DbObject->ObjectType)
+ {
+ case SamDbAliasObject:
+ ContainerName = L"Aliases";
+ break;
+
+ case SamDbGroupObject:
+ ContainerName = L"Groups";
+ break;
+
+ case SamDbUserObject:
+ ContainerName = L"Users";
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Get the account name */
+ Status = SampGetObjectAttribute(DbObject,
+ L"Name",
+ NULL,
+ NULL,
+ &Length);
+ if (Status != STATUS_BUFFER_OVERFLOW)
+ {
+ TRACE("Status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ AccountName = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ Length);
+ if (AccountName == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ Status = SampGetObjectAttribute(DbObject,
+ L"Name",
+ NULL,
+ (PVOID)AccountName,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampGetObjectAttribute failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ if (DbObject->KeyHandle != NULL)
+ NtClose(DbObject->KeyHandle);
+
+ if (DbObject->ObjectType == SamDbAliasObject)
+ {
+ if (DbObject->MembersKeyHandle != NULL)
+ NtClose(DbObject->MembersKeyHandle);
+
+ SampRegDeleteKey(DbObject->KeyHandle,
+ L"Members");
+ }
+
+ /* Open the domain container key */
+ Status = SampRegOpenKey(DbObject->ParentObject->KeyHandle,
+ ContainerName,
+ DELETE | KEY_SET_VALUE,
+ &ContainerKey);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRegOpenKey failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Open the Names key */
+ Status = SampRegOpenKey(ContainerKey,
+ L"Names",
+ KEY_SET_VALUE,
+ &NamesKey);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRegOpenKey failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Remove the account from the Names key */
+ Status = SampRegDeleteValue(NamesKey,
+ AccountName);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRegDeleteValue failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Remove the account key from the container */
+ Status = SampRegDeleteKey(ContainerKey,
+ DbObject->Name);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRegDeleteKey failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Release the database object name */
+ if (DbObject->Name != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject->Name);
+
+ /* Release the database object */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
+
+ Status = STATUS_SUCCESS;
+
+done:
+ if (NamesKey != NULL)
+ SampRegCloseKey(NamesKey);
+
+ if (ContainerKey != NULL)
+ SampRegCloseKey(ContainerKey);
+
+ if (AccountName != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, AccountName);
return Status;
}
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?…
==============================================================================
--- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Sun Jan 20 10:22:15 2013
@@ -3952,7 +3952,7 @@
&UserObject);
if (!NT_SUCCESS(Status))
{
- ERR("SampOpenUserObject() failed (Status 0x%08lx)\n", Status);
+ TRACE("SampOpenUserObject() failed (Status 0x%08lx)\n", Status);
goto done;
}
@@ -3962,7 +3962,7 @@
Attributes);
if (!NT_SUCCESS(Status))
{
- ERR("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n",
Status);
+ TRACE("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n",
Status);
goto done;
}
@@ -3971,7 +3971,7 @@
MemberId);
if (!NT_SUCCESS(Status))
{
- ERR("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status);
+ TRACE("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status);
}
done:
@@ -3987,8 +3987,58 @@
NTAPI
SamrDeleteGroup(IN OUT SAMPR_HANDLE *GroupHandle)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PSAM_DB_OBJECT GroupObject;
+ ULONG Length = 0;
+ NTSTATUS Status;
+
+ TRACE("(%p)\n", GroupHandle);
+
+ /* Validate the group handle */
+ Status = SampValidateDbObject(*GroupHandle,
+ SamDbGroupObject,
+ DELETE,
+ &GroupObject);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampValidateDbObject() failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ /* Fail, if the group is built-in */
+ if (GroupObject->RelativeId < 1000)
+ {
+ TRACE("You can not delete a special account!\n");
+ return STATUS_SPECIAL_ACCOUNT;
+ }
+
+ /* Get the length of the Members attribute */
+ SampGetObjectAttribute(GroupObject,
+ L"Members",
+ NULL,
+ NULL,
+ &Length);
+
+ /* Fail, if the group has members */
+ if (Length != 0)
+ {
+ TRACE("There are still members in the group!\n");
+ return STATUS_MEMBER_IN_GROUP;
+ }
+
+ /* FIXME: Remove the group from all aliases */
+
+ /* Delete the group from the database */
+ Status = SampDeleteAccountDbObject(GroupObject);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n",
Status);
+ return Status;
+ }
+
+ /* Invalidate the handle */
+ *GroupHandle = NULL;
+
+ return STATUS_SUCCESS;
}
Modified: trunk/reactos/dll/win32/samsrv/samsrv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samsrv.h?…
==============================================================================
--- trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] Sun Jan 20 10:22:15 2013
@@ -29,7 +29,6 @@
typedef enum _SAM_DB_OBJECT_TYPE
{
SamDbIgnoreObject,
- SamDbContainerObject,
SamDbServerObject,
SamDbDomainObject,
SamDbAliasObject,
@@ -45,7 +44,7 @@
ACCESS_MASK Access;
LPWSTR Name;
HANDLE KeyHandle;
- HANDLE MembersKeyHandle; // only used by Aliases and Groups
+ HANDLE MembersKeyHandle; // only used by Aliases
ULONG RelativeId;
struct _SAM_DB_OBJECT *ParentObject;
} SAM_DB_OBJECT, *PSAM_DB_OBJECT;
@@ -143,6 +142,9 @@
SampCloseDbObject(PSAM_DB_OBJECT DbObject);
NTSTATUS
+SampDeleteAccountDbObject(PSAM_DB_OBJECT DbObject);
+
+NTSTATUS
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
LPWSTR AttributeName,
ULONG AttributeType,