Author: ekohl Date: Sun Jun 3 20:54:06 2012 New Revision: 56690
URL: http://svn.reactos.org/svn/reactos?rev=56690&view=rev Log: [SAMLIB]: Implement SamAddMemberToAlias, SamCreateAliasInDomain, SamEnumerateDomainsInSamServer, SamOpenAlias, SamQueryInformationDomain and SamQueryInformationUser. [SAMSRV]: Implement SamrEnumerateDomainsInSamServer (buggy, probably a bug in WIDL), SamrQueryInformationDomain.DomainNameInformation, SamrCreateAliasInDomain, SamrOpenAlias and SamrAddMemberToAlias. [SAMSRV]: Add more registry helper routines. [SAMSRV]: Create builtin aliases upon setup.
Modified: trunk/reactos/dll/win32/samlib/samlib.c trunk/reactos/dll/win32/samlib/samlib.spec trunk/reactos/dll/win32/samsrv/registry.c trunk/reactos/dll/win32/samsrv/samrpc.c trunk/reactos/dll/win32/samsrv/samsrv.h trunk/reactos/dll/win32/samsrv/setup.c trunk/reactos/include/ddk/ntsam.h trunk/reactos/include/reactos/idl/sam.idl
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] Sun Jun 3 20:54:06 2012 @@ -105,6 +105,31 @@
NTSTATUS NTAPI +SamAddMemberToAlias(IN SAM_HANDLE AliasHandle, + IN PSID MemberId) +{ + NTSTATUS Status; + + TRACE("SamAddMemberToAlias(%p %p)\n", + AliasHandle, MemberId); + + RpcTryExcept + { + Status = SamrAddMemberToAlias((SAMPR_HANDLE)AliasHandle, + (PRPC_SID)MemberId); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + +NTSTATUS +NTAPI SamCloseHandle(IN SAM_HANDLE SamHandle) { NTSTATUS Status; @@ -142,6 +167,37 @@ Status = SamrConnect((PSAMPR_SERVER_NAME)ServerName, (SAMPR_HANDLE *)ServerHandle, DesiredAccess); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + +NTSTATUS +NTAPI +SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle, + IN PUNICODE_STRING AccountName, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_HANDLE AliasHandle, + OUT PULONG RelativeId) +{ + NTSTATUS Status; + + TRACE("SamCreateAliasInDomain(%p,%p,0x%08x,%p,%p)\n", + DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId); + + RpcTryExcept + { + Status = SamrCreateAliasInDomain((SAMPR_HANDLE)DomainHandle, + (PRPC_UNICODE_STRING)AccountName, + DesiredAccess, + (SAMPR_HANDLE *)AliasHandle, + RelativeId); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -186,9 +242,59 @@
NTSTATUS NTAPI +SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + OUT PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned) +{ + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + NTSTATUS Status; + + TRACE("SamEnumerateDomainsInSamServer(%p,%p,%p,%lu,%p)\n", + ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength, + CountReturned); + + if ((EnumerationContext == NULL) || + (Buffer == NULL) || + (CountReturned == NULL)) + return STATUS_INVALID_PARAMETER; + + *Buffer = NULL; + + RpcTryExcept + { + Status = SamrEnumerateDomainsInSamServer((SAMPR_HANDLE)ServerHandle, + 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 SamFreeMemory(IN PVOID Buffer) { - if (Buffer!= NULL) + if (Buffer != NULL) midl_user_free(Buffer);
return STATUS_SUCCESS; @@ -211,6 +317,35 @@ 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 +SamOpenAlias(IN SAM_HANDLE DomainHandle, + IN ACCESS_MASK DesiredAccess, + IN ULONG AliasId, + OUT PSAM_HANDLE AliasHandle) +{ + NTSTATUS Status; + + TRACE("SamOpenAlias(%p 0x%08x %lx %p)\n", + DomainHandle, DesiredAccess, AliasId, AliasHandle); + + RpcTryExcept + { + Status = SamrOpenAlias((SAMPR_HANDLE)DomainHandle, + DesiredAccess, + AliasId, + (SAMPR_HANDLE *)AliasHandle); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -282,12 +417,55 @@
NTSTATUS NTAPI +SamQueryInformationDomain(IN SAM_HANDLE DomainHandle, + IN DOMAIN_INFORMATION_CLASS DomainInformationClass, + OUT PVOID *Buffer) +{ + NTSTATUS Status; + + TRACE("SamQueryInformationDomain(%p %lu %p)\n", + DomainHandle, DomainInformationClass, Buffer); + + RpcTryExcept + { + Status = SamrQueryInformationDomain((SAMPR_HANDLE)DomainHandle, + DomainInformationClass, + (PSAMPR_DOMAIN_INFO_BUFFER *)Buffer); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + +NTSTATUS +NTAPI SamQueryInformationUser(IN SAM_HANDLE UserHandle, IN USER_INFORMATION_CLASS UserInformationClass, OUT PVOID *Buffer) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + + TRACE("SamQueryInformationUser(%p %lu %p)\n", + UserHandle, UserInformationClass, Buffer); + + RpcTryExcept + { + Status = SamrQueryInformationUser((SAMPR_HANDLE)UserHandle, + UserInformationClass, + (PSAMPR_USER_INFO_BUFFER *)Buffer); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; }
@@ -349,6 +527,7 @@ NTAPI SamShutdownSamServer(IN SAM_HANDLE ServerHandle) { + UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; }
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] Sun Jun 3 20:54:06 2012 @@ -1,4 +1,4 @@ -@ stub SamAddMemberToAlias +@ stdcall SamAddMemberToAlias(ptr ptr) @ stub SamAddMemberToGroup @ stub SamAddMultipleMembersToAlias @ stub SamChangePasswordUser2 @@ -7,7 +7,7 @@ @ stdcall SamCloseHandle(ptr) @ stdcall SamConnect(ptr ptr long ptr) @ stub SamConnectWithCreds -@ stub SamCreateAliasInDomain +@ stdcall SamCreateAliasInDomain(ptr ptr long ptr ptr) @ stub SamCreateGroupInDomain @ stub SamCreateUser2InDomain @ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr) @@ -15,7 +15,7 @@ @ stub SamDeleteGroup @ stub SamDeleteUser @ stub SamEnumerateAliasesInDomain -@ stub SamEnumerateDomainsInSamServer +@ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr) @ stub SamEnumerateGroupsInDomain @ stub SamEnumerateUsersInDomain @ stdcall SamFreeMemory(ptr) @@ -28,13 +28,13 @@ @ stdcall SamLookupDomainInSamServer(ptr ptr ptr) @ stub SamLookupIdsInDomain @ stub SamLookupNamesInDomain -@ stub SamOpenAlias +@ stdcall SamOpenAlias(ptr long long ptr) @ stdcall SamOpenDomain(ptr long ptr ptr) @ stub SamOpenGroup @ stdcall SamOpenUser(ptr long long ptr) @ stub SamQueryDisplayInformation @ stub SamQueryInformationAlias -@ stub SamQueryInformationDomain +@ stdcall SamQueryInformationDomain(ptr long ptr) @ stub SamQueryInformationGroup @ stdcall SamQueryInformationUser(ptr long ptr) @ stub SamQuerySecurityObject
Modified: trunk/reactos/dll/win32/samsrv/registry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/registry.c... ============================================================================== --- trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] Sun Jun 3 20:54:06 2012 @@ -16,7 +16,42 @@ /* FUNCTIONS ***************************************************************/
NTSTATUS -NTAPI +SampRegCloseKey(IN HANDLE KeyHandle) +{ + return NtClose(KeyHandle); +} + + +NTSTATUS +SampRegCreateKey(IN HANDLE ParentKeyHandle, + IN LPCWSTR KeyName, + IN ACCESS_MASK DesiredAccess, + OUT HANDLE KeyHandle) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + ULONG Disposition; + + RtlInitUnicodeString(&Name, KeyName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + ParentKeyHandle, + NULL); + + /* Create the key */ + return ZwCreateKey(KeyHandle, + DesiredAccess, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); +} + + +NTSTATUS SampRegEnumerateSubKey(IN HANDLE KeyHandle, IN ULONG Index, IN ULONG Length, @@ -74,7 +109,6 @@
NTSTATUS -NTAPI SampRegOpenKey(IN HANDLE ParentKeyHandle, IN LPCWSTR KeyName, IN ACCESS_MASK DesiredAccess, @@ -171,5 +205,8 @@ /* Free the memory and return status */ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
+ if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW)) + Status = STATUS_SUCCESS; + return Status; }
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] Sun Jun 3 20:54:06 2012 @@ -269,11 +269,201 @@ SamrEnumerateDomainsInSamServer(IN SAMPR_HANDLE ServerHandle, IN OUT unsigned long *EnumerationContext, OUT PSAMPR_ENUMERATION_BUFFER *Buffer, - IN unsigned long PreferedMaximumLength, - OUT unsigned long *CountReturned) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned) +{ + PSAM_DB_OBJECT ServerObject; + WCHAR DomainKeyName[64]; + HANDLE DomainsKeyHandle; + HANDLE DomainKeyHandle; + ULONG EnumIndex; + ULONG EnumCount; + ULONG RequiredLength; + ULONG DataLength; + ULONG i; + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + NTSTATUS Status; + + TRACE("SamrEnumerateDomainsInSamServer(%p %p %p %lu %p)\n", + ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength, + CountReturned); + + /* Validate the server handle */ + Status = SampValidateDbObject(ServerHandle, + SamDbServerObject, + SAM_SERVER_ENUMERATE_DOMAINS, + &ServerObject); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegOpenKey(ServerObject->KeyHandle, + L"Domains", + KEY_READ, + &DomainsKeyHandle); + if (!NT_SUCCESS(Status)) + return Status; + + EnumIndex = *EnumerationContext; + EnumCount = 0; + RequiredLength = 0; + + while (TRUE) + { + Status = SampRegEnumerateSubKey(DomainsKeyHandle, + EnumIndex, + 64 * sizeof(WCHAR), + DomainKeyName); + if (!NT_SUCCESS(Status)) + break; + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Domain key name: %S\n", DomainKeyName); + + Status = SampRegOpenKey(DomainsKeyHandle, + DomainKeyName, + KEY_READ, + &DomainKeyHandle); + TRACE("SampRegOpenKey returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + DataLength = 0; + Status = SampRegQueryValue(DomainKeyHandle, + L"Name", + NULL, + NULL, + &DataLength); + TRACE("SampRegQueryValue returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + TRACE("Data length: %lu\n", DataLength); + + if ((RequiredLength + DataLength + sizeof(UNICODE_STRING)) > PreferedMaximumLength) + break; + + RequiredLength += (DataLength + sizeof(UNICODE_STRING)); + EnumCount++; + } + + NtClose(DomainKeyHandle); + } + + EnumIndex++; + } + + TRACE("EnumCount: %lu\n", EnumCount); + TRACE("RequiredLength: %lu\n", RequiredLength); + + EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER)); + if (EnumBuffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + EnumBuffer->EntriesRead = EnumCount; + EnumBuffer->Buffer = midl_user_allocate(EnumCount * sizeof(SAMPR_RID_ENUMERATION)); + if (EnumBuffer->Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + EnumIndex = *EnumerationContext; + for (i = 0; i < EnumCount; i++, EnumIndex++) + { + Status = SampRegEnumerateSubKey(DomainsKeyHandle, + EnumIndex, + 64 * sizeof(WCHAR), + DomainKeyName); + if (!NT_SUCCESS(Status)) + break; + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Domain key name: %S\n", DomainKeyName); + + Status = SampRegOpenKey(DomainsKeyHandle, + DomainKeyName, + KEY_READ, + &DomainKeyHandle); + TRACE("SampRegOpenKey returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + DataLength = 0; + Status = SampRegQueryValue(DomainKeyHandle, + L"Name", + NULL, + NULL, + &DataLength); + TRACE("SampRegQueryValue returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + EnumBuffer->Buffer[i].RelativeId = 0; + 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(DomainKeyHandle); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampRegQueryValue(DomainKeyHandle, + L"Name", + NULL, + EnumBuffer->Buffer[i].Name.Buffer, + &DataLength); + TRACE("SampRegQueryValue returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + TRACE("Domain name: %S\n", EnumBuffer->Buffer[i].Name.Buffer); + } + } + + NtClose(DomainKeyHandle); + + if (!NT_SUCCESS(Status)) + goto done; + } + } + + if (NT_SUCCESS(Status)) + { + *EnumerationContext += EnumCount; + *Buffer = EnumBuffer; + *CountReturned = EnumCount; + } + +done: + if (!NT_SUCCESS(Status)) + { + *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); + } + } + + NtClose(DomainsKeyHandle); + + return Status; }
/* Function 7 */ @@ -348,6 +538,64 @@ return Status; }
+ +static NTSTATUS +SampQueryDomainName(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(DomainObject, + L"Name", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Name.DomainName.Length = Length - sizeof(WCHAR); + InfoBuffer->Name.DomainName.MaximumLength = Length; + InfoBuffer->Name.DomainName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Name.DomainName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"Name", + NULL, + (PVOID)InfoBuffer->Name.DomainName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->Name.DomainName.Buffer != NULL) + midl_user_free(InfoBuffer->Name.DomainName.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + /* Function 8 */ NTSTATUS NTAPI @@ -355,8 +603,32 @@ IN DOMAIN_INFORMATION_CLASS DomainInformationClass, OUT PSAMPR_DOMAIN_INFO_BUFFER *Buffer) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT DomainObject; + NTSTATUS Status; + + TRACE("SamrQueryInformationDomain(%p %lu %p)\n", + DomainHandle, DomainInformationClass, Buffer); + + /* Validate the server handle */ + Status = SampValidateDbObject(DomainHandle, + SamDbDomainObject, + DOMAIN_READ_OTHER_PARAMETERS, + &DomainObject); + if (!NT_SUCCESS(Status)) + return Status; + + switch (DomainInformationClass) + { + case DomainNameInformation: + Status = SampQueryDomainName(DomainObject, + Buffer); + break; + + default: + Status = STATUS_NOT_IMPLEMENTED; + } + + return Status; }
static NTSTATUS @@ -399,7 +671,7 @@ { case DomainNameInformation: Status = SampSetDomainName(DomainObject, - (PSAMPR_DOMAIN_NAME_INFORMATION)DomainInformation); + &DomainInformation->Name); break;
default: @@ -579,8 +851,116 @@ OUT SAMPR_HANDLE *AliasHandle, OUT unsigned long *RelativeId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT DomainObject; + PSAM_DB_OBJECT AliasObject; + ULONG ulSize; + ULONG ulRid; + WCHAR szRid[9]; + BOOL bAliasExists = FALSE; + 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; + } + + /* 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 + 1; + + TRACE("RID: %lx\n", ulRid); + + /* Convert the RID into a string (hex) */ + swprintf(szRid, L"%08lX", ulRid); + + /* Check whether the user name is already in use */ + Status = SampCheckDbObjectNameAlias(DomainObject, + L"Aliases", + AccountName->Buffer, + &bAliasExists); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + if (bAliasExists) + { + TRACE("The alias account %S already exists!\n", AccountName->Buffer); + return STATUS_ALIAS_EXISTS; + } + + /* Create the user 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 name alias for the user object */ + Status = SampSetDbObjectNameAlias(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; + } + + /* FIXME: Set default alias attributes */ + + if (NT_SUCCESS(Status)) + { + *AliasHandle = (SAMPR_HANDLE)AliasObject; + *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 15 */ @@ -723,11 +1103,47 @@ NTAPI SamrOpenAlias(IN SAMPR_HANDLE DomainHandle, IN ACCESS_MASK DesiredAccess, - IN unsigned long AliasId, + IN ULONG AliasId, OUT SAMPR_HANDLE *AliasHandle) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT DomainObject; + PSAM_DB_OBJECT AliasObject; + WCHAR szRid[9]; + NTSTATUS Status; + + TRACE("SamrOpenAlias(%p %lx %lx %p)\n", + DomainHandle, DesiredAccess, AliasId, AliasHandle); + + /* Validate the domain handle */ + Status = SampValidateDbObject(DomainHandle, + SamDbDomainObject, + DOMAIN_LOOKUP, + &DomainObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + /* Convert the RID into a string (hex) */ + swprintf(szRid, L"%08lX", AliasId); + + /* Create the alias object */ + Status = SampOpenDbObject(DomainObject, + L"Aliases", + szRid, + SamDbAliasObject, + DesiredAccess, + &AliasObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + *AliasHandle = (SAMPR_HANDLE)AliasObject; + + return STATUS_SUCCESS; }
/* Function 28 */ @@ -767,8 +1183,52 @@ SamrAddMemberToAlias(IN SAMPR_HANDLE AliasHandle, IN PRPC_SID MemberId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT AliasObject; + LPWSTR MemberIdString = NULL; + HANDLE MembersKeyHandle = NULL; + NTSTATUS Status; + + TRACE("SamrAddMemberToAlias(%p %p)\n", + AliasHandle, MemberId); + + /* Validate the domain handle */ + Status = SampValidateDbObject(AliasHandle, + SamDbAliasObject, + ALIAS_ADD_MEMBER, + &AliasObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + ConvertSidToStringSidW(MemberId, &MemberIdString); + TRACE("Member SID: %S\n", MemberIdString); + + Status = SampRegCreateKey(AliasObject->KeyHandle, + L"Members", + KEY_WRITE, + &MembersKeyHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status); + goto done; + } + + Status = SampRegSetValue(MembersKeyHandle, + MemberIdString, + REG_BINARY, + NULL, + 0); + +done: + if (MembersKeyHandle != NULL) + SampRegCloseKey(MembersKeyHandle); + + if (MemberIdString != NULL) + LocalFree(MemberIdString); + + return Status; }
/* Function 32 */
Modified: trunk/reactos/dll/win32/samsrv/samsrv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samsrv.h?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] Sun Jun 3 20:54:06 2012 @@ -17,6 +17,7 @@ #include <ndk/umtypes.h> #include <ddk/ntsam.h> #include <ntsecapi.h> +#include <sddl.h>
#include <samsrv/samsrv.h>
@@ -105,14 +106,21 @@
/* registry.h */ NTSTATUS -NTAPI +SampRegCloseKey(IN HANDLE KeyHandle); + +NTSTATUS +SampRegCreateKey(IN HANDLE ParentKeyHandle, + IN LPCWSTR KeyName, + IN ACCESS_MASK DesiredAccess, + OUT HANDLE KeyHandle); + +NTSTATUS 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,
Modified: trunk/reactos/dll/win32/samsrv/setup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/setup.c?re... ============================================================================== --- trunk/reactos/dll/win32/samsrv/setup.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/setup.c [iso-8859-1] Sun Jun 3 20:54:06 2012 @@ -59,35 +59,87 @@
static BOOL +SampCreateAliasAccount(HKEY hDomainKey, + LPCWSTR lpAccountName, + ULONG ulRelativeId) +{ + DWORD dwDisposition; + WCHAR szAccountKeyName[32]; + HKEY hAccountKey = NULL; + HKEY hNamesKey = NULL; + + swprintf(szAccountKeyName, L"Aliases\%08lX", ulRelativeId); + + if (!RegCreateKeyExW(hDomainKey, + szAccountKeyName, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + NULL, + &hAccountKey, + &dwDisposition)) + { + RegSetValueEx(hAccountKey, + L"Name", + 0, + REG_SZ, + (LPVOID)lpAccountName, + (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); + + RegCloseKey(hAccountKey); + } + + if (!RegOpenKeyExW(hDomainKey, + L"Aliases\Names", + 0, + KEY_ALL_ACCESS, + &hNamesKey)) + { + RegSetValueEx(hNamesKey, + lpAccountName, + 0, + REG_DWORD, + (LPVOID)&ulRelativeId, + sizeof(ULONG)); + + RegCloseKey(hNamesKey); + } + + return TRUE; +} + + +static BOOL SampCreateUserAccount(HKEY hDomainKey, LPCWSTR lpAccountName, ULONG ulRelativeId) { DWORD dwDisposition; - WCHAR szUserKeyName[32]; - HKEY hUserKey = NULL; + WCHAR szAccountKeyName[32]; + HKEY hAccountKey = NULL; HKEY hNamesKey = NULL;
- swprintf(szUserKeyName, L"Users\%08lX", ulRelativeId); + swprintf(szAccountKeyName, L"Users\%08lX", ulRelativeId);
if (!RegCreateKeyExW(hDomainKey, - szUserKeyName, + szAccountKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, - &hUserKey, + &hAccountKey, &dwDisposition)) { - RegSetValueEx(hUserKey, + RegSetValueEx(hAccountKey, L"Name", 0, REG_SZ, (LPVOID)lpAccountName, (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
- RegCloseKey(hUserKey); + RegCloseKey(hAccountKey); }
if (!RegOpenKeyExW(hDomainKey, @@ -119,7 +171,7 @@ { DWORD dwDisposition; HKEY hDomainKey = NULL; - HKEY hAliasKey = NULL; + HKEY hAliasesKey = NULL; HKEY hGroupsKey = NULL; HKEY hUsersKey = NULL; HKEY hNamesKey = NULL; @@ -157,16 +209,16 @@
/* Create the Alias container */ if (!RegCreateKeyExW(hDomainKey, - L"Alias", + L"Aliases", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, - &hAliasKey, + &hAliasesKey, &dwDisposition)) { - if (!RegCreateKeyExW(hAliasKey, + if (!RegCreateKeyExW(hAliasesKey, L"Names", 0, NULL, @@ -177,7 +229,7 @@ &dwDisposition)) RegCloseKey(hNamesKey);
- RegCloseKey(hAliasKey); + RegCloseKey(hAliasesKey); }
/* Create the Groups container */ @@ -344,6 +396,21 @@ pBuiltinSid, &hDomainKey)) { + SampCreateAliasAccount(hDomainKey, + L"Administrators", + DOMAIN_ALIAS_RID_ADMINS); + + SampCreateAliasAccount(hDomainKey, + L"Users", + DOMAIN_ALIAS_RID_USERS); + + SampCreateAliasAccount(hDomainKey, + L"Guests", + DOMAIN_ALIAS_RID_GUESTS); + + SampCreateAliasAccount(hDomainKey, + L"Power Users", + DOMAIN_ALIAS_RID_POWER_USERS);
RegCloseKey(hDomainKey); }
Modified: trunk/reactos/include/ddk/ntsam.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=566... ============================================================================== --- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original) +++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Sun Jun 3 20:54:06 2012 @@ -5,6 +5,12 @@ #ifdef __cplusplus extern "C" { #endif + +#define ALIAS_ADD_MEMBER 1 +#define ALIAS_REMOVE_MEMBER 2 +#define ALIAS_LIST_MEMBERS 4 +#define ALIAS_READ_INFORMATION 8 +#define ALIAS_WRITE_ACCOUNT 16
#define DOMAIN_READ_PASSWORD_PARAMETERS 1 #define DOMAIN_WRITE_PASSWORD_PARAMS 2 @@ -38,6 +44,19 @@ #define USER_WRITE_GROUP_INFORMATION 1024
typedef PVOID SAM_HANDLE, *PSAM_HANDLE; +typedef ULONG SAM_ENUMERATE_HANDLE, *PSAM_ENUMERATE_HANDLE; + +typedef struct _SAM_RID_ENUMERATION +{ + ULONG RelativeId; + UNICODE_STRING Name; +} SAM_RID_ENUMERATION, *PSAM_RID_ENUMERATION; + +typedef struct _SAM_SID_ENUMERATION +{ + PSID Sid; + UNICODE_STRING Name; +} SAM_SID_ENUMERATION, *PSAM_SID_ENUMERATION;
typedef enum _DOMAIN_INFORMATION_CLASS { @@ -103,6 +122,11 @@
NTSTATUS NTAPI +SamAddMemberToAlias(IN SAM_HANDLE AliasHandle, + IN PSID MemberId); + +NTSTATUS +NTAPI SamCloseHandle(IN SAM_HANDLE SamHandle);
NTSTATUS @@ -111,6 +135,14 @@ OUT PSAM_HANDLE ServerHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTSTATUS +NTAPI +SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle, + IN PUNICODE_STRING AccountName, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_HANDLE AliasHandle, + OUT PULONG RelativeId);
NTSTATUS NTAPI @@ -122,6 +154,14 @@
NTSTATUS NTAPI +SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + OUT PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned); + +NTSTATUS +NTAPI SamFreeMemory(IN PVOID Buffer);
NTSTATUS @@ -129,6 +169,13 @@ SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, IN PUNICODE_STRING Name, OUT PSID *DomainId); + +NTSTATUS +NTAPI +SamOpenAlias(IN SAM_HANDLE DomainHandle, + IN ACCESS_MASK DesiredAccess, + IN ULONG AliasId, + OUT PSAM_HANDLE AliasHandle);
NTSTATUS NTAPI @@ -146,6 +193,12 @@
NTSTATUS NTAPI +SamQueryInformationDomain(IN SAM_HANDLE DomainHandle, + IN DOMAIN_INFORMATION_CLASS DomainInformationClass, + OUT PVOID *Buffer); + +NTSTATUS +NTAPI SamQueryInformationUser(IN SAM_HANDLE UserHandle, IN USER_INFORMATION_CLASS UserInformationClass, OUT PVOID *Buffer);
Modified: trunk/reactos/include/reactos/idl/sam.idl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/idl/sam.idl... ============================================================================== --- trunk/reactos/include/reactos/idl/sam.idl [iso-8859-1] (original) +++ trunk/reactos/include/reactos/idl/sam.idl [iso-8859-1] Sun Jun 3 20:54:06 2012 @@ -1036,7 +1036,7 @@ SamrOpenAlias( [in] SAMPR_HANDLE DomainHandle, [in] ACCESS_MASK DesiredAccess, - [in] unsigned long AliasId, + [in] ULONG AliasId, [out] SAMPR_HANDLE *AliasHandle);
/* Function 28 */ @@ -1088,7 +1088,7 @@ SamrOpenUser( [in] SAMPR_HANDLE DomainHandle, [in] ACCESS_MASK DesiredAccess, - [in] unsigned long UserId, + [in] ULONG UserId, [out] SAMPR_HANDLE *UserHandle);
/* Function 35 */