mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 03:46:38 +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,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if ((ObjectType == SamDbAliasObject) ||
|
if (ObjectType == SamDbAliasObject)
|
||||||
(ObjectType == SamDbGroupObject))
|
|
||||||
{
|
{
|
||||||
/* Open the object key */
|
/* Open the object key */
|
||||||
RtlInitUnicodeString(&KeyName,
|
RtlInitUnicodeString(&KeyName,
|
||||||
|
@ -244,9 +243,6 @@ SampCreateDbObject(IN PSAM_DB_OBJECT ParentObject,
|
||||||
NewObject->RelativeId = RelativeId;
|
NewObject->RelativeId = RelativeId;
|
||||||
NewObject->ParentObject = ParentObject;
|
NewObject->ParentObject = ParentObject;
|
||||||
|
|
||||||
if (ParentObject != NULL)
|
|
||||||
ParentObject->RefCount++;
|
|
||||||
|
|
||||||
*DbObject = NewObject;
|
*DbObject = NewObject;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -313,8 +309,7 @@ SampOpenDbObject(IN PSAM_DB_OBJECT ParentObject,
|
||||||
KEY_ALL_ACCESS,
|
KEY_ALL_ACCESS,
|
||||||
&ObjectAttributes);
|
&ObjectAttributes);
|
||||||
|
|
||||||
if ((ObjectType == SamDbAliasObject) ||
|
if (ObjectType == SamDbAliasObject)
|
||||||
(ObjectType == SamDbGroupObject))
|
|
||||||
{
|
{
|
||||||
/* Open the object key */
|
/* Open the object key */
|
||||||
RtlInitUnicodeString(&KeyName,
|
RtlInitUnicodeString(&KeyName,
|
||||||
|
@ -396,9 +391,6 @@ SampOpenDbObject(IN PSAM_DB_OBJECT ParentObject,
|
||||||
NewObject->RelativeId = RelativeId;
|
NewObject->RelativeId = RelativeId;
|
||||||
NewObject->ParentObject = ParentObject;
|
NewObject->ParentObject = ParentObject;
|
||||||
|
|
||||||
if (ParentObject != NULL)
|
|
||||||
ParentObject->RefCount++;
|
|
||||||
|
|
||||||
*DbObject = NewObject;
|
*DbObject = NewObject;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -475,14 +467,144 @@ SampCloseDbObject(PSAM_DB_OBJECT DbObject)
|
||||||
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
|
||||||
|
|
||||||
if (ParentObject != NULL)
|
return Status;
|
||||||
{
|
}
|
||||||
ParentObject->RefCount--;
|
|
||||||
|
|
||||||
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3952,7 +3952,7 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
|
||||||
&UserObject);
|
&UserObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("SampOpenUserObject() failed (Status 0x%08lx)\n", Status);
|
TRACE("SampOpenUserObject() failed (Status 0x%08lx)\n", Status);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3962,7 +3962,7 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
|
||||||
Attributes);
|
Attributes);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status);
|
TRACE("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3971,7 +3971,7 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
|
||||||
MemberId);
|
MemberId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status);
|
TRACE("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -3987,8 +3987,58 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SamrDeleteGroup(IN OUT SAMPR_HANDLE *GroupHandle)
|
SamrDeleteGroup(IN OUT SAMPR_HANDLE *GroupHandle)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PSAM_DB_OBJECT GroupObject;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
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
|
typedef enum _SAM_DB_OBJECT_TYPE
|
||||||
{
|
{
|
||||||
SamDbIgnoreObject,
|
SamDbIgnoreObject,
|
||||||
SamDbContainerObject,
|
|
||||||
SamDbServerObject,
|
SamDbServerObject,
|
||||||
SamDbDomainObject,
|
SamDbDomainObject,
|
||||||
SamDbAliasObject,
|
SamDbAliasObject,
|
||||||
|
@ -45,7 +44,7 @@ typedef struct _SAM_DB_OBJECT
|
||||||
ACCESS_MASK Access;
|
ACCESS_MASK Access;
|
||||||
LPWSTR Name;
|
LPWSTR Name;
|
||||||
HANDLE KeyHandle;
|
HANDLE KeyHandle;
|
||||||
HANDLE MembersKeyHandle; // only used by Aliases and Groups
|
HANDLE MembersKeyHandle; // only used by Aliases
|
||||||
ULONG RelativeId;
|
ULONG RelativeId;
|
||||||
struct _SAM_DB_OBJECT *ParentObject;
|
struct _SAM_DB_OBJECT *ParentObject;
|
||||||
} SAM_DB_OBJECT, *PSAM_DB_OBJECT;
|
} SAM_DB_OBJECT, *PSAM_DB_OBJECT;
|
||||||
|
@ -142,6 +141,9 @@ SampValidateDbObject(SAMPR_HANDLE Handle,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SampCloseDbObject(PSAM_DB_OBJECT DbObject);
|
SampCloseDbObject(PSAM_DB_OBJECT DbObject);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SampDeleteAccountDbObject(PSAM_DB_OBJECT DbObject);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
||||||
LPWSTR AttributeName,
|
LPWSTR AttributeName,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue