diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 11d4442d4a3..ebf5a46ac9b 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -539,6 +539,290 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle, } +static NTSTATUS +SampQueryDomainPassword(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Password.MinPasswordLength = FixedData.MinPasswordLength; + InfoBuffer->Password.PasswordHistoryLength = FixedData.PasswordHistoryLength; + InfoBuffer->Password.PasswordProperties = FixedData.PasswordProperties; + InfoBuffer->Password.MaxPasswordAge.LowPart = FixedData.MaxPasswordAge.LowPart; + InfoBuffer->Password.MaxPasswordAge.HighPart = FixedData.MaxPasswordAge.HighPart; + InfoBuffer->Password.MinPasswordAge.LowPart = FixedData.MinPasswordAge.LowPart; + InfoBuffer->Password.MinPasswordAge.HighPart = FixedData.MinPasswordAge.HighPart; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainGeneral(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General.ForceLogoff.LowPart = FixedData.ForceLogoff.LowPart; + InfoBuffer->General.ForceLogoff.HighPart = FixedData.ForceLogoff.HighPart; + InfoBuffer->General.DomainModifiedCount.LowPart = FixedData.DomainModifiedCount.LowPart; + InfoBuffer->General.DomainModifiedCount.HighPart = FixedData.DomainModifiedCount.HighPart; + InfoBuffer->General.DomainServerState = FixedData.DomainServerState; + InfoBuffer->General.DomainServerRole = FixedData.DomainServerRole; + InfoBuffer->General.UasCompatibilityRequired = FixedData.UasCompatibilityRequired; + + Length = 0; + Status = SampGetObjectAttribute(DomainObject, + L"OemInformation", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General.OemInformation.Length = Length - sizeof(WCHAR); + InfoBuffer->General.OemInformation.MaximumLength = Length; + InfoBuffer->General.OemInformation.Buffer = midl_user_allocate(Length); + if (InfoBuffer->General.OemInformation.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"OemInformation", + NULL, + (PVOID)InfoBuffer->General.OemInformation.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + Length = 0; + Status = SampGetObjectAttribute(DomainObject, + L"Name", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General.DomainName.Length = Length - sizeof(WCHAR); + InfoBuffer->General.DomainName.MaximumLength = Length; + InfoBuffer->General.DomainName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->General.DomainName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"Name", + NULL, + (PVOID)InfoBuffer->General.DomainName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + Length = 0; + Status = SampGetObjectAttribute(DomainObject, + L"ReplicaSourceNodeName", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General.ReplicaSourceNodeName.Length = Length - sizeof(WCHAR); + InfoBuffer->General.ReplicaSourceNodeName.MaximumLength = Length; + InfoBuffer->General.ReplicaSourceNodeName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->General.ReplicaSourceNodeName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"ReplicaSourceNodeName", + NULL, + (PVOID)InfoBuffer->General.ReplicaSourceNodeName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General.UserCount = 0; /* FIXME */ + InfoBuffer->General.GroupCount = 0; /* FIXME */ + InfoBuffer->General.AliasCount = 0; /* FIXME */ + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->General.OemInformation.Buffer != NULL) + midl_user_free(InfoBuffer->General.OemInformation.Buffer); + + if (InfoBuffer->General.DomainName.Buffer != NULL) + midl_user_free(InfoBuffer->General.DomainName.Buffer); + + if (InfoBuffer->General.ReplicaSourceNodeName.Buffer != NULL) + midl_user_free(InfoBuffer->General.ReplicaSourceNodeName.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainLogoff(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Logoff.ForceLogoff.LowPart = FixedData.ForceLogoff.LowPart; + InfoBuffer->Logoff.ForceLogoff.HighPart = FixedData.ForceLogoff.HighPart; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainOem(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"OemInformation", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Oem.OemInformation.Length = Length - sizeof(WCHAR); + InfoBuffer->Oem.OemInformation.MaximumLength = Length; + InfoBuffer->Oem.OemInformation.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Oem.OemInformation.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"OemInformation", + NULL, + (PVOID)InfoBuffer->Oem.OemInformation.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->Oem.OemInformation.Buffer != NULL) + midl_user_free(InfoBuffer->Oem.OemInformation.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + static NTSTATUS SampQueryDomainName(PSAM_DB_OBJECT DomainObject, PSAMPR_DOMAIN_INFO_BUFFER *Buffer) @@ -596,6 +880,420 @@ done: } +static NTSTATUS +SampQueryDomainReplication(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"ReplicaSourceNodeName", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Replication.ReplicaSourceNodeName.Length = Length - sizeof(WCHAR); + InfoBuffer->Replication.ReplicaSourceNodeName.MaximumLength = Length; + InfoBuffer->Replication.ReplicaSourceNodeName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Replication.ReplicaSourceNodeName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"ReplicaSourceNodeName", + NULL, + (PVOID)InfoBuffer->Replication.ReplicaSourceNodeName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->Replication.ReplicaSourceNodeName.Buffer != NULL) + midl_user_free(InfoBuffer->Replication.ReplicaSourceNodeName.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainServerRole(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Role.DomainServerRole = FixedData.DomainServerRole; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainModified(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Modified.DomainModifiedCount.LowPart = FixedData.DomainModifiedCount.LowPart; + InfoBuffer->Modified.DomainModifiedCount.HighPart = FixedData.DomainModifiedCount.HighPart; + InfoBuffer->Modified.CreationTime.LowPart = FixedData.CreationTime.LowPart; + InfoBuffer->Modified.CreationTime.HighPart = FixedData.CreationTime.HighPart; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainState(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->State.DomainServerState = FixedData.DomainServerState; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainGeneral2(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General2.I1.ForceLogoff.LowPart = FixedData.ForceLogoff.LowPart; + InfoBuffer->General2.I1.ForceLogoff.HighPart = FixedData.ForceLogoff.HighPart; + InfoBuffer->General2.I1.DomainModifiedCount.LowPart = FixedData.DomainModifiedCount.LowPart; + InfoBuffer->General2.I1.DomainModifiedCount.HighPart = FixedData.DomainModifiedCount.HighPart; + InfoBuffer->General2.I1.DomainServerState = FixedData.DomainServerState; + InfoBuffer->General2.I1.DomainServerRole = FixedData.DomainServerRole; + InfoBuffer->General2.I1.UasCompatibilityRequired = FixedData.UasCompatibilityRequired; + + InfoBuffer->General2.LockoutDuration = FixedData.LockoutDuration; + InfoBuffer->General2.LockoutObservationWindow = FixedData.LockoutObservationWindow; + InfoBuffer->General2.LockoutThreshold = FixedData.LockoutThreshold; + + Length = 0; + Status = SampGetObjectAttribute(DomainObject, + L"OemInformation", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General2.I1.OemInformation.Length = Length - sizeof(WCHAR); + InfoBuffer->General2.I1.OemInformation.MaximumLength = Length; + InfoBuffer->General2.I1.OemInformation.Buffer = midl_user_allocate(Length); + if (InfoBuffer->General2.I1.OemInformation.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"OemInformation", + NULL, + (PVOID)InfoBuffer->General2.I1.OemInformation.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + Length = 0; + Status = SampGetObjectAttribute(DomainObject, + L"Name", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General2.I1.DomainName.Length = Length - sizeof(WCHAR); + InfoBuffer->General2.I1.DomainName.MaximumLength = Length; + InfoBuffer->General2.I1.DomainName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->General2.I1.DomainName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"Name", + NULL, + (PVOID)InfoBuffer->General2.I1.DomainName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + Length = 0; + Status = SampGetObjectAttribute(DomainObject, + L"ReplicaSourceNodeName", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General2.I1.ReplicaSourceNodeName.Length = Length - sizeof(WCHAR); + InfoBuffer->General2.I1.ReplicaSourceNodeName.MaximumLength = Length; + InfoBuffer->General2.I1.ReplicaSourceNodeName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->General2.I1.ReplicaSourceNodeName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(DomainObject, + L"ReplicaSourceNodeName", + NULL, + (PVOID)InfoBuffer->General2.I1.ReplicaSourceNodeName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->General2.I1.UserCount = 0; /* FIXME */ + InfoBuffer->General2.I1.GroupCount = 0; /* FIXME */ + InfoBuffer->General2.I1.AliasCount = 0; /* FIXME */ + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->General2.I1.OemInformation.Buffer != NULL) + midl_user_free(InfoBuffer->General2.I1.OemInformation.Buffer); + + if (InfoBuffer->General2.I1.DomainName.Buffer != NULL) + midl_user_free(InfoBuffer->General2.I1.DomainName.Buffer); + + if (InfoBuffer->General2.I1.ReplicaSourceNodeName.Buffer != NULL) + midl_user_free(InfoBuffer->General2.I1.ReplicaSourceNodeName.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainLockout(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Lockout.LockoutDuration = FixedData.LockoutDuration; + InfoBuffer->Lockout.LockoutObservationWindow = FixedData.LockoutObservationWindow; + InfoBuffer->Lockout.LockoutThreshold = FixedData.LockoutThreshold; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryDomainModified2(PSAM_DB_OBJECT DomainObject, + PSAMPR_DOMAIN_INFO_BUFFER *Buffer) +{ + PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL; + SAM_DOMAIN_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_DOMAIN_FIXED_DATA); + Status = SampGetObjectAttribute(DomainObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Modified2.DomainModifiedCount.LowPart = FixedData.DomainModifiedCount.LowPart; + InfoBuffer->Modified2.DomainModifiedCount.HighPart = FixedData.DomainModifiedCount.HighPart; + InfoBuffer->Modified2.CreationTime.LowPart = FixedData.CreationTime.LowPart; + InfoBuffer->Modified2.CreationTime.HighPart = FixedData.CreationTime.HighPart; + InfoBuffer->Modified2.ModifiedCountAtLastPromotion.LowPart = FixedData.ModifiedCountAtLastPromotion.LowPart; + InfoBuffer->Modified2.ModifiedCountAtLastPromotion.HighPart = FixedData.ModifiedCountAtLastPromotion.HighPart; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + /* Function 8 */ NTSTATUS NTAPI @@ -604,26 +1302,110 @@ SamrQueryInformationDomain(IN SAMPR_HANDLE DomainHandle, OUT PSAMPR_DOMAIN_INFO_BUFFER *Buffer) { PSAM_DB_OBJECT DomainObject; + ACCESS_MASK DesiredAccess; NTSTATUS Status; TRACE("SamrQueryInformationDomain(%p %lu %p)\n", DomainHandle, DomainInformationClass, Buffer); + switch (DomainInformationClass) + { + case DomainPasswordInformation: + case DomainLockoutInformation: + DesiredAccess = DOMAIN_READ_PASSWORD_PARAMETERS; + break; + + case DomainGeneralInformation: + case DomainLogoffInformation: + case DomainOemInformation: + case DomainNameInformation: + case DomainReplicationInformation: + case DomainServerRoleInformation: + case DomainModifiedInformation: + case DomainStateInformation: + case DomainModifiedInformation2: + DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS; + break; + + case DomainGeneralInformation2: + DesiredAccess = DOMAIN_READ_PASSWORD_PARAMETERS | + DOMAIN_READ_OTHER_PARAMETERS; + break; + + default: + return STATUS_INVALID_INFO_CLASS; + } + /* Validate the server handle */ Status = SampValidateDbObject(DomainHandle, SamDbDomainObject, - DOMAIN_READ_OTHER_PARAMETERS, + DesiredAccess, &DomainObject); if (!NT_SUCCESS(Status)) return Status; switch (DomainInformationClass) { + case DomainPasswordInformation: + Status = SampQueryDomainPassword(DomainObject, + Buffer); + break; + + case DomainGeneralInformation: + Status = SampQueryDomainGeneral(DomainObject, + Buffer); + break; + + case DomainLogoffInformation: + Status = SampQueryDomainLogoff(DomainObject, + Buffer); + break; + + case DomainOemInformation: + Status = SampQueryDomainOem(DomainObject, + Buffer); + break; + case DomainNameInformation: Status = SampQueryDomainName(DomainObject, Buffer); break; + case DomainReplicationInformation: + Status = SampQueryDomainReplication(DomainObject, + Buffer); + break; + + case DomainServerRoleInformation: + Status = SampQueryDomainServerRole(DomainObject, + Buffer); + break; + + case DomainModifiedInformation: + Status = SampQueryDomainModified(DomainObject, + Buffer); + break; + + case DomainStateInformation: + Status = SampQueryDomainState(DomainObject, + Buffer); + break; + + case DomainGeneralInformation2: + Status = SampQueryDomainGeneral2(DomainObject, + Buffer); + break; + + case DomainLockoutInformation: + Status = SampQueryDomainLockout(DomainObject, + Buffer); + break; + + case DomainModifiedInformation2: + Status = SampQueryDomainModified2(DomainObject, + Buffer); + break; + default: Status = STATUS_NOT_IMPLEMENTED; } @@ -631,21 +1413,6 @@ SamrQueryInformationDomain(IN SAMPR_HANDLE DomainHandle, return Status; } -static NTSTATUS -SampSetDomainName(PSAM_DB_OBJECT DomainObject, - PSAMPR_DOMAIN_NAME_INFORMATION DomainNameInfo) -{ - NTSTATUS Status; - - Status = SampSetObjectAttribute(DomainObject, - L"Name", - REG_SZ, - DomainNameInfo->DomainName.Buffer, - DomainNameInfo->DomainName.Length + sizeof(WCHAR)); - - return Status; -} - /* Function 9 */ NTSTATUS NTAPI @@ -654,24 +1421,82 @@ SamrSetInformationDomain(IN SAMPR_HANDLE DomainHandle, IN PSAMPR_DOMAIN_INFO_BUFFER DomainInformation) { PSAM_DB_OBJECT DomainObject; + ACCESS_MASK DesiredAccess; NTSTATUS Status; TRACE("SamrSetInformationDomain(%p %lu %p)\n", DomainHandle, DomainInformationClass, DomainInformation); + switch (DomainInformationClass) + { + case DomainPasswordInformation: + case DomainLockoutInformation: + DesiredAccess = DOMAIN_WRITE_PASSWORD_PARAMS; + break; + + case DomainLogoffInformation: + case DomainOemInformation: + case DomainNameInformation: + DesiredAccess = DOMAIN_WRITE_OTHER_PARAMETERS; + break; + + case DomainReplicationInformation: + case DomainServerRoleInformation: + case DomainStateInformation: + DesiredAccess = DOMAIN_ADMINISTER_SERVER; + break; + + default: + return STATUS_INVALID_INFO_CLASS; + } + /* Validate the server handle */ Status = SampValidateDbObject(DomainHandle, SamDbDomainObject, - DOMAIN_WRITE_OTHER_PARAMETERS, + DesiredAccess, &DomainObject); if (!NT_SUCCESS(Status)) return Status; switch (DomainInformationClass) { + case DomainPasswordInformation: + break; + + case DomainLogoffInformation: + break; + + case DomainOemInformation: + Status = SampSetObjectAttribute(DomainObject, + L"OemInformation", + REG_SZ, + DomainInformation->Oem.OemInformation.Buffer, + DomainInformation->Oem.OemInformation.Length + sizeof(WCHAR)); + break; + case DomainNameInformation: - Status = SampSetDomainName(DomainObject, - &DomainInformation->Name); + Status = SampSetObjectAttribute(DomainObject, + L"Name", + REG_SZ, + DomainInformation->Name.DomainName.Buffer, + DomainInformation->Name.DomainName.Length + sizeof(WCHAR)); + break; + + case DomainReplicationInformation: + Status = SampSetObjectAttribute(DomainObject, + L"ReplicaSourceNodeName", + REG_SZ, + DomainInformation->Replication.ReplicaSourceNodeName.Buffer, + DomainInformation->Replication.ReplicaSourceNodeName.Length + sizeof(WCHAR)); + break; + + case DomainServerRoleInformation: + break; + + case DomainStateInformation: + break; + + case DomainLockoutInformation: break; default: @@ -1800,37 +2625,6 @@ SamrQueryInformationAlias(IN SAMPR_HANDLE AliasHandle, return Status; } - -static NTSTATUS -SampSetAliasName(PSAM_DB_OBJECT AliasObject, - PSAMPR_ALIAS_INFO_BUFFER Buffer) -{ - NTSTATUS Status; - - Status = SampSetObjectAttribute(AliasObject, - L"Name", - REG_SZ, - Buffer->Name.Name.Buffer, - Buffer->Name.Name.Length + sizeof(WCHAR)); - - return Status; -} - -static NTSTATUS -SampSetAliasAdminComment(PSAM_DB_OBJECT AliasObject, - PSAMPR_ALIAS_INFO_BUFFER Buffer) -{ - NTSTATUS Status; - - Status = SampSetObjectAttribute(AliasObject, - L"Description", - REG_SZ, - Buffer->AdminComment.AdminComment.Buffer, - Buffer->AdminComment.AdminComment.Length + sizeof(WCHAR)); - - return Status; -} - /* Function 29 */ NTSTATUS NTAPI @@ -1855,13 +2649,19 @@ SamrSetInformationAlias(IN SAMPR_HANDLE AliasHandle, switch (AliasInformationClass) { case AliasNameInformation: - Status = SampSetAliasName(AliasObject, - Buffer); + Status = SampSetObjectAttribute(AliasObject, + L"Name", + REG_SZ, + Buffer->Name.Name.Buffer, + Buffer->Name.Name.Length + sizeof(WCHAR)); break; case AliasAdminCommentInformation: - Status = SampSetAliasAdminComment(AliasObject, - Buffer); + Status = SampSetObjectAttribute(AliasObject, + L"Description", + REG_SZ, + Buffer->AdminComment.AdminComment.Buffer, + Buffer->AdminComment.AdminComment.Length + sizeof(WCHAR)); break; default: @@ -2166,6 +2966,15 @@ SamrDeleteUser(IN OUT SAMPR_HANDLE *UserHandle) return STATUS_NOT_IMPLEMENTED; } +static +NTSTATUS +SampQueryUserName(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + /* Function 36 */ NTSTATUS NTAPI @@ -2173,8 +2982,52 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle, IN USER_INFORMATION_CLASS UserInformationClass, OUT PSAMPR_USER_INFO_BUFFER *Buffer) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT UserObject; + ACCESS_MASK DesiredAccess; + NTSTATUS Status; + + TRACE("SamrQueryInformationUser(%p %lu %p)\n", + UserHandle, UserInformationClass, Buffer); + + switch (UserInformationClass) + { + case UserGeneralInformation: + case UserNameInformation: + case UserAccountNameInformation: + case UserFullNameInformation: + case UserPrimaryGroupInformation: + case UserAdminCommentInformation: + DesiredAccess = USER_READ_GENERAL; + break; + + + default: + return STATUS_INVALID_INFO_CLASS; + } + + /* Validate the domain handle */ + Status = SampValidateDbObject(UserHandle, + SamDbUserObject, + DesiredAccess, + &UserObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + switch (UserInformationClass) + { + case UserNameInformation: + Status = SampQueryUserName(UserObject, + Buffer); + break; + + default: + Status = STATUS_INVALID_INFO_CLASS; + } + + return Status; } /* Function 37 */ diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index 819049d818f..ff734c270ab 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -12,6 +12,7 @@ #include #define NTOS_MODE_USER #include +#include #include #include #include @@ -50,6 +51,28 @@ typedef struct _SAM_DB_OBJECT #define SAMP_DB_SIGNATURE 0x87654321 +typedef struct _SAM_DOMAIN_FIXED_DATA +{ + ULONG Version; + ULONG Reserved; + LARGE_INTEGER CreationTime; + LARGE_INTEGER DomainModifiedCount; + LARGE_INTEGER MaxPasswordAge; + LARGE_INTEGER MinPasswordAge; + LARGE_INTEGER ForceLogoff; + LARGE_INTEGER LockoutDuration; + LARGE_INTEGER LockoutObservationWindow; + LARGE_INTEGER ModifiedCountAtLastPromotion; + ULONG NextRid; + ULONG PasswordProperties; + USHORT MinPasswordLength; + USHORT PasswordHistoryLength; + USHORT LockoutThreshold; + DOMAIN_SERVER_ENABLE_STATE DomainServerState; + DOMAIN_SERVER_ROLE DomainServerRole; + BOOLEAN UasCompatibilityRequired; +} SAM_DOMAIN_FIXED_DATA, *PSAM_DOMAIN_FIXED_DATA; + /* database.c */ NTSTATUS diff --git a/reactos/dll/win32/samsrv/setup.c b/reactos/dll/win32/samsrv/setup.c index 635fc9ceefc..fc420130df7 100644 --- a/reactos/dll/win32/samsrv/setup.c +++ b/reactos/dll/win32/samsrv/setup.c @@ -277,6 +277,8 @@ SampCreateDomain(IN HKEY hDomainsKey, IN PSID lpDomainSid, OUT PHKEY lpDomainKey) { + SAM_DOMAIN_FIXED_DATA FixedData; + LPWSTR lpEmptyString = L""; DWORD dwDisposition; HKEY hDomainKey = NULL; HKEY hAliasesKey = NULL; @@ -287,6 +289,26 @@ SampCreateDomain(IN HKEY hDomainsKey, if (lpDomainKey != NULL) *lpDomainKey = NULL; + /* Initialize the fixed domain data */ + memset(&FixedData, 0, sizeof(SAM_DOMAIN_FIXED_DATA)); + FixedData.Version = 1; + NtQuerySystemTime(&FixedData.CreationTime); + FixedData.DomainModifiedCount.QuadPart = 0; +// FixedData.MaxPasswordAge // 6 Weeks + FixedData.MinPasswordAge.QuadPart = 0; // Now +// FixedData.ForceLogoff +// FixedData.LockoutDuration // 30 minutes +// FixedData.LockoutObservationWindow // 30 minutes + FixedData.ModifiedCountAtLastPromotion.QuadPart = 0; + FixedData.NextRid = 1000; + FixedData.PasswordProperties = 0; + FixedData.MinPasswordLength = 0; + FixedData.PasswordHistoryLength = 0; + FixedData.LockoutThreshold = 0; + FixedData.DomainServerState = DomainServerEnabled; + FixedData.DomainServerRole = DomainServerRolePrimary; + FixedData.UasCompatibilityRequired = TRUE; + if (RegCreateKeyExW(hDomainsKey, lpKeyName, 0, @@ -298,6 +320,15 @@ SampCreateDomain(IN HKEY hDomainsKey, &dwDisposition)) return FALSE; + /* Set the fixed data value */ + if (RegSetValueEx(hDomainKey, + L"F", + 0, + REG_BINARY, + (LPVOID)&FixedData, + sizeof(SAM_DOMAIN_FIXED_DATA))) + return FALSE; + if (lpDomainSid != NULL) { RegSetValueEx(hDomainKey, @@ -315,6 +346,20 @@ SampCreateDomain(IN HKEY hDomainsKey, RtlLengthSid(lpDomainSid)); } + RegSetValueEx(hDomainKey, + L"OemInformation", + 0, + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + + RegSetValueEx(hDomainKey, + L"ReplicaSourceNodeName", + 0, + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + /* Create the Alias container */ if (!RegCreateKeyExW(hDomainKey, L"Aliases", @@ -507,22 +552,22 @@ SampInitializeSAM(VOID) { SampCreateAliasAccount(hDomainKey, L"Administrators", - L"", + L"Testabc1234567890", DOMAIN_ALIAS_RID_ADMINS); SampCreateAliasAccount(hDomainKey, L"Users", - L"", + L"Users Group", DOMAIN_ALIAS_RID_USERS); SampCreateAliasAccount(hDomainKey, L"Guests", - L"", + L"Guests Group", DOMAIN_ALIAS_RID_GUESTS); SampCreateAliasAccount(hDomainKey, L"Power Users", - L"", + L"Power Users Group", DOMAIN_ALIAS_RID_POWER_USERS); diff --git a/reactos/include/ddk/ntsam.h b/reactos/include/ddk/ntsam.h index eff4eb5d36c..2ebc62c8ff6 100644 --- a/reactos/include/ddk/ntsam.h +++ b/reactos/include/ddk/ntsam.h @@ -220,6 +220,18 @@ typedef enum _DOMAIN_INFORMATION_CLASS DomainModifiedInformation2 } DOMAIN_INFORMATION_CLASS; +typedef enum _DOMAIN_SERVER_ENABLE_STATE +{ + DomainServerEnabled = 1, + DomainServerDisabled +} DOMAIN_SERVER_ENABLE_STATE, *PDOMAIN_SERVER_ENABLE_STATE; + +typedef enum _DOMAIN_SERVER_ROLE +{ + DomainServerRoleBackup = 2, + DomainServerRolePrimary +} DOMAIN_SERVER_ROLE, *PDOMAIN_SERVER_ROLE; + typedef struct _DOMAIN_NAME_INFORMATION { UNICODE_STRING DomainName; @@ -384,6 +396,11 @@ SamQueryInformationUser(IN SAM_HANDLE UserHandle, IN USER_INFORMATION_CLASS UserInformationClass, OUT PVOID *Buffer); +NTSTATUS +NTAPI +SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle, + IN PSID MemberId); + NTSTATUS NTAPI SamSetInformationAlias(IN SAM_HANDLE AliasHandle, diff --git a/reactos/include/reactos/idl/sam.idl b/reactos/include/reactos/idl/sam.idl index 1a52369ce0c..43a8dcc77ee 100644 --- a/reactos/include/reactos/idl/sam.idl +++ b/reactos/include/reactos/idl/sam.idl @@ -135,22 +135,26 @@ typedef struct _USER_DOMAIN_PASSWORD_INFORMATION unsigned long PasswordProperties; } USER_DOMAIN_PASSWORD_INFORMATION, *PUSER_DOMAIN_PASSWORD_INFORMATION; +cpp_quote("#ifndef _NTSAM_") typedef enum _DOMAIN_SERVER_ENABLE_STATE { DomainServerEnabled = 1, DomainServerDisabled } DOMAIN_SERVER_ENABLE_STATE, *PDOMAIN_SERVER_ENABLE_STATE; +cpp_quote("#endif") typedef struct _DOMAIN_STATE_INFORMATION { DOMAIN_SERVER_ENABLE_STATE DomainServerState; } DOMAIN_STATE_INFORMATION, *PDOMAIN_STATE_INFORMATION; +cpp_quote("#ifndef _NTSAM_") typedef enum _DOMAIN_SERVER_ROLE { DomainServerRoleBackup = 2, DomainServerRolePrimary = 3 } DOMAIN_SERVER_ROLE, *PDOMAIN_SERVER_ROLE; +cpp_quote("#endif") cpp_quote("#ifndef _NTSECAPI_H") typedef struct _DOMAIN_PASSWORD_INFORMATION