mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[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. svn path=/trunk/; revision=58196
This commit is contained in:
parent
56704cdb76
commit
7a779210ab
3 changed files with 196 additions and 22 deletions
|
@ -157,8 +157,7 @@ SampCreateDbObject(IN PSAM_DB_OBJECT ParentObject,
|
|||
0,
|
||||
NULL);
|
||||
|
||||
if ((ObjectType == SamDbAliasObject) ||
|
||||
(ObjectType == SamDbGroupObject))
|
||||
if (ObjectType == SamDbAliasObject)
|
||||
{
|
||||
/* Open the object key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
|
@ -244,9 +243,6 @@ SampCreateDbObject(IN PSAM_DB_OBJECT ParentObject,
|
|||
NewObject->RelativeId = RelativeId;
|
||||
NewObject->ParentObject = ParentObject;
|
||||
|
||||
if (ParentObject != NULL)
|
||||
ParentObject->RefCount++;
|
||||
|
||||
*DbObject = NewObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -313,8 +309,7 @@ SampOpenDbObject(IN PSAM_DB_OBJECT ParentObject,
|
|||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
|
||||
if ((ObjectType == SamDbAliasObject) ||
|
||||
(ObjectType == SamDbGroupObject))
|
||||
if (ObjectType == SamDbAliasObject)
|
||||
{
|
||||
/* Open the object key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
|
@ -396,9 +391,6 @@ SampOpenDbObject(IN PSAM_DB_OBJECT ParentObject,
|
|||
NewObject->RelativeId = RelativeId;
|
||||
NewObject->ParentObject = ParentObject;
|
||||
|
||||
if (ParentObject != NULL)
|
||||
ParentObject->RefCount++;
|
||||
|
||||
*DbObject = NewObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -475,14 +467,144 @@ SampCloseDbObject(PSAM_DB_OBJECT DbObject)
|
|||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
|
||||
|
||||
if (ParentObject != NULL)
|
||||
{
|
||||
ParentObject->RefCount--;
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ParentObject->RefCount == 0)
|
||||
Status = SampCloseDbObject(ParentObject);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -3952,7 +3952,7 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
|
|||
&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 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
|
|||
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 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
|
|||
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 @@ NTSTATUS
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
typedef enum _SAM_DB_OBJECT_TYPE
|
||||
{
|
||||
SamDbIgnoreObject,
|
||||
SamDbContainerObject,
|
||||
SamDbServerObject,
|
||||
SamDbDomainObject,
|
||||
SamDbAliasObject,
|
||||
|
@ -45,7 +44,7 @@ typedef struct _SAM_DB_OBJECT
|
|||
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;
|
||||
|
@ -142,6 +141,9 @@ SampValidateDbObject(SAMPR_HANDLE Handle,
|
|||
NTSTATUS
|
||||
SampCloseDbObject(PSAM_DB_OBJECT DbObject);
|
||||
|
||||
NTSTATUS
|
||||
SampDeleteAccountDbObject(PSAM_DB_OBJECT DbObject);
|
||||
|
||||
NTSTATUS
|
||||
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
||||
LPWSTR AttributeName,
|
||||
|
|
Loading…
Reference in a new issue