Author: ekohl
Date: Mon May 28 22:47:52 2012
New Revision: 56672
URL:
http://svn.reactos.org/svn/reactos?rev=56672&view=rev
Log:
[SAMLIB][SAMSRV]
- Implement SamCreateUserInDomain and SamrCreateUserInDomain.
- SamOpenDomain: Use the correct object types when trying to open a domain object.
Modified:
trunk/reactos/dll/win32/samlib/samlib.c
trunk/reactos/dll/win32/samlib/samlib.spec
trunk/reactos/dll/win32/samsrv/database.c
trunk/reactos/dll/win32/samsrv/samrpc.c
trunk/reactos/dll/win32/samsrv/samsrv.h
trunk/reactos/include/ddk/ntsam.h
Modified: trunk/reactos/dll/win32/samlib/samlib.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.c?…
==============================================================================
--- trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] Mon May 28 22:47:52 2012
@@ -433,6 +433,36 @@
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,
IN ACCESS_MASK DesiredAccess,
IN PSID DomainId,
Modified: trunk/reactos/dll/win32/samlib/samlib.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.sp…
==============================================================================
--- trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] Mon May 28 22:47:52 2012
@@ -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
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] Mon May 28 22:47:52 2012
@@ -603,6 +603,151 @@
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,
ULONG AttributeType,
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] Mon May 28 22:47:52 2012
@@ -193,6 +193,7 @@
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 @@
Status = SampOpenDbObject(ServerObject,
L"Domains",
L"Builtin",
- SamDbServerObject,
+ SamDbDomainObject,
DesiredAccess,
&DomainObject);
}
@@ -231,7 +232,7 @@
Status = SampOpenDbObject(ServerObject,
L"Domains",
L"Account",
- SamDbServerObject,
+ SamDbDomainObject,
DesiredAccess,
&DomainObject);
}
@@ -306,8 +307,116 @@
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 */
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] Mon May 28 22:47:52 2012
@@ -7,6 +7,7 @@
* PROGRAMMERS: Eric Kohl
*/
+#include <stdlib.h>
#define WIN32_NO_STATUS
#include <windows.h>
#define NTOS_MODE_USER
@@ -76,6 +77,18 @@
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,
ULONG AttributeType,
Modified: trunk/reactos/include/ddk/ntsam.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=56…
==============================================================================
--- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original)
+++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Mon May 28 22:47:52 2012
@@ -5,6 +5,18 @@
#ifdef __cplusplus
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