mirror of
https://github.com/reactos/reactos.git
synced 2025-06-06 18:00:41 +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;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SamOpenDomain(IN SAM_HANDLE ServerHandle,
|
SamOpenDomain(IN SAM_HANDLE ServerHandle,
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
@ stub SamCreateAliasInDomain
|
@ stub SamCreateAliasInDomain
|
||||||
@ stub SamCreateGroupInDomain
|
@ stub SamCreateGroupInDomain
|
||||||
@ stub SamCreateUser2InDomain
|
@ stub SamCreateUser2InDomain
|
||||||
@ stub SamCreateUserInDomain
|
@ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr)
|
||||||
@ stub SamDeleteAlias
|
@ stub SamDeleteAlias
|
||||||
@ stub SamDeleteGroup
|
@ stub SamDeleteGroup
|
||||||
@ stub SamDeleteUser
|
@ 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
|
NTSTATUS
|
||||||
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
||||||
LPWSTR AttributeName,
|
LPWSTR AttributeName,
|
||||||
|
|
|
@ -193,6 +193,7 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
||||||
TRACE("SamrOpenDomain(%p %lx %p %p)\n",
|
TRACE("SamrOpenDomain(%p %lx %p %p)\n",
|
||||||
ServerHandle, DesiredAccess, DomainId, DomainHandle);
|
ServerHandle, DesiredAccess, DomainId, DomainHandle);
|
||||||
|
|
||||||
|
/* Validate the server handle */
|
||||||
Status = SampValidateDbObject(ServerHandle,
|
Status = SampValidateDbObject(ServerHandle,
|
||||||
SamDbServerObject,
|
SamDbServerObject,
|
||||||
SAM_SERVER_LOOKUP_DOMAIN,
|
SAM_SERVER_LOOKUP_DOMAIN,
|
||||||
|
@ -216,7 +217,7 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
||||||
Status = SampOpenDbObject(ServerObject,
|
Status = SampOpenDbObject(ServerObject,
|
||||||
L"Domains",
|
L"Domains",
|
||||||
L"Builtin",
|
L"Builtin",
|
||||||
SamDbServerObject,
|
SamDbDomainObject,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
&DomainObject);
|
&DomainObject);
|
||||||
}
|
}
|
||||||
|
@ -231,7 +232,7 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
||||||
Status = SampOpenDbObject(ServerObject,
|
Status = SampOpenDbObject(ServerObject,
|
||||||
L"Domains",
|
L"Domains",
|
||||||
L"Account",
|
L"Account",
|
||||||
SamDbServerObject,
|
SamDbDomainObject,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
&DomainObject);
|
&DomainObject);
|
||||||
}
|
}
|
||||||
|
@ -306,8 +307,116 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||||
OUT SAMPR_HANDLE *UserHandle,
|
OUT SAMPR_HANDLE *UserHandle,
|
||||||
OUT unsigned long *RelativeId)
|
OUT unsigned long *RelativeId)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PSAM_DB_OBJECT DomainObject;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
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 */
|
/* Function 13 */
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* PROGRAMMERS: Eric Kohl
|
* PROGRAMMERS: Eric Kohl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#define NTOS_MODE_USER
|
#define NTOS_MODE_USER
|
||||||
|
@ -75,6 +76,18 @@ SampValidateDbObject(SAMPR_HANDLE Handle,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SampCloseDbObject(PSAM_DB_OBJECT DbObject);
|
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
|
NTSTATUS
|
||||||
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
|
||||||
LPWSTR AttributeName,
|
LPWSTR AttributeName,
|
||||||
|
|
|
@ -6,6 +6,18 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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_CONNECT 1
|
||||||
#define SAM_SERVER_SHUTDOWN 2
|
#define SAM_SERVER_SHUTDOWN 2
|
||||||
#define SAM_SERVER_INITIALIZE 4
|
#define SAM_SERVER_INITIALIZE 4
|
||||||
|
|
Loading…
Reference in a new issue