From f023556a306531bb5861d2f33ccc7b6f86493e19 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 1 Jun 2012 18:03:25 +0000 Subject: [PATCH] [SAMLIB] - Implement SamFreeMemory and SamLookupDomainInSamServer. - Remove unused file debug.h. [SAMSRV] - Implement SamrLookupDomainInSamServer. - Add registry helper functions. - Store the domain name in a new Name attribute which is used by Sam(r)LookupDomainInSamServer. svn path=/trunk/; revision=56685 --- reactos/dll/win32/samlib/debug.h | 16 --- reactos/dll/win32/samlib/samlib.c | 38 +++++ reactos/dll/win32/samlib/samlib.spec | 4 +- reactos/dll/win32/samsrv/CMakeLists.txt | 1 + reactos/dll/win32/samsrv/registry.c | 175 ++++++++++++++++++++++++ reactos/dll/win32/samsrv/samrpc.c | 102 +++++++++++++- reactos/dll/win32/samsrv/samsrv.h | 29 ++++ reactos/dll/win32/samsrv/setup.c | 14 +- reactos/include/ddk/ntsam.h | 10 ++ 9 files changed, 367 insertions(+), 22 deletions(-) delete mode 100644 reactos/dll/win32/samlib/debug.h create mode 100644 reactos/dll/win32/samsrv/registry.c diff --git a/reactos/dll/win32/samlib/debug.h b/reactos/dll/win32/samlib/debug.h deleted file mode 100644 index b54107f482c..00000000000 --- a/reactos/dll/win32/samlib/debug.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifdef NDEBUG -#define DPRINT(...) -#define CHECKPOINT -#else -#define DPRINT(...) do { DebugPrint("(SAMLIB:%s:%d) ",__FILE__,__LINE__); DebugPrint(__VA_ARGS__); } while(0) -#define CHECKPOINT do { DebugPrint("(SAMLIB:%s:%d) Checkpoint\n",__FILE__,__LINE__); } while(0) -#endif - -#define DPRINT1(...) do { DebugPrint("(SAMLIB:%s:%d) ",__FILE__,__LINE__); DebugPrint(__VA_ARGS__); } while(0) -#define CHECKPOINT1 do { DebugPrint("(SAMLIB:%s:%d) Checkpoint\n",__FILE__,__LINE__); } while(0) - - -void -DebugPrint(char* fmt,...); - -/* EOF */ diff --git a/reactos/dll/win32/samlib/samlib.c b/reactos/dll/win32/samlib/samlib.c index d77543b1469..1354f284bc8 100644 --- a/reactos/dll/win32/samlib/samlib.c +++ b/reactos/dll/win32/samlib/samlib.c @@ -184,6 +184,44 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle, } +NTSTATUS +NTAPI +SamFreeMemory(IN PVOID Buffer) +{ + if (Buffer!= NULL) + midl_user_free(Buffer); + + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, + IN PUNICODE_STRING Name, + OUT PSID *DomainId) +{ + NTSTATUS Status; + + TRACE("SamLookupDomainInSamServer(%p,%p,%p)\n", + ServerHandle, Name, DomainId); + + RpcTryExcept + { + Status = SamrLookupDomainInSamServer((SAMPR_HANDLE)ServerHandle, + (PRPC_UNICODE_STRING)Name, + (PRPC_SID *)DomainId); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + NTSTATUS NTAPI SamOpenDomain(IN SAM_HANDLE ServerHandle, diff --git a/reactos/dll/win32/samlib/samlib.spec b/reactos/dll/win32/samlib/samlib.spec index 6abfa9f64f3..3991574c244 100644 --- a/reactos/dll/win32/samlib/samlib.spec +++ b/reactos/dll/win32/samlib/samlib.spec @@ -18,14 +18,14 @@ @ stub SamEnumerateDomainsInSamServer @ stub SamEnumerateGroupsInDomain @ stub SamEnumerateUsersInDomain -@ stub SamFreeMemory +@ stdcall SamFreeMemory(ptr) @ stub SamGetAliasMembership @ stub SamGetCompatibilityMode @ stub SamGetDisplayEnumerationIndex @ stub SamGetGroupsForUser @ stub SamGetMembersInAlias @ stub SamGetMembersInGroup -@ stub SamLookupDomainInSamServer +@ stdcall SamLookupDomainInSamServer(ptr ptr ptr) @ stub SamLookupIdsInDomain @ stub SamLookupNamesInDomain @ stub SamOpenAlias diff --git a/reactos/dll/win32/samsrv/CMakeLists.txt b/reactos/dll/win32/samsrv/CMakeLists.txt index 0a1b9dd12b2..bdc88e0a55f 100644 --- a/reactos/dll/win32/samsrv/CMakeLists.txt +++ b/reactos/dll/win32/samsrv/CMakeLists.txt @@ -9,6 +9,7 @@ spec2def(samsrv.dll samsrv.spec ADD_IMPORTLIB) list(APPEND SOURCE database.c + registry.c samrpc.c samsrv.c setup.c diff --git a/reactos/dll/win32/samsrv/registry.c b/reactos/dll/win32/samsrv/registry.c new file mode 100644 index 00000000000..28e6bb00792 --- /dev/null +++ b/reactos/dll/win32/samsrv/registry.c @@ -0,0 +1,175 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: Security Account Manager (SAM) Server + * FILE: reactos/dll/win32/samsrv/registry.c + * PURPOSE: Registry helper functions + * + * PROGRAMMERS: Eric Kohl + */ + +/* INCLUDES ****************************************************************/ + +#include "samsrv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(samsrv); + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS +NTAPI +SampRegEnumerateSubKey(IN HANDLE KeyHandle, + IN ULONG Index, + IN ULONG Length, + OUT LPWSTR Buffer) +{ + PKEY_BASIC_INFORMATION KeyInfo = NULL; + ULONG BufferLength = 0; + ULONG ReturnedLength; + NTSTATUS Status; + + /* Check if we have a name */ + if (Length) + { + /* Allocate a buffer for it */ + BufferLength = sizeof(KEY_BASIC_INFORMATION) + Length * sizeof(WCHAR); + + KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); + if (KeyInfo == NULL) + return STATUS_NO_MEMORY; + } + + /* Enumerate the key */ + Status = ZwEnumerateKey(KeyHandle, + Index, + KeyBasicInformation, + KeyInfo, + BufferLength, + &ReturnedLength); + if (NT_SUCCESS(Status)) + { + /* Check if the name fits */ + if (KeyInfo->NameLength < (Length * sizeof(WCHAR))) + { + /* Copy it */ + RtlMoveMemory(Buffer, + KeyInfo->Name, + KeyInfo->NameLength); + + /* Terminate the string */ + Buffer[KeyInfo->NameLength / sizeof(WCHAR)] = 0; + } + else + { + /* Otherwise, we ran out of buffer space */ + Status = STATUS_BUFFER_OVERFLOW; + } + } + + /* Free the buffer and return status */ + if (KeyInfo) + RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo); + + return Status; +} + + +NTSTATUS +NTAPI +SampRegOpenKey(IN HANDLE ParentKeyHandle, + IN LPCWSTR KeyName, + IN ACCESS_MASK DesiredAccess, + OUT HANDLE KeyHandle) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + + RtlInitUnicodeString(&Name, KeyName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + ParentKeyHandle, + NULL); + + return NtOpenKey(KeyHandle, + DesiredAccess, + &ObjectAttributes); +} + + +NTSTATUS +SampRegSetValue(HANDLE KeyHandle, + LPWSTR ValueName, + ULONG Type, + LPVOID Data, + ULONG DataLength) +{ + UNICODE_STRING Name; + + RtlInitUnicodeString(&Name, + ValueName); + + return ZwSetValueKey(KeyHandle, + &Name, + 0, + Type, + Data, + DataLength); +} + + +NTSTATUS +SampRegQueryValue(HANDLE KeyHandle, + LPWSTR ValueName, + PULONG Type OPTIONAL, + LPVOID Data OPTIONAL, + PULONG DataLength OPTIONAL) +{ + PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; + UNICODE_STRING Name; + ULONG BufferLength = 0; + NTSTATUS Status; + + RtlInitUnicodeString(&Name, + ValueName); + + if (DataLength != NULL) + BufferLength = *DataLength; + + 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(KeyHandle, + &Name, + KeyValuePartialInformation, + ValueInfo, + BufferLength, + &BufferLength); + if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) + { + if (Type != NULL) + *Type = ValueInfo->Type; + + if (DataLength != NULL) + *DataLength = ValueInfo->DataLength; + } + + /* Check if the caller wanted data back, and we got it */ + if ((NT_SUCCESS(Status)) && (Data != NULL)) + { + /* Copy it */ + RtlMoveMemory(Data, + ValueInfo->Data, + ValueInfo->DataLength); + } + + /* Free the memory and return status */ + RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); + + return Status; +} diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index dd4b6de0959..2452de3447d 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -161,8 +161,106 @@ SamrLookupDomainInSamServer(IN SAMPR_HANDLE ServerHandle, IN PRPC_UNICODE_STRING Name, OUT PRPC_SID *DomainId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT ServerObject; + HANDLE DomainsKeyHandle = NULL; + HANDLE DomainKeyHandle = NULL; + WCHAR DomainKeyName[64]; + ULONG Index; + WCHAR DomainNameString[MAX_COMPUTERNAME_LENGTH + 1]; + UNICODE_STRING DomainName; + ULONG Length; + BOOL Found = FALSE; + NTSTATUS Status; + + TRACE("SamrLookupDomainInSamServer(%p %p %p)\n", + ServerHandle, Name, DomainId); + + /* Validate the server handle */ + Status = SampValidateDbObject(ServerHandle, + SamDbServerObject, + SAM_SERVER_LOOKUP_DOMAIN, + &ServerObject); + if (!NT_SUCCESS(Status)) + return Status; + + *DomainId = NULL; + + Status = SampRegOpenKey(ServerObject->KeyHandle, + L"Domains", + KEY_READ, + &DomainsKeyHandle); + if (!NT_SUCCESS(Status)) + return Status; + + Index = 0; + while (Found == FALSE) + { + Status = SampRegEnumerateSubKey(DomainsKeyHandle, + Index, + 64, + DomainKeyName); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_NO_SUCH_DOMAIN; + break; + } + + TRACE("Domain key name: %S\n", DomainKeyName); + + Status = SampRegOpenKey(DomainsKeyHandle, + DomainKeyName, + KEY_READ, + &DomainKeyHandle); + if (NT_SUCCESS(Status)) + { + Length = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR); + Status = SampRegQueryValue(DomainKeyHandle, + L"Name", + NULL, + (PVOID)&DomainNameString, + &Length); + if (NT_SUCCESS(Status)) + { + TRACE("Domain name: %S\n", DomainNameString); + + RtlInitUnicodeString(&DomainName, + DomainNameString); + if (RtlEqualUnicodeString(&DomainName, (PUNICODE_STRING)Name, TRUE)) + { + TRACE("Found it!\n"); + Found = TRUE; + + Status = SampRegQueryValue(DomainKeyHandle, + L"SID", + NULL, + NULL, + &Length); + if (NT_SUCCESS(Status)) + { + *DomainId = midl_user_allocate(Length); + + SampRegQueryValue(DomainKeyHandle, + L"SID", + NULL, + (PVOID)*DomainId, + &Length); + + Status = STATUS_SUCCESS; + break; + } + } + } + + NtClose(DomainKeyHandle); + } + + Index++; + } + + NtClose(DomainsKeyHandle); + + return Status; } /* Function 6 */ diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index 9c4037f78a6..1b0def3e349 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -103,6 +103,35 @@ SampGetObjectAttribute(PSAM_DB_OBJECT DbObject, LPVOID AttributeData, PULONG AttributeSize); +/* registry.h */ +NTSTATUS +NTAPI +SampRegEnumerateSubKey(IN HANDLE KeyHandle, + IN ULONG Index, + IN ULONG Length, + OUT LPWSTR Buffer); + +NTSTATUS +NTAPI +SampRegOpenKey(IN HANDLE ParentKeyHandle, + IN LPCWSTR KeyName, + IN ACCESS_MASK DesiredAccess, + OUT HANDLE KeyHandle); + +NTSTATUS +SampRegQueryValue(IN HANDLE KeyHandle, + IN LPWSTR ValueName, + OUT PULONG Type OPTIONAL, + OUT LPVOID Data OPTIONAL, + IN OUT PULONG DataLength OPTIONAL); + +NTSTATUS +SampRegSetValue(IN HANDLE KeyHandle, + IN LPWSTR ValueName, + IN ULONG Type, + IN LPVOID Data, + IN ULONG DataLength); + /* samspc.c */ VOID SampStartRpcServer(VOID); diff --git a/reactos/dll/win32/samsrv/setup.c b/reactos/dll/win32/samsrv/setup.c index cc62d1533d1..ec46a032daa 100644 --- a/reactos/dll/win32/samsrv/setup.c +++ b/reactos/dll/win32/samsrv/setup.c @@ -112,6 +112,7 @@ SampCreateUserAccount(HKEY hDomainKey, static BOOL SampCreateDomain(IN HKEY hDomainsKey, + IN LPCWSTR lpKeyName, IN LPCWSTR lpDomainName, IN PSID lpDomainSid, OUT PHKEY lpDomainKey) @@ -127,7 +128,7 @@ SampCreateDomain(IN HKEY hDomainsKey, *lpDomainKey = NULL; if (RegCreateKeyExW(hDomainsKey, - lpDomainName, + lpKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, @@ -139,6 +140,13 @@ SampCreateDomain(IN HKEY hDomainsKey, if (lpDomainSid != NULL) { + RegSetValueEx(hDomainKey, + L"Name", + 0, + REG_SZ, + (LPVOID)lpDomainName, + (wcslen(lpDomainName) + 1) * sizeof(WCHAR)); + RegSetValueEx(hDomainKey, L"SID", 0, @@ -331,6 +339,7 @@ SampInitializeSAM(VOID) /* Create the Builtin domain */ if (SampCreateDomain(hDomainsKey, + L"Builtin", L"Builtin", pBuiltinSid, &hDomainKey)) @@ -342,7 +351,8 @@ SampInitializeSAM(VOID) /* Create the Account domain */ if (SampCreateDomain(hDomainsKey, L"Account", - AccountDomainInfo->DomainSid, //NULL, + L"", + AccountDomainInfo->DomainSid, &hDomainKey)) { SampCreateUserAccount(hDomainKey, diff --git a/reactos/include/ddk/ntsam.h b/reactos/include/ddk/ntsam.h index b1e7dc4818d..8c38fc99a1f 100644 --- a/reactos/include/ddk/ntsam.h +++ b/reactos/include/ddk/ntsam.h @@ -98,6 +98,16 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle, OUT PSAM_HANDLE UserHandle, OUT PULONG RelativeId); +NTSTATUS +NTAPI +SamFreeMemory(IN PVOID Buffer); + +NTSTATUS +NTAPI +SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, + IN PUNICODE_STRING Name, + OUT PSID *DomainId); + NTSTATUS NTAPI SamOpenDomain(IN SAM_HANDLE ServerHandle,