Author: ekohl
Date: Thu Jun 7 10:31:17 2012
New Revision: 56704
URL:
http://svn.reactos.org/svn/reactos?rev=56704&view=rev
Log:
[SAMLIB][SAMSRV]
- Implement SamGetMembersInAlias and SamrGetMembersInAlias.
- Add registry helper routines SampRegQueryKeyInfo, SampRegEnumerateValue and
SampRegSetValue.
- Remove unused SAM database code.
- Store the name and members key (only for aliases and groups) in the database 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/registry.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] Thu Jun 7 10:31:17 2012
@@ -303,6 +303,48 @@
NTSTATUS
NTAPI
+SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
+ OUT PSID **MemberIds,
+ OUT PULONG MemberCount)
+{
+ SAMPR_PSID_ARRAY_OUT SidArray;
+ NTSTATUS Status;
+
+ TRACE("SamGetMembersInAlias(%p %p %p)\n",
+ AliasHandle, MemberIds, MemberCount);
+
+ if ((MemberIds == NULL) ||
+ (MemberCount == NULL))
+ return STATUS_INVALID_PARAMETER;
+
+ *MemberIds = NULL;
+ *MemberCount = 0;
+
+ SidArray.Sids = NULL;
+
+ RpcTryExcept
+ {
+ Status = SamrGetMembersInAlias((SAMPR_HANDLE)AliasHandle,
+ &SidArray);
+ if (NT_SUCCESS(Status))
+ {
+ *MemberCount = SidArray.Count;
+ *MemberIds = (PSID *)(SidArray.Sids);
+ }
+
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
IN PUNICODE_STRING Name,
OUT 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] Thu Jun 7 10:31:17 2012
@@ -23,7 +23,7 @@
@ stub SamGetCompatibilityMode
@ stub SamGetDisplayEnumerationIndex
@ stub SamGetGroupsForUser
-@ stub SamGetMembersInAlias
+@ stdcall SamGetMembersInAlias(ptr ptr ptr)
@ stub SamGetMembersInGroup
@ stdcall SamLookupDomainInSamServer(ptr ptr ptr)
@ stub SamLookupIdsInDomain
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] Thu Jun 7 10:31:17 2012
@@ -44,210 +44,6 @@
return Status;
}
-#if 0
-static BOOLEAN
-LsapIsDatabaseInstalled(VOID)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- HANDLE KeyHandle;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&KeyName,
- L"Policy");
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- SecurityKeyHandle,
- NULL);
-
- Status = RtlpNtOpenKey(&KeyHandle,
- KEY_READ,
- &ObjectAttributes,
- 0);
- if (!NT_SUCCESS(Status))
- return FALSE;
-
- NtClose(KeyHandle);
-
- return TRUE;
-}
-
-
-static NTSTATUS
-LsapCreateDatabaseKeys(VOID)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- HANDLE PolicyKeyHandle = NULL;
- HANDLE AccountsKeyHandle = NULL;
- HANDLE DomainsKeyHandle = NULL;
- HANDLE SecretsKeyHandle = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
-
- TRACE("LsapInstallDatabase()\n");
-
- /* Create the 'Policy' key */
- RtlInitUnicodeString(&KeyName,
- L"Policy");
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- SecurityKeyHandle,
- NULL);
-
- Status = NtCreateKey(&PolicyKeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- 0,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Failed to create the 'Policy' key (Status: 0x%08lx)\n",
Status);
- goto Done;
- }
-
- /* Create the 'Accounts' key */
- RtlInitUnicodeString(&KeyName,
- L"Accounts");
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- PolicyKeyHandle,
- NULL);
-
- Status = NtCreateKey(&AccountsKeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- 0,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Failed to create the 'Accounts' key (Status: 0x%08lx)\n",
Status);
- goto Done;
- }
-
- /* Create the 'Domains' key */
- RtlInitUnicodeString(&KeyName,
- L"Domains");
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- PolicyKeyHandle,
- NULL);
-
- Status = NtCreateKey(&DomainsKeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- 0,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Failed to create the 'Domains' key (Status: 0x%08lx)\n",
Status);
- goto Done;
- }
-
- /* Create the 'Secrets' key */
- RtlInitUnicodeString(&KeyName,
- L"Secrets");
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- PolicyKeyHandle,
- NULL);
-
- Status = NtCreateKey(&SecretsKeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- 0,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Failed to create the 'Secrets' key (Status: 0x%08lx)\n",
Status);
- goto Done;
- }
-
-Done:
- if (SecretsKeyHandle != NULL)
- NtClose(SecretsKeyHandle);
-
- if (DomainsKeyHandle != NULL)
- NtClose(DomainsKeyHandle);
-
- if (AccountsKeyHandle != NULL)
- NtClose(AccountsKeyHandle);
-
- if (PolicyKeyHandle != NULL)
- NtClose(PolicyKeyHandle);
-
- TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status);
-
- return Status;
-}
-
-
-static NTSTATUS
-LsapCreateDatabaseObjects(VOID)
-{
- PLSA_DB_OBJECT PolicyObject;
- NTSTATUS Status;
-
- /* Open the 'Policy' object */
- Status = LsapOpenDbObject(NULL,
- L"Policy",
- LsaDbPolicyObject,
- 0,
- &PolicyObject);
- if (!NT_SUCCESS(Status))
- return Status;
-
- LsapSetObjectAttribute(PolicyObject,
- L"PolPrDmN",
- NULL,
- 0);
-
- LsapSetObjectAttribute(PolicyObject,
- L"PolPrDmS",
- NULL,
- 0);
-
- LsapSetObjectAttribute(PolicyObject,
- L"PolAcDmN",
- NULL,
- 0);
-
- LsapSetObjectAttribute(PolicyObject,
- L"PolAcDmS",
- NULL,
- 0);
-
- /* Close the 'Policy' object */
- LsapCloseDbObject(PolicyObject);
-
- return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-LsapUpdateDatabase(VOID)
-{
- return STATUS_SUCCESS;
-}
-#endif
-
NTSTATUS
SampInitDatabase(VOID)
@@ -310,7 +106,8 @@
UNICODE_STRING KeyName;
HANDLE ParentKeyHandle;
HANDLE ContainerKeyHandle = NULL;
- HANDLE ObjectKeyHandle;
+ HANDLE ObjectKeyHandle = NULL;
+ HANDLE MembersKeyHandle = NULL;
NTSTATUS Status;
if (DbObject == NULL)
@@ -359,6 +156,28 @@
0,
NULL);
+ if ((ObjectType == SamDbAliasObject) ||
+ (ObjectType == SamDbGroupObject))
+ {
+ /* Open the object key */
+ RtlInitUnicodeString(&KeyName,
+ L"Members");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ ContainerKeyHandle,
+ NULL);
+
+ Status = NtCreateKey(&MembersKeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ }
+
NtClose(ContainerKeyHandle);
if (!NT_SUCCESS(Status))
@@ -395,15 +214,32 @@
sizeof(SAM_DB_OBJECT));
if (NewObject == NULL)
{
+ if (MembersKeyHandle != NULL)
+ NtClose(MembersKeyHandle);
NtClose(ObjectKeyHandle);
return STATUS_NO_MEMORY;
}
+
+ NewObject->Name = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ (wcslen(ObjectName) + 1) * sizeof(WCHAR));
+ if (NewObject == NULL)
+ {
+ if (MembersKeyHandle != NULL)
+ NtClose(MembersKeyHandle);
+ NtClose(ObjectKeyHandle);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NewObject);
+ return STATUS_NO_MEMORY;
+ }
+
+ wcscpy(NewObject->Name, ObjectName);
NewObject->Signature = SAMP_DB_SIGNATURE;
NewObject->RefCount = 1;
NewObject->ObjectType = ObjectType;
NewObject->Access = DesiredAccess;
NewObject->KeyHandle = ObjectKeyHandle;
+ NewObject->MembersKeyHandle = MembersKeyHandle;
NewObject->ParentObject = ParentObject;
if (ParentObject != NULL)
@@ -428,7 +264,8 @@
UNICODE_STRING KeyName;
HANDLE ParentKeyHandle;
HANDLE ContainerKeyHandle = NULL;
- HANDLE ObjectKeyHandle;
+ HANDLE ObjectKeyHandle = NULL;
+ HANDLE MembersKeyHandle = NULL;
NTSTATUS Status;
if (DbObject == NULL)
@@ -473,6 +310,28 @@
KEY_ALL_ACCESS,
&ObjectAttributes);
+ if ((ObjectType == SamDbAliasObject) ||
+ (ObjectType == SamDbGroupObject))
+ {
+ /* Open the object key */
+ RtlInitUnicodeString(&KeyName,
+ L"Members");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ ContainerKeyHandle,
+ NULL);
+
+ Status = NtCreateKey(&MembersKeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ }
+
NtClose(ContainerKeyHandle);
if (!NT_SUCCESS(Status))
@@ -506,15 +365,31 @@
sizeof(SAM_DB_OBJECT));
if (NewObject == NULL)
{
+ if (MembersKeyHandle != NULL)
+ NtClose(MembersKeyHandle);
NtClose(ObjectKeyHandle);
return STATUS_NO_MEMORY;
}
+ NewObject->Name = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ (wcslen(ObjectName) + 1) * sizeof(WCHAR));
+ if (NewObject == NULL)
+ {
+ if (MembersKeyHandle != NULL)
+ NtClose(MembersKeyHandle);
+ NtClose(ObjectKeyHandle);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NewObject);
+ return STATUS_NO_MEMORY;
+ }
+
+ wcscpy(NewObject->Name, ObjectName);
NewObject->Signature = SAMP_DB_SIGNATURE;
NewObject->RefCount = 1;
NewObject->ObjectType = ObjectType;
NewObject->Access = DesiredAccess;
NewObject->KeyHandle = ObjectKeyHandle;
+ NewObject->MembersKeyHandle = MembersKeyHandle;
NewObject->ParentObject = ParentObject;
if (ParentObject != NULL)
@@ -585,8 +460,14 @@
if (DbObject->KeyHandle != NULL)
NtClose(DbObject->KeyHandle);
+ if (DbObject->MembersKeyHandle != NULL)
+ NtClose(DbObject->MembersKeyHandle);
+
if (DbObject->ParentObject != NULL)
ParentObject = DbObject->ParentObject;
+
+ if (DbObject->Name != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject->Name);
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
Modified: trunk/reactos/dll/win32/samsrv/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/registry.…
==============================================================================
--- trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] Thu Jun 7 10:31:17 2012
@@ -15,6 +15,14 @@
/* FUNCTIONS ***************************************************************/
+static
+BOOLEAN
+IsStringType(ULONG Type)
+{
+ return (Type == REG_SZ) || (Type == REG_EXPAND_SZ) || (Type == REG_MULTI_SZ);
+}
+
+
NTSTATUS
SampRegCloseKey(IN HANDLE KeyHandle)
{
@@ -132,32 +140,148 @@
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)
+SampRegQueryKeyInfo(IN HANDLE KeyHandle,
+ OUT PULONG SubKeyCount,
+ OUT PULONG ValueCount)
+{
+ KEY_FULL_INFORMATION FullInfoBuffer;
+ ULONG Length;
+ NTSTATUS Status;
+
+ FullInfoBuffer.ClassLength = 0;
+ FullInfoBuffer.ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+
+ Status = NtQueryKey(KeyHandle,
+ KeyFullInformation,
+ &FullInfoBuffer,
+ sizeof(KEY_FULL_INFORMATION),
+ &Length);
+ TRACE("NtQueryKey() returned status 0x%08lX\n", Status);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (SubKeyCount != NULL)
+ *SubKeyCount = FullInfoBuffer.SubKeys;
+
+ if (ValueCount != NULL)
+ *ValueCount = FullInfoBuffer.Values;
+
+ return Status;
+}
+
+
+NTSTATUS
+SampRegEnumerateValue(IN HANDLE KeyHandle,
+ IN ULONG Index,
+ OUT LPWSTR Name,
+ IN OUT PULONG NameLength,
+ OUT PULONG Type OPTIONAL,
+ OUT PVOID Data OPTIONAL,
+ IN OUT PULONG DataLength OPTIONAL)
+{
+ PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL;
+ ULONG BufferLength = 0;
+ ULONG ReturnedLength;
+ NTSTATUS Status;
+
+ TRACE("Index: %lu\n", Index);
+
+ /* Calculate the required buffer length */
+ BufferLength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name);
+ BufferLength += (MAX_PATH + 1) * sizeof(WCHAR);
+ if (Data != NULL)
+ BufferLength += *DataLength;
+
+ /* Allocate the value buffer */
+ ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
+ if (ValueInfo == NULL)
+ return STATUS_NO_MEMORY;
+
+ /* Enumerate the value*/
+ Status = ZwEnumerateValueKey(KeyHandle,
+ Index,
+ KeyValueFullInformation,
+ ValueInfo,
+ BufferLength,
+ &ReturnedLength);
+ if (NT_SUCCESS(Status))
+ {
+ if (Name != NULL)
+ {
+ /* Check if the name fits */
+ if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR)))
+ {
+ /* Copy it */
+ RtlMoveMemory(Name,
+ ValueInfo->Name,
+ ValueInfo->NameLength);
+
+ /* Terminate the string */
+ Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0;
+ }
+ else
+ {
+ /* Otherwise, we ran out of buffer space */
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto done;
+ }
+ }
+
+ if (Data != NULL)
+ {
+ /* Check if the data fits */
+ if (ValueInfo->DataLength <= *DataLength)
+ {
+ /* Copy it */
+ RtlMoveMemory(Data,
+ (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
+ ValueInfo->DataLength);
+
+ /* if the type is REG_SZ and data is not 0-terminated
+ * and there is enough space in the buffer NT appends a \0 */
+ if (IsStringType(ValueInfo->Type) &&
+ ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
+ {
+ WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
+ if ((ptr > (WCHAR *)Data) && ptr[-1])
+ *ptr = 0;
+ }
+ }
+ else
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ goto done;
+ }
+ }
+ }
+
+done:
+ if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
+ {
+ if (Type != NULL)
+ *Type = ValueInfo->Type;
+
+ if (NameLength != NULL)
+ *NameLength = ValueInfo->NameLength;
+
+ if (DataLength != NULL)
+ *DataLength = ValueInfo->DataLength;
+ }
+
+ /* Free the buffer and return status */
+ if (ValueInfo)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
+
+ return Status;
+}
+
+
+NTSTATUS
+SampRegQueryValue(IN HANDLE KeyHandle,
+ IN LPWSTR ValueName,
+ OUT PULONG Type OPTIONAL,
+ OUT PVOID Data OPTIONAL,
+ IN OUT PULONG DataLength OPTIONAL)
{
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
UNICODE_STRING Name;
@@ -200,6 +324,16 @@
RtlMoveMemory(Data,
ValueInfo->Data,
ValueInfo->DataLength);
+
+ /* if the type is REG_SZ and data is not 0-terminated
+ * and there is enough space in the buffer NT appends a \0 */
+ if (IsStringType(ValueInfo->Type) &&
+ ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
+ {
+ WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
+ if ((ptr > (WCHAR *)Data) && ptr[-1])
+ *ptr = 0;
+ }
}
/* Free the memory and return status */
@@ -210,3 +344,24 @@
return Status;
}
+
+
+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);
+}
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] Thu Jun 7 10:31:17 2012
@@ -1186,6 +1186,8 @@
PSAM_DB_OBJECT AliasObject;
LPWSTR MemberIdString = NULL;
HANDLE MembersKeyHandle = NULL;
+ HANDLE MemberKeyHandle = NULL;
+ ULONG MemberIdLength;
NTSTATUS Status;
TRACE("SamrAddMemberToAlias(%p %p)\n",
@@ -1205,6 +1207,8 @@
ConvertSidToStringSidW(MemberId, &MemberIdString);
TRACE("Member SID: %S\n", MemberIdString);
+ MemberIdLength = RtlLengthSid(MemberId);
+
Status = SampRegCreateKey(AliasObject->KeyHandle,
L"Members",
KEY_WRITE,
@@ -1218,10 +1222,39 @@
Status = SampRegSetValue(MembersKeyHandle,
MemberIdString,
REG_BINARY,
- NULL,
- 0);
+ MemberId,
+ MemberIdLength);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRegSetValue failed with status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ Status = SampRegCreateKey(AliasObject->MembersKeyHandle,
+ MemberIdString,
+ KEY_WRITE,
+ &MemberKeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ Status = SampRegSetValue(MemberKeyHandle,
+ AliasObject->Name,
+ REG_BINARY,
+ MemberId,
+ MemberIdLength);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRegSetValue failed with status 0x%08lx\n", Status);
+ goto done;
+ }
done:
+ if (MemberKeyHandle != NULL)
+ SampRegCloseKey(MemberKeyHandle);
+
if (MembersKeyHandle != NULL)
SampRegCloseKey(MembersKeyHandle);
@@ -1247,8 +1280,129 @@
SamrGetMembersInAlias(IN SAMPR_HANDLE AliasHandle,
OUT PSAMPR_PSID_ARRAY_OUT Members)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PSAM_DB_OBJECT AliasObject;
+ HANDLE MembersKeyHandle = NULL;
+ PSAMPR_SID_INFORMATION MemberArray = NULL;
+ ULONG ValueCount = 0;
+ ULONG DataLength;
+ ULONG Index;
+ NTSTATUS Status;
+
+ TRACE("SamrGetMembersInAlias(%p %p %p)\n",
+ AliasHandle, Members);
+
+ /* Validate the alias handle */
+ Status = SampValidateDbObject(AliasHandle,
+ SamDbAliasObject,
+ ALIAS_LIST_MEMBERS,
+ &AliasObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* Open the members key of the alias objct */
+ Status = SampRegOpenKey(AliasObject->KeyHandle,
+ L"Members",
+ KEY_READ,
+ &MembersKeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SampRegOpenKey failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* Get the number of members */
+ Status = SampRegQueryKeyInfo(MembersKeyHandle,
+ NULL,
+ &ValueCount);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ /* Allocate the member array */
+ MemberArray = midl_user_allocate(ValueCount * sizeof(SAMPR_SID_INFORMATION));
+ if (MemberArray == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ /* Enumerate the members */
+ Index = 0;
+ while (TRUE)
+ {
+ /* Get the size of the next SID */
+ DataLength = 0;
+ Status = SampRegEnumerateValue(MembersKeyHandle,
+ Index,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &DataLength);
+ if (!NT_SUCCESS(Status))
+ {
+ if (Status == STATUS_NO_MORE_ENTRIES)
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ /* Allocate a buffer for the SID */
+ MemberArray[Index].SidPointer = midl_user_allocate(DataLength);
+ if (MemberArray[Index].SidPointer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ /* Read the SID into the buffer */
+ Status = SampRegEnumerateValue(MembersKeyHandle,
+ Index,
+ NULL,
+ NULL,
+ NULL,
+ (PVOID)MemberArray[Index].SidPointer,
+ &DataLength);
+ if (!NT_SUCCESS(Status))
+ {
+ goto done;
+ }
+
+ Index++;
+ }
+
+ /* Return the number of members and the member array */
+ if (NT_SUCCESS(Status))
+ {
+ Members->Count = ValueCount;
+ Members->Sids = MemberArray;
+ }
+
+done:
+ /* Clean up the members array and the SID buffers if something failed */
+ if (!NT_SUCCESS(Status))
+ {
+ if (MemberArray != NULL)
+ {
+ for (Index = 0; Index < ValueCount; Index++)
+ {
+ if (MemberArray[Index].SidPointer != NULL)
+ midl_user_free(MemberArray[Index].SidPointer);
+ }
+
+ midl_user_free(MemberArray);
+ }
+ }
+
+ /* Close the members key */
+ if (MembersKeyHandle != NULL)
+ SampRegCloseKey(MembersKeyHandle);
+
+ return Status;
}
/* Function 34 */
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] Thu Jun 7 10:31:17 2012
@@ -42,7 +42,9 @@
SAM_DB_OBJECT_TYPE ObjectType;
ULONG RefCount;
ACCESS_MASK Access;
+ LPWSTR Name;
HANDLE KeyHandle;
+ HANDLE MembersKeyHandle; // only used by Aliases and Groups
struct _SAM_DB_OBJECT *ParentObject;
} SAM_DB_OBJECT, *PSAM_DB_OBJECT;
@@ -127,6 +129,20 @@
OUT HANDLE KeyHandle);
NTSTATUS
+SampRegQueryKeyInfo(IN HANDLE KeyHandle,
+ OUT PULONG SubKeyCount,
+ OUT PULONG ValueCount);
+
+NTSTATUS
+SampRegEnumerateValue(IN HANDLE KeyHandle,
+ IN ULONG Index,
+ OUT LPWSTR Name,
+ IN OUT PULONG NameLength,
+ OUT PULONG Type OPTIONAL,
+ OUT PVOID Data OPTIONAL,
+ IN OUT PULONG DataLength OPTIONAL);
+
+NTSTATUS
SampRegQueryValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName,
OUT PULONG Type OPTIONAL,
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] Thu Jun 7 10:31:17 2012
@@ -166,6 +166,12 @@
NTSTATUS
NTAPI
+SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
+ OUT PSID **MemberIds,
+ OUT PULONG MemberCount);
+
+NTSTATUS
+NTAPI
SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
IN PUNICODE_STRING Name,
OUT PSID *DomainId);