diff --git a/reactos/dll/win32/advapi32/advapi32.spec b/reactos/dll/win32/advapi32/advapi32.spec index aecac42a4dd..5c17fb8e304 100644 --- a/reactos/dll/win32/advapi32/advapi32.spec +++ b/reactos/dll/win32/advapi32/advapi32.spec @@ -387,7 +387,7 @@ @ stdcall LsaQueryForestTrustInformation(ptr ptr ptr) @ stdcall LsaQueryInfoTrustedDomain(long long long) @ stdcall LsaQueryInformationPolicy(ptr long ptr) -@ stub LsaQuerySecret +@ stdcall LsaQuerySecret(ptr ptr ptr ptr ptr) @ stub LsaQuerySecurityObject @ stdcall LsaQueryTrustedDomainInfo(ptr ptr long ptr) @ stdcall LsaQueryTrustedDomainInfoByName(ptr ptr long ptr) diff --git a/reactos/dll/win32/advapi32/sec/lsa.c b/reactos/dll/win32/advapi32/sec/lsa.c index 24960c1f592..a15ab3dda3a 100644 --- a/reactos/dll/win32/advapi32/sec/lsa.c +++ b/reactos/dll/win32/advapi32/sec/lsa.c @@ -963,6 +963,125 @@ LsaQueryInformationPolicy(IN LSA_HANDLE PolicyHandle, } +/* + * @unimplemented + */ +NTSTATUS +WINAPI +LsaQuerySecret(IN LSA_HANDLE SecretHandle, + OUT PLSA_UNICODE_STRING *CurrentValue OPTIONAL, + OUT PLARGE_INTEGER CurrentValueSetTime OPTIONAL, + OUT PLSA_UNICODE_STRING *OldValue OPTIONAL, + OUT PLARGE_INTEGER OldValueSetTime OPTIONAL) +{ + PLSAPR_CR_CIPHER_VALUE EncryptedCurrentValue = NULL; + PLSAPR_CR_CIPHER_VALUE EncryptedOldValue = NULL; + PLSA_UNICODE_STRING DecryptedCurrentValue = NULL; + PLSA_UNICODE_STRING DecryptedOldValue = NULL; + SIZE_T BufferSize; + NTSTATUS Status; + + RpcTryExcept + { + Status = LsarQuerySecret((PLSAPR_HANDLE)SecretHandle, + &EncryptedCurrentValue, + CurrentValueSetTime, + &EncryptedOldValue, + OldValueSetTime); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + if (!NT_SUCCESS(Status)) + goto done; + + /* Decrypt the current value */ + if (CurrentValue != NULL) + { + if (EncryptedCurrentValue == NULL) + { + *CurrentValue = NULL; + } + else + { + /* FIXME: Decrypt the current value */ + BufferSize = sizeof(LSA_UNICODE_STRING) + EncryptedCurrentValue->MaximumLength; + DecryptedCurrentValue = midl_user_allocate(BufferSize); + if (DecryptedCurrentValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + DecryptedCurrentValue->Length = (USHORT)EncryptedCurrentValue->Length; + DecryptedCurrentValue->MaximumLength = (USHORT)EncryptedCurrentValue->MaximumLength; + DecryptedCurrentValue->Buffer = (PWSTR)(DecryptedCurrentValue + 1); + RtlCopyMemory(DecryptedCurrentValue->Buffer, + EncryptedCurrentValue->Buffer, + EncryptedCurrentValue->Length); + + *CurrentValue = DecryptedCurrentValue; + } + } + + /* Decrypt the old value */ + if (OldValue != NULL) + { + if (EncryptedOldValue == NULL) + { + *OldValue = NULL; + } + else + { + /* FIXME: Decrypt the old value */ + BufferSize = sizeof(LSA_UNICODE_STRING) + EncryptedOldValue->MaximumLength; + DecryptedOldValue = midl_user_allocate(BufferSize); + if (DecryptedOldValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + DecryptedOldValue->Length = (USHORT)EncryptedOldValue->Length; + DecryptedOldValue->MaximumLength = (USHORT)EncryptedOldValue->MaximumLength; + DecryptedOldValue->Buffer = (PWSTR)(DecryptedOldValue + 1); + RtlCopyMemory(DecryptedOldValue->Buffer, + EncryptedOldValue->Buffer, + EncryptedOldValue->Length); + + *OldValue = DecryptedOldValue; + } + } + +done: + if (!NT_SUCCESS(Status)) + { + if (DecryptedCurrentValue != NULL) + midl_user_free(DecryptedCurrentValue); + + if (DecryptedOldValue != NULL) + midl_user_free(DecryptedOldValue); + + if (CurrentValue != NULL) + *CurrentValue = NULL; + + if (OldValue != NULL) + *OldValue = NULL; + } + + if (EncryptedCurrentValue != NULL) + midl_user_free(EncryptedCurrentValue); + + if (EncryptedOldValue != NULL) + midl_user_free(EncryptedOldValue); + + return Status; +} + + /* * @unimplemented */ diff --git a/reactos/dll/win32/lsasrv/lsarpc.c b/reactos/dll/win32/lsasrv/lsarpc.c index 169383e9cd8..4c8876651b6 100644 --- a/reactos/dll/win32/lsasrv/lsarpc.c +++ b/reactos/dll/win32/lsasrv/lsarpc.c @@ -1262,6 +1262,9 @@ NTSTATUS WINAPI LsarSetSecret( LARGE_INTEGER Time; NTSTATUS Status; + TRACE("LsarSetSecret(%p %p %p)\n", SecretHandle, + EncryptedCurrentValue, EncryptedOldValue); + /* Validate the SecretHandle */ Status = LsapValidateDbObject(SecretHandle, LsaDbSecretObject, @@ -1351,8 +1354,175 @@ NTSTATUS WINAPI LsarQuerySecret( PLSAPR_CR_CIPHER_VALUE *EncryptedOldValue, PLARGE_INTEGER OldValueSetTime) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PLSA_DB_OBJECT SecretObject; + PLSAPR_CR_CIPHER_VALUE EncCurrentValue = NULL; + PLSAPR_CR_CIPHER_VALUE EncOldValue = NULL; + PBYTE CurrentValue = NULL; + PBYTE OldValue = NULL; + ULONG CurrentValueLength = 0; + ULONG OldValueLength = 0; + ULONG BufferSize; + NTSTATUS Status; + + TRACE("LsarQuerySecret(%p %p %p %p %p)\n", SecretHandle, + EncryptedCurrentValue, CurrentValueSetTime, + EncryptedOldValue, OldValueSetTime); + + /* Validate the SecretHandle */ + Status = LsapValidateDbObject(SecretHandle, + LsaDbSecretObject, + SECRET_QUERY_VALUE, + &SecretObject); + if (!NT_SUCCESS(Status)) + { + ERR("LsapValidateDbObject returned 0x%08lx\n", Status); + return Status; + } + + if (EncryptedCurrentValue != NULL) + { + CurrentValueLength = 0; + + /* Get the size of the current value */ + Status = LsapGetObjectAttribute(SecretObject, + L"CurrentValue", + NULL, + &CurrentValueLength); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the current value */ + CurrentValue = midl_user_allocate(CurrentValueLength); + if (CurrentValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* Get the current value */ + Status = LsapGetObjectAttribute(SecretObject, + L"CurrentValue", + CurrentValue, + &CurrentValueLength); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the encrypted current value */ + EncCurrentValue = midl_user_allocate(sizeof(LSAPR_CR_CIPHER_VALUE)); + if (EncCurrentValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* FIXME: Encrypt the current value */ + EncCurrentValue->Length = (USHORT)(CurrentValueLength - sizeof(WCHAR)); + EncCurrentValue->MaximumLength = (USHORT)CurrentValueLength; + EncCurrentValue->Buffer = (PBYTE)CurrentValue; + } + + if (CurrentValueSetTime != NULL) + { + BufferSize = sizeof(LARGE_INTEGER); + + /* Get the current value time */ + Status = LsapGetObjectAttribute(SecretObject, + L"CurrentTime", + (PBYTE)CurrentValueSetTime, + &BufferSize); + if (!NT_SUCCESS(Status)) + goto done; + } + + if (EncryptedOldValue != NULL) + { + OldValueLength = 0; + + /* Get the size of the old value */ + Status = LsapGetObjectAttribute(SecretObject, + L"OldValue", + NULL, + &OldValueLength); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the old value */ + OldValue = midl_user_allocate(OldValueLength); + if (OldValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* Get the old value */ + Status = LsapGetObjectAttribute(SecretObject, + L"OldValue", + OldValue, + &OldValueLength); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the encrypted old value */ + EncOldValue = midl_user_allocate(sizeof(LSAPR_CR_CIPHER_VALUE) + OldValueLength); + if (EncOldValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* FIXME: Encrypt the old value */ + EncOldValue->Length = (USHORT)(OldValueLength - sizeof(WCHAR)); + EncOldValue->MaximumLength = (USHORT)OldValueLength; + EncOldValue->Buffer = (PBYTE)OldValue; + } + + if (OldValueSetTime != NULL) + { + BufferSize = sizeof(LARGE_INTEGER); + + /* Get the old value time */ + Status = LsapGetObjectAttribute(SecretObject, + L"OldTime", + (PBYTE)OldValueSetTime, + &BufferSize); + if (!NT_SUCCESS(Status)) + goto done; + } + + +done: + if (NT_SUCCESS(Status)) + { + if (EncryptedCurrentValue != NULL) + *EncryptedCurrentValue = EncCurrentValue; + + if (EncryptedOldValue != NULL) + *EncryptedOldValue = EncOldValue; + } + else + { + if (EncryptedCurrentValue != NULL) + *EncryptedCurrentValue = NULL; + + if (EncryptedOldValue != NULL) + *EncryptedOldValue = NULL; + + if (EncCurrentValue != NULL) + midl_user_free(EncCurrentValue); + + if (EncOldValue != NULL) + midl_user_free(EncOldValue); + + if (CurrentValue != NULL) + midl_user_free(CurrentValue); + + if (OldValue != NULL) + midl_user_free(OldValue); + } + + TRACE("LsarQuerySecret done (Status 0x%08lx)\n", Status); + + return Status; } diff --git a/reactos/include/psdk/ntsecapi.h b/reactos/include/psdk/ntsecapi.h index 3f6259ac0a4..9da7332f1a1 100644 --- a/reactos/include/psdk/ntsecapi.h +++ b/reactos/include/psdk/ntsecapi.h @@ -721,6 +721,8 @@ NTSTATUS NTAPI LsaQueryDomainInformationPolicy(LSA_HANDLE, NTSTATUS NTAPI LsaQueryInformationPolicy(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*); NTSTATUS NTAPI LsaQueryLocalInformationPolicy(LSA_HANDLE, POLICY_LOCAL_INFORMATION_CLASS,PVOID*); +NTSTATUS NTAPI LsaQuerySecret(LSA_HANDLE,PLSA_UNICODE_STRING*,PLARGE_INTEGER, + PLSA_UNICODE_STRING*,PLARGE_INTEGER); NTSTATUS NTAPI LsaQueryTrustedDomainInfo(LSA_HANDLE,PSID, TRUSTED_INFORMATION_CLASS,PVOID*); NTSTATUS NTAPI LsaQueryTrustedDomainInfoByName(LSA_HANDLE,PLSA_UNICODE_STRING,