Author: ekohl Date: Thu Aug 2 20:09:24 2012 New Revision: 57029
URL: http://svn.reactos.org/svn/reactos?rev=57029&view=rev Log: [SAMLIB/SAMSRV] - Implement SamEnumerateGroupsInDomain and SamEnumerateUsersInDomain (ignore UserAccountControl). - Simplify SamrEnumerateAliasesInDomain.
Modified: trunk/reactos/dll/win32/samlib/samlib.c trunk/reactos/dll/win32/samlib/samlib.spec trunk/reactos/dll/win32/samsrv/samrpc.c 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?r... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] Thu Aug 2 20:09:24 2012 @@ -159,7 +159,7 @@ { NTSTATUS Status;
- TRACE("SamConnect(%p,%p,0x%08x,%p)\n", + TRACE("SamConnect(%p %p 0x%08x %p)\n", ServerName, ServerHandle, DesiredAccess, ObjectAttributes);
RpcTryExcept @@ -188,7 +188,7 @@ { NTSTATUS Status;
- TRACE("SamCreateAliasInDomain(%p,%p,0x%08x,%p,%p)\n", + TRACE("SamCreateAliasInDomain(%p %p 0x%08x %p %p)\n", DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
RpcTryExcept @@ -219,7 +219,7 @@ { NTSTATUS Status;
- TRACE("SamCreateGroupInDomain(%p,%p,0x%08x,%p,%p)\n", + TRACE("SamCreateGroupInDomain(%p %p 0x%08x %p %p)\n", DomainHandle, AccountName, DesiredAccess, GroupHandle, RelativeId);
RpcTryExcept @@ -250,7 +250,7 @@ { NTSTATUS Status;
- TRACE("SamCreateUserInDomain(%p,%p,0x%08x,%p,%p)\n", + TRACE("SamCreateUserInDomain(%p %p 0x%08x %p %p)\n", DomainHandle, AccountName, DesiredAccess, UserHandle, RelativeId);
RpcTryExcept @@ -282,7 +282,7 @@ PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; NTSTATUS Status;
- TRACE("SamEnumerateAliasesInDomain(%p,%p,%p,%lu,%p)\n", + TRACE("SamEnumerateAliasesInDomain(%p %p %p %lu %p)\n", DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength, CountReturned);
@@ -332,7 +332,7 @@ PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; NTSTATUS Status;
- TRACE("SamEnumerateDomainsInSamServer(%p,%p,%p,%lu,%p)\n", + TRACE("SamEnumerateDomainsInSamServer(%p %p %p %lu %p)\n", ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength, CountReturned);
@@ -360,6 +360,101 @@
midl_user_free(EnumBuffer); } + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + +NTSTATUS +NTAPI +SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + IN PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned) +{ + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + NTSTATUS Status; + + TRACE("SamEnumerateGroupsInDomain(%p %p %p %lu %p)\n", + DomainHandle, EnumerationContext, Buffer, + PreferedMaximumLength, CountReturned); + + if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL) + return STATUS_INVALID_PARAMETER; + + *Buffer = NULL; + + RpcTryExcept + { + Status = SamrEnumerateGroupsInDomain((SAMPR_HANDLE)DomainHandle, + EnumerationContext, + (PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer, + PreferedMaximumLength, + CountReturned); + if (EnumBuffer != NULL) + { + if (EnumBuffer->Buffer != NULL) + *Buffer = EnumBuffer->Buffer; + + midl_user_free(EnumBuffer); + } + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + +NTSTATUS +NTAPI +SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + IN ULONG UserAccountControl, + OUT PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned) +{ + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + NTSTATUS Status; + + TRACE("SamEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n", + DomainHandle, EnumerationContext, UserAccountControl, Buffer, + PreferedMaximumLength, CountReturned); + + if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL) + return STATUS_INVALID_PARAMETER; + + *Buffer = NULL; + + RpcTryExcept + { + Status = SamrEnumerateUsersInDomain((SAMPR_HANDLE)DomainHandle, + EnumerationContext, + UserAccountControl, + (PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer, + PreferedMaximumLength, + CountReturned); + if (EnumBuffer != NULL) + { + if (EnumBuffer->Buffer != NULL) + { + *Buffer = EnumBuffer->Buffer; + } + + midl_user_free(EnumBuffer); + } + } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -483,7 +578,7 @@ { NTSTATUS Status;
- TRACE("SamLookupDomainInSamServer(%p,%p,%p)\n", + TRACE("SamLookupDomainInSamServer(%p %p %p)\n", ServerHandle, Name, DomainId);
RpcTryExcept @@ -553,7 +648,7 @@ { NTSTATUS Status;
- TRACE("SamOpenDomain(%p,0x%08x,%p,%p)\n", + TRACE("SamOpenDomain(%p 0x%08x %p %p)\n", ServerHandle, DesiredAccess, DomainId, DomainHandle);
RpcTryExcept @@ -582,7 +677,7 @@ { NTSTATUS Status;
- TRACE("SamOpenGroup(%p,0x%08x,%p,%p)\n", + TRACE("SamOpenGroup(%p 0x%08x %p %p)\n", DomainHandle, DesiredAccess, GroupId, GroupHandle);
RpcTryExcept @@ -611,7 +706,7 @@ { NTSTATUS Status;
- TRACE("SamOpenUser(%p,0x%08x,%lx,%p)\n", + TRACE("SamOpenUser(%p 0x%08x %lx %p)\n", DomainHandle, DesiredAccess, UserId, UserHandle);
RpcTryExcept @@ -770,18 +865,18 @@ NTAPI SamSetInformationDomain(IN SAM_HANDLE DomainHandle, IN DOMAIN_INFORMATION_CLASS DomainInformationClass, - IN PVOID DomainInformation) + IN PVOID Buffer) { NTSTATUS Status;
TRACE("SamSetInformationDomain(%p %lu %p)\n", - DomainHandle, DomainInformationClass, DomainInformation); + DomainHandle, DomainInformationClass, Buffer);
RpcTryExcept { Status = SamrSetInformationDomain((SAMPR_HANDLE)DomainHandle, DomainInformationClass, - DomainInformation); + Buffer); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) {
Modified: trunk/reactos/dll/win32/samlib/samlib.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.spe... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] Thu Aug 2 20:09:24 2012 @@ -16,8 +16,8 @@ @ stub SamDeleteUser @ stdcall SamEnumerateAliasesInDomain(ptr ptr ptr long ptr) @ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr) -@ stub SamEnumerateGroupsInDomain -@ stub SamEnumerateUsersInDomain +@ stdcall SamEnumerateGroupsInDomain(ptr ptr ptr long ptr) +@ stdcall SamEnumerateUsersInDomain(ptr ptr long ptr long ptr) @ stdcall SamFreeMemory(ptr) @ stdcall SamGetAliasMembership(ptr long ptr ptr ptr) @ stub SamGetCompatibilityMode
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Thu Aug 2 20:09:24 2012 @@ -1696,8 +1696,197 @@ IN unsigned long PreferedMaximumLength, OUT unsigned long *CountReturned) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + PSAM_DB_OBJECT DomainObject; + HANDLE GroupsKeyHandle = NULL; + HANDLE NamesKeyHandle = NULL; + WCHAR GroupName[64]; + ULONG EnumIndex; + ULONG EnumCount = 0; + ULONG RequiredLength = 0; + ULONG NameLength; + ULONG DataLength; + ULONG Rid; + ULONG i; + BOOLEAN MoreEntries = FALSE; + NTSTATUS Status; + + TRACE("SamrEnumerateUsersInDomain(%p %p %p %lu %p)\n", + DomainHandle, EnumerationContext, Buffer, + PreferedMaximumLength, CountReturned); + + /* Validate the domain handle */ + Status = SampValidateDbObject(DomainHandle, + SamDbDomainObject, + DOMAIN_LIST_ACCOUNTS, + &DomainObject); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Groups", + KEY_READ, + &GroupsKeyHandle); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegOpenKey(GroupsKeyHandle, + L"Names", + KEY_READ, + &NamesKeyHandle); + if (!NT_SUCCESS(Status)) + goto done; + + TRACE("Part 1\n"); + + EnumIndex = *EnumerationContext; + + while (TRUE) + { + NameLength = 64 * sizeof(WCHAR); + Status = SampRegEnumerateValue(NamesKeyHandle, + EnumIndex, + GroupName, + &NameLength, + NULL, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Group name: %S\n", GroupName); + TRACE("Name length: %lu\n", NameLength); + + if ((RequiredLength + NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength) + { + MoreEntries = TRUE; + break; + } + + RequiredLength += (NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)); + EnumCount++; + + EnumIndex++; + } + + TRACE("EnumCount: %lu\n", EnumCount); + TRACE("RequiredLength: %lu\n", RequiredLength); + + if (!NT_SUCCESS(Status)) + goto done; + + EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER)); + if (EnumBuffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + EnumBuffer->EntriesRead = EnumCount; + if (EnumCount == 0) + goto done; + + EnumBuffer->Buffer = midl_user_allocate(EnumCount * sizeof(SAMPR_RID_ENUMERATION)); + if (EnumBuffer->Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Part 2\n"); + + EnumIndex = *EnumerationContext; + for (i = 0; i < EnumCount; i++, EnumIndex++) + { + NameLength = 64 * sizeof(WCHAR); + DataLength = sizeof(ULONG); + Status = SampRegEnumerateValue(NamesKeyHandle, + EnumIndex, + GroupName, + &NameLength, + NULL, + &Rid, + &DataLength); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Group name: %S\n", GroupName); + TRACE("Name length: %lu\n", NameLength); + TRACE("RID: %lu\n", Rid); + + EnumBuffer->Buffer[i].RelativeId = Rid; + + EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength; + EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL)); + +/* FIXME: Disabled because of bugs in widl and rpcrt4 */ +#if 0 + EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(EnumBuffer->Buffer[i].Name.MaximumLength); + if (EnumBuffer->Buffer[i].Name.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + memcpy(EnumBuffer->Buffer[i].Name.Buffer, + GroupName, + EnumBuffer->Buffer[i].Name.Length); +#endif + } + +done: + if (NT_SUCCESS(Status)) + { + *EnumerationContext += EnumCount; + *Buffer = EnumBuffer; + *CountReturned = EnumCount; + } + else + { + *EnumerationContext = 0; + *Buffer = NULL; + *CountReturned = 0; + + if (EnumBuffer != NULL) + { + if (EnumBuffer->Buffer != NULL) + { + if (EnumBuffer->EntriesRead != 0) + { + for (i = 0; i < EnumBuffer->EntriesRead; i++) + { + if (EnumBuffer->Buffer[i].Name.Buffer != NULL) + midl_user_free(EnumBuffer->Buffer[i].Name.Buffer); + } + } + + midl_user_free(EnumBuffer->Buffer); + } + + midl_user_free(EnumBuffer); + } + } + + if (NamesKeyHandle != NULL) + SampRegCloseKey(NamesKeyHandle); + + if (GroupsKeyHandle != NULL) + SampRegCloseKey(GroupsKeyHandle); + + if ((Status == STATUS_SUCCESS) && (MoreEntries == TRUE)) + Status = STATUS_MORE_ENTRIES; + + return Status; }
@@ -1968,171 +2157,24 @@ IN unsigned long PreferedMaximumLength, OUT unsigned long *CountReturned) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - -/* Function 14 */ -NTSTATUS -NTAPI -SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, - IN PRPC_UNICODE_STRING AccountName, - IN ACCESS_MASK DesiredAccess, - OUT SAMPR_HANDLE *AliasHandle, - OUT unsigned long *RelativeId) -{ - SAM_DOMAIN_FIXED_DATA FixedDomainData; - PSAM_DB_OBJECT DomainObject; - PSAM_DB_OBJECT AliasObject; - UNICODE_STRING EmptyString = RTL_CONSTANT_STRING(L""); - ULONG ulSize; - ULONG ulRid; - WCHAR szRid[9]; - NTSTATUS Status; - - TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n", - DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId); - - /* Validate the domain handle */ - Status = SampValidateDbObject(DomainHandle, - SamDbDomainObject, - DOMAIN_CREATE_ALIAS, - &DomainObject); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - /* Check if the alias name already exists in the domain */ - Status = SampCheckAccountNameInDomain(DomainObject, - AccountName->Buffer); - if (!NT_SUCCESS(Status)) - { - TRACE("Alias name '%S' already exists in domain (Status 0x%08lx)\n", - AccountName->Buffer, Status); - return Status; - } - - /* Get the fixed domain attributes */ - ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); - Status = SampGetObjectAttribute(DomainObject, - L"F", - NULL, - (PVOID)&FixedDomainData, - &ulSize); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - /* Increment the NextRid attribute */ - ulRid = FixedDomainData.NextRid; - FixedDomainData.NextRid++; - - /* Store the fixed domain attributes */ - Status = SampSetObjectAttribute(DomainObject, - L"F", - REG_BINARY, - &FixedDomainData, - ulSize); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - TRACE("RID: %lx\n", ulRid); - - /* Convert the RID into a string (hex) */ - swprintf(szRid, L"%08lX", ulRid); - - /* Create the alias object */ - Status = SampCreateDbObject(DomainObject, - L"Aliases", - szRid, - SamDbAliasObject, - DesiredAccess, - &AliasObject); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - /* Add the account name for the alias object */ - Status = SampSetAccountNameInDomain(DomainObject, - L"Aliases", - AccountName->Buffer, - ulRid); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - /* Set the Name attribute */ - Status = SampSetObjectAttribute(AliasObject, - L"Name", - REG_SZ, - (LPVOID)AccountName->Buffer, - AccountName->MaximumLength); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - /* Set the Description attribute */ - Status = SampSetObjectAttribute(AliasObject, - L"Description", - REG_SZ, - EmptyString.Buffer, - EmptyString.MaximumLength); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - if (NT_SUCCESS(Status)) - { - *AliasHandle = (SAMPR_HANDLE)AliasObject; - *RelativeId = ulRid; - } - - TRACE("returns with status 0x%08lx\n", Status); - - return Status; -} - -/* Function 15 */ -NTSTATUS -NTAPI -SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle, - IN OUT unsigned long *EnumerationContext, - OUT PSAMPR_ENUMERATION_BUFFER *Buffer, - IN unsigned long PreferedMaximumLength, - OUT unsigned long *CountReturned) -{ PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; PSAM_DB_OBJECT DomainObject; - HANDLE AliasesKeyHandle; - WCHAR AliasKeyName[64]; - HANDLE AliasKeyHandle; + HANDLE UsersKeyHandle = NULL; + HANDLE NamesKeyHandle = NULL; + WCHAR UserName[64]; ULONG EnumIndex; - ULONG EnumCount; - ULONG RequiredLength; + ULONG EnumCount = 0; + ULONG RequiredLength = 0; + ULONG NameLength; ULONG DataLength; + ULONG Rid; ULONG i; BOOLEAN MoreEntries = FALSE; NTSTATUS Status;
- TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n", - DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength, - CountReturned); + TRACE("SamrEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n", + DomainHandle, EnumerationContext, UserAccountControl, Buffer, + PreferedMaximumLength, CountReturned);
/* Validate the domain handle */ Status = SampValidateDbObject(DomainHandle, @@ -2143,24 +2185,33 @@ return Status;
Status = SampRegOpenKey(DomainObject->KeyHandle, - L"Aliases", + L"Users", KEY_READ, - &AliasesKeyHandle); - if (!NT_SUCCESS(Status)) - return Status; + &UsersKeyHandle); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegOpenKey(UsersKeyHandle, + L"Names", + KEY_READ, + &NamesKeyHandle); + if (!NT_SUCCESS(Status)) + goto done;
TRACE("Part 1\n");
EnumIndex = *EnumerationContext; - EnumCount = 0; - RequiredLength = 0;
while (TRUE) { - Status = SampRegEnumerateSubKey(AliasesKeyHandle, - EnumIndex, - 64 * sizeof(WCHAR), - AliasKeyName); + NameLength = 64 * sizeof(WCHAR); + Status = SampRegEnumerateValue(NamesKeyHandle, + EnumIndex, + UserName, + &NameLength, + NULL, + NULL, + NULL); if (!NT_SUCCESS(Status)) { if (Status == STATUS_NO_MORE_ENTRIES) @@ -2169,40 +2220,17 @@ }
TRACE("EnumIndex: %lu\n", EnumIndex); - TRACE("Alias key name: %S\n", AliasKeyName); - - Status = SampRegOpenKey(AliasesKeyHandle, - AliasKeyName, - KEY_READ, - &AliasKeyHandle); - TRACE("SampRegOpenKey returned %08lX\n", Status); - if (NT_SUCCESS(Status)) - { - DataLength = 0; - Status = SampRegQueryValue(AliasKeyHandle, - L"Name", - NULL, - NULL, - &DataLength); - - NtClose(AliasKeyHandle); - - TRACE("SampRegQueryValue returned %08lX\n", Status); - - if (NT_SUCCESS(Status)) - { - TRACE("Data length: %lu\n", DataLength); - - if ((RequiredLength + DataLength + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength) - { - MoreEntries = TRUE; - break; - } - - RequiredLength += (DataLength + sizeof(SAMPR_RID_ENUMERATION)); - EnumCount++; - } - } + TRACE("User name: %S\n", UserName); + TRACE("Name length: %lu\n", NameLength); + + if ((RequiredLength + NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength) + { + MoreEntries = TRUE; + break; + } + + RequiredLength += (NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)); + EnumCount++;
EnumIndex++; } @@ -2210,6 +2238,9 @@ TRACE("EnumCount: %lu\n", EnumCount); TRACE("RequiredLength: %lu\n", RequiredLength);
+ if (!NT_SUCCESS(Status)) + goto done; + EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER)); if (EnumBuffer == NULL) { @@ -2233,10 +2264,15 @@ EnumIndex = *EnumerationContext; for (i = 0; i < EnumCount; i++, EnumIndex++) { - Status = SampRegEnumerateSubKey(AliasesKeyHandle, - EnumIndex, - 64 * sizeof(WCHAR), - AliasKeyName); + NameLength = 64 * sizeof(WCHAR); + DataLength = sizeof(ULONG); + Status = SampRegEnumerateValue(NamesKeyHandle, + EnumIndex, + UserName, + &NameLength, + NULL, + &Rid, + &DataLength); if (!NT_SUCCESS(Status)) { if (Status == STATUS_NO_MORE_ENTRIES) @@ -2245,53 +2281,28 @@ }
TRACE("EnumIndex: %lu\n", EnumIndex); - TRACE("Alias key name: %S\n", AliasKeyName); - - Status = SampRegOpenKey(AliasesKeyHandle, - AliasKeyName, - KEY_READ, - &AliasKeyHandle); - TRACE("SampRegOpenKey returned %08lX\n", Status); - if (NT_SUCCESS(Status)) - { - DataLength = 0; - Status = SampRegQueryValue(AliasKeyHandle, - L"Name", - NULL, - NULL, - &DataLength); - TRACE("SampRegQueryValue returned %08lX\n", Status); - if (NT_SUCCESS(Status)) - { - EnumBuffer->Buffer[i].RelativeId = wcstoul(AliasKeyName, NULL, 16); - - EnumBuffer->Buffer[i].Name.Length = (USHORT)DataLength - sizeof(WCHAR); - EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)DataLength; - EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(DataLength); - if (EnumBuffer->Buffer[i].Name.Buffer == NULL) - { - NtClose(AliasKeyHandle); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto done; - } - - Status = SampRegQueryValue(AliasKeyHandle, - L"Name", - NULL, - EnumBuffer->Buffer[i].Name.Buffer, - &DataLength); - TRACE("SampRegQueryValue returned %08lX\n", Status); - if (NT_SUCCESS(Status)) - { - TRACE("Alias name: %S\n", EnumBuffer->Buffer[i].Name.Buffer); - } - } - - NtClose(AliasKeyHandle); - - if (!NT_SUCCESS(Status)) - goto done; - } + TRACE("User name: %S\n", UserName); + TRACE("Name length: %lu\n", NameLength); + TRACE("RID: %lu\n", Rid); + + EnumBuffer->Buffer[i].RelativeId = Rid; + + EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength; + EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL)); + +/* FIXME: Disabled because of bugs in widl and rpcrt4 */ +#if 0 + EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(EnumBuffer->Buffer[i].Name.MaximumLength); + if (EnumBuffer->Buffer[i].Name.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + memcpy(EnumBuffer->Buffer[i].Name.Buffer, + UserName, + EnumBuffer->Buffer[i].Name.Length); +#endif }
done: @@ -2301,8 +2312,7 @@ *Buffer = EnumBuffer; *CountReturned = EnumCount; } - - if (!NT_SUCCESS(Status)) + else { *EnumerationContext = 0; *Buffer = NULL; @@ -2328,13 +2338,357 @@ } }
- NtClose(AliasesKeyHandle); + if (NamesKeyHandle != NULL) + SampRegCloseKey(NamesKeyHandle); + + if (UsersKeyHandle != NULL) + SampRegCloseKey(UsersKeyHandle);
if ((Status == STATUS_SUCCESS) && (MoreEntries == TRUE)) Status = STATUS_MORE_ENTRIES;
return Status; } + + +/* Function 14 */ +NTSTATUS +NTAPI +SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, + IN PRPC_UNICODE_STRING AccountName, + IN ACCESS_MASK DesiredAccess, + OUT SAMPR_HANDLE *AliasHandle, + OUT unsigned long *RelativeId) +{ + SAM_DOMAIN_FIXED_DATA FixedDomainData; + PSAM_DB_OBJECT DomainObject; + PSAM_DB_OBJECT AliasObject; + UNICODE_STRING EmptyString = RTL_CONSTANT_STRING(L""); + ULONG ulSize; + ULONG ulRid; + WCHAR szRid[9]; + NTSTATUS Status; + + TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n", + DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId); + + /* Validate the domain handle */ + Status = SampValidateDbObject(DomainHandle, + SamDbDomainObject, + DOMAIN_CREATE_ALIAS, + &DomainObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + /* Check if the alias name already exists in the domain */ + Status = SampCheckAccountNameInDomain(DomainObject, + AccountName->Buffer); + if (!NT_SUCCESS(Status)) + { + TRACE("Alias name '%S' already exists in domain (Status 0x%08lx)\n", + AccountName->Buffer, Status); + return Status; + } + + /* Get the fixed domain attributes */ + ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedDomainData, + &ulSize); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + /* Increment the NextRid attribute */ + ulRid = FixedDomainData.NextRid; + FixedDomainData.NextRid++; + + /* Store the fixed domain attributes */ + Status = SampSetObjectAttribute(DomainObject, + L"F", + REG_BINARY, + &FixedDomainData, + ulSize); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + TRACE("RID: %lx\n", ulRid); + + /* Convert the RID into a string (hex) */ + swprintf(szRid, L"%08lX", ulRid); + + /* Create the alias object */ + Status = SampCreateDbObject(DomainObject, + L"Aliases", + szRid, + SamDbAliasObject, + DesiredAccess, + &AliasObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + /* Add the account name for the alias object */ + Status = SampSetAccountNameInDomain(DomainObject, + L"Aliases", + AccountName->Buffer, + ulRid); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + /* Set the Name attribute */ + Status = SampSetObjectAttribute(AliasObject, + L"Name", + REG_SZ, + (LPVOID)AccountName->Buffer, + AccountName->MaximumLength); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + /* Set the Description attribute */ + Status = SampSetObjectAttribute(AliasObject, + L"Description", + REG_SZ, + EmptyString.Buffer, + EmptyString.MaximumLength); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + if (NT_SUCCESS(Status)) + { + *AliasHandle = (SAMPR_HANDLE)AliasObject; + *RelativeId = ulRid; + } + + TRACE("returns with status 0x%08lx\n", Status); + + return Status; +} + + +/* Function 15 */ +NTSTATUS +NTAPI +SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle, + IN OUT unsigned long *EnumerationContext, + OUT PSAMPR_ENUMERATION_BUFFER *Buffer, + IN unsigned long PreferedMaximumLength, + OUT unsigned long *CountReturned) +{ + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + PSAM_DB_OBJECT DomainObject; + HANDLE AliasesKeyHandle = NULL; + HANDLE NamesKeyHandle = NULL; + WCHAR AliasName[64]; + ULONG EnumIndex; + ULONG EnumCount = 0; + ULONG RequiredLength = 0; + ULONG NameLength; + ULONG DataLength; + ULONG Rid; + ULONG i; + BOOLEAN MoreEntries = FALSE; + NTSTATUS Status; + + TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n", + DomainHandle, EnumerationContext, Buffer, + PreferedMaximumLength, CountReturned); + + /* Validate the domain handle */ + Status = SampValidateDbObject(DomainHandle, + SamDbDomainObject, + DOMAIN_LIST_ACCOUNTS, + &DomainObject); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Aliases", + KEY_READ, + &AliasesKeyHandle); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegOpenKey(AliasesKeyHandle, + L"Names", + KEY_READ, + &NamesKeyHandle); + if (!NT_SUCCESS(Status)) + goto done; + + TRACE("Part 1\n"); + + EnumIndex = *EnumerationContext; + + while (TRUE) + { + NameLength = 64 * sizeof(WCHAR); + Status = SampRegEnumerateValue(NamesKeyHandle, + EnumIndex, + AliasName, + &NameLength, + NULL, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Alias name: %S\n", AliasName); + TRACE("Name length: %lu\n", NameLength); + + if ((RequiredLength + NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength) + { + MoreEntries = TRUE; + break; + } + + RequiredLength += (NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)); + EnumCount++; + + EnumIndex++; + } + + TRACE("EnumCount: %lu\n", EnumCount); + TRACE("RequiredLength: %lu\n", RequiredLength); + + if (!NT_SUCCESS(Status)) + goto done; + + EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER)); + if (EnumBuffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + EnumBuffer->EntriesRead = EnumCount; + if (EnumCount == 0) + goto done; + + EnumBuffer->Buffer = midl_user_allocate(EnumCount * sizeof(SAMPR_RID_ENUMERATION)); + if (EnumBuffer->Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Part 2\n"); + + EnumIndex = *EnumerationContext; + for (i = 0; i < EnumCount; i++, EnumIndex++) + { + NameLength = 64 * sizeof(WCHAR); + DataLength = sizeof(ULONG); + Status = SampRegEnumerateValue(NamesKeyHandle, + EnumIndex, + AliasName, + &NameLength, + NULL, + &Rid, + &DataLength); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Alias name: %S\n", AliasName); + TRACE("Name length: %lu\n", NameLength); + TRACE("RID: %lu\n", Rid); + + EnumBuffer->Buffer[i].RelativeId = Rid; + + EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength; + EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL)); + +/* FIXME: Disabled because of bugs in widl and rpcrt4 */ +#if 0 + EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(EnumBuffer->Buffer[i].Name.MaximumLength); + if (EnumBuffer->Buffer[i].Name.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + memcpy(EnumBuffer->Buffer[i].Name.Buffer, + AliasName, + EnumBuffer->Buffer[i].Name.Length); +#endif + } + +done: + if (NT_SUCCESS(Status)) + { + *EnumerationContext += EnumCount; + *Buffer = EnumBuffer; + *CountReturned = EnumCount; + } + else + { + *EnumerationContext = 0; + *Buffer = NULL; + *CountReturned = 0; + + if (EnumBuffer != NULL) + { + if (EnumBuffer->Buffer != NULL) + { + if (EnumBuffer->EntriesRead != 0) + { + for (i = 0; i < EnumBuffer->EntriesRead; i++) + { + if (EnumBuffer->Buffer[i].Name.Buffer != NULL) + midl_user_free(EnumBuffer->Buffer[i].Name.Buffer); + } + } + + midl_user_free(EnumBuffer->Buffer); + } + + midl_user_free(EnumBuffer); + } + } + + if (NamesKeyHandle != NULL) + SampRegCloseKey(NamesKeyHandle); + + if (AliasesKeyHandle != NULL) + SampRegCloseKey(AliasesKeyHandle); + + if ((Status == STATUS_SUCCESS) && (MoreEntries == TRUE)) + Status = STATUS_MORE_ENTRIES; + + return Status; +} +
/* Function 16 */ NTSTATUS
Modified: trunk/reactos/include/ddk/ntsam.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=570... ============================================================================== --- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original) +++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Thu Aug 2 20:09:24 2012 @@ -375,6 +375,23 @@
NTSTATUS NTAPI +SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + IN PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned); + +NTSTATUS +NTAPI +SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + IN ULONG UserAccountControl, + OUT PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned); + +NTSTATUS +NTAPI SamFreeMemory(IN PVOID Buffer);
NTSTATUS