mirror of
https://github.com/reactos/reactos.git
synced 2025-06-06 01:40:36 +00:00
[SAMLIB][SAMSRV]
- Implement SamCreateUserInDomain and SamrCreateUserInDomain. - SamOpenDomain: Use the correct object types when trying to open a domain object. svn path=/trunk/; revision=56672
This commit is contained in:
parent
bf77113125
commit
5e6927ddd1
6 changed files with 314 additions and 5 deletions
|
@ -431,6 +431,36 @@ SamConnect(IN OUT PUNICODE_STRING ServerName,
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN PUNICODE_STRING AccountName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
OUT PSAM_HANDLE UserHandle,
|
||||
OUT PULONG RelativeId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamCreateUserInDomain(%p,%p,0x%08x,%p,%p)\n",
|
||||
DomainHandle, AccountName, DesiredAccess, UserHandle, RelativeId);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrCreateUserInDomain((SAMPR_HANDLE)DomainHandle,
|
||||
(PRPC_UNICODE_STRING)AccountName,
|
||||
DesiredAccess,
|
||||
(SAMPR_HANDLE *)UserHandle,
|
||||
RelativeId);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamOpenDomain(IN SAM_HANDLE ServerHandle,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
@ stub SamCreateAliasInDomain
|
||||
@ stub SamCreateGroupInDomain
|
||||
@ stub SamCreateUser2InDomain
|
||||
@ stub SamCreateUserInDomain
|
||||
@ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr)
|
||||
@ stub SamDeleteAlias
|
||||
@ stub SamDeleteGroup
|
||||
@ stub SamDeleteUser
|
||||
|
|
|
@ -602,6 +602,151 @@ SampCloseDbObject(PSAM_DB_OBJECT DbObject)
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
|
||||
IN LPCWSTR lpContainerName,
|
||||
IN LPCWSTR lpAliasName,
|
||||
IN ULONG ulAliasValue)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
UNICODE_STRING ValueName;
|
||||
HANDLE ContainerKeyHandle = NULL;
|
||||
HANDLE NamesKeyHandle = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Open the container key */
|
||||
RtlInitUnicodeString(&KeyName, lpContainerName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
DomainObject->KeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&ContainerKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Open the 'Names' key */
|
||||
RtlInitUnicodeString(&KeyName, L"Names");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ContainerKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&NamesKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
/* Set the alias value */
|
||||
RtlInitUnicodeString(&ValueName, lpAliasName);
|
||||
|
||||
Status = NtSetValueKey(NamesKeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
(LPVOID)&ulAliasValue,
|
||||
sizeof(ULONG));
|
||||
|
||||
done:
|
||||
if (NamesKeyHandle)
|
||||
NtClose(NamesKeyHandle);
|
||||
|
||||
if (ContainerKeyHandle)
|
||||
NtClose(ContainerKeyHandle);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampCheckDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
|
||||
IN LPCWSTR lpContainerName,
|
||||
IN LPCWSTR lpAliasName,
|
||||
OUT PBOOL bAliasExists)
|
||||
{
|
||||
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
UNICODE_STRING ValueName;
|
||||
HANDLE ContainerKeyHandle = NULL;
|
||||
HANDLE NamesKeyHandle = NULL;
|
||||
ULONG BufferLength = sizeof(ULONG);
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Open the container key */
|
||||
RtlInitUnicodeString(&KeyName, lpContainerName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
DomainObject->KeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&ContainerKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Open the 'Names' key */
|
||||
RtlInitUnicodeString(&KeyName, L"Names");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ContainerKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&NamesKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
/* Get the alias value */
|
||||
RtlInitUnicodeString(&ValueName, lpAliasName);
|
||||
|
||||
BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
|
||||
|
||||
/* Allocate memory for the value */
|
||||
ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
|
||||
if (ValueInfo == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
/* Query the value */
|
||||
Status = ZwQueryValueKey(NamesKeyHandle,
|
||||
&ValueName,
|
||||
KeyValuePartialInformation,
|
||||
ValueInfo,
|
||||
BufferLength,
|
||||
&BufferLength);
|
||||
|
||||
*bAliasExists = (Status != STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* Free the memory and return status */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
|
||||
|
||||
done:
|
||||
if (NamesKeyHandle)
|
||||
NtClose(NamesKeyHandle);
|
||||
|
||||
if (ContainerKeyHandle)
|
||||
NtClose(ContainerKeyHandle);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
||||
LPWSTR AttributeName,
|
||||
|
|
|
@ -193,6 +193,7 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
|||
TRACE("SamrOpenDomain(%p %lx %p %p)\n",
|
||||
ServerHandle, DesiredAccess, DomainId, DomainHandle);
|
||||
|
||||
/* Validate the server handle */
|
||||
Status = SampValidateDbObject(ServerHandle,
|
||||
SamDbServerObject,
|
||||
SAM_SERVER_LOOKUP_DOMAIN,
|
||||
|
@ -216,7 +217,7 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
|||
Status = SampOpenDbObject(ServerObject,
|
||||
L"Domains",
|
||||
L"Builtin",
|
||||
SamDbServerObject,
|
||||
SamDbDomainObject,
|
||||
DesiredAccess,
|
||||
&DomainObject);
|
||||
}
|
||||
|
@ -231,7 +232,7 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
|||
Status = SampOpenDbObject(ServerObject,
|
||||
L"Domains",
|
||||
L"Account",
|
||||
SamDbServerObject,
|
||||
SamDbDomainObject,
|
||||
DesiredAccess,
|
||||
&DomainObject);
|
||||
}
|
||||
|
@ -306,8 +307,116 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
OUT SAMPR_HANDLE *UserHandle,
|
||||
OUT unsigned long *RelativeId)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PSAM_DB_OBJECT DomainObject;
|
||||
PSAM_DB_OBJECT UserObject;
|
||||
ULONG ulSize;
|
||||
ULONG ulRid;
|
||||
WCHAR szRid[9];
|
||||
BOOL bAliasExists = FALSE;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
|
||||
DomainHandle, Name, DesiredAccess, UserHandle, RelativeId);
|
||||
|
||||
/* Validate the domain handle */
|
||||
Status = SampValidateDbObject(DomainHandle,
|
||||
SamDbDomainObject,
|
||||
DOMAIN_CREATE_USER,
|
||||
&DomainObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get the NextRID attribute */
|
||||
ulSize = sizeof(ULONG);
|
||||
Status = SampGetObjectAttribute(DomainObject,
|
||||
L"NextRID",
|
||||
NULL,
|
||||
(LPVOID)&ulRid,
|
||||
&ulSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
ulRid = DOMAIN_USER_RID_MAX;
|
||||
|
||||
TRACE("RID: %lx\n", ulRid);
|
||||
|
||||
/* Convert the RID into a string (hex) */
|
||||
_ultow(ulRid, szRid, 16);
|
||||
|
||||
/* Check whether the user name is already in use */
|
||||
Status = SampCheckDbObjectNameAlias(DomainObject,
|
||||
L"Users",
|
||||
Name->Buffer,
|
||||
&bAliasExists);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (bAliasExists)
|
||||
{
|
||||
TRACE("The user account %S already exists!\n", Name->Buffer);
|
||||
return STATUS_USER_EXISTS;
|
||||
}
|
||||
|
||||
/* Create the user object */
|
||||
Status = SampCreateDbObject(DomainObject,
|
||||
L"Users",
|
||||
szRid,
|
||||
SamDbUserObject,
|
||||
DesiredAccess,
|
||||
&UserObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add the name alias for the user object */
|
||||
Status = SampSetDbObjectNameAlias(DomainObject,
|
||||
L"Users",
|
||||
Name->Buffer,
|
||||
ulRid);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the account name attribute */
|
||||
Status = SampSetObjectAttribute(UserObject,
|
||||
L"AccountName",
|
||||
REG_SZ,
|
||||
(LPVOID)Name->Buffer,
|
||||
Name->MaximumLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* FIXME: Set default user attributes */
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*UserHandle = (SAMPR_HANDLE)UserObject;
|
||||
*RelativeId = ulRid;
|
||||
}
|
||||
|
||||
/* Increment the NextRID attribute */
|
||||
ulRid++;
|
||||
ulSize = sizeof(ULONG);
|
||||
SampSetObjectAttribute(DomainObject,
|
||||
L"NextRID",
|
||||
REG_DWORD,
|
||||
(LPVOID)&ulRid,
|
||||
ulSize);
|
||||
|
||||
TRACE("returns with status 0x%08lx\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Function 13 */
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* PROGRAMMERS: Eric Kohl
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windows.h>
|
||||
#define NTOS_MODE_USER
|
||||
|
@ -75,6 +76,18 @@ SampValidateDbObject(SAMPR_HANDLE Handle,
|
|||
NTSTATUS
|
||||
SampCloseDbObject(PSAM_DB_OBJECT DbObject);
|
||||
|
||||
NTSTATUS
|
||||
SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
|
||||
IN LPCWSTR lpContainerName,
|
||||
IN LPCWSTR lpAliasName,
|
||||
IN DWORD dwAliasValue);
|
||||
|
||||
NTSTATUS
|
||||
SampCheckDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
|
||||
IN LPCWSTR lpContainerName,
|
||||
IN LPCWSTR lpAliasName,
|
||||
OUT PBOOL bAliasExists);
|
||||
|
||||
NTSTATUS
|
||||
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
||||
LPWSTR AttributeName,
|
||||
|
|
|
@ -6,6 +6,18 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DOMAIN_READ_PASSWORD_PARAMETERS 1
|
||||
#define DOMAIN_WRITE_PASSWORD_PARAMS 2
|
||||
#define DOMAIN_READ_OTHER_PARAMETERS 4
|
||||
#define DOMAIN_WRITE_OTHER_PARAMETERS 8
|
||||
#define DOMAIN_CREATE_USER 16
|
||||
#define DOMAIN_CREATE_GROUP 32
|
||||
#define DOMAIN_CREATE_ALIAS 64
|
||||
#define DOMAIN_GET_ALIAS_MEMBERSHIP 128
|
||||
#define DOMAIN_LIST_ACCOUNTS 256
|
||||
#define DOMAIN_LOOKUP 512
|
||||
#define DOMAIN_ADMINISTER_SERVER 1024
|
||||
|
||||
#define SAM_SERVER_CONNECT 1
|
||||
#define SAM_SERVER_SHUTDOWN 2
|
||||
#define SAM_SERVER_INITIALIZE 4
|
||||
|
|
Loading…
Reference in a new issue