diff --git a/reactos/dll/win32/advapi32/advapi32.spec b/reactos/dll/win32/advapi32/advapi32.spec index e770be0b61f..8098c2cc0fe 100644 --- a/reactos/dll/win32/advapi32/advapi32.spec +++ b/reactos/dll/win32/advapi32/advapi32.spec @@ -402,7 +402,7 @@ @ stub LsaSetQuotasForAccount @ stdcall LsaSetSecret(ptr ptr ptr) @ stub LsaSetSecurityObject -@ stub LsaSetSystemAccessAccount +@ stdcall LsaSetSystemAccessAccount(ptr long) @ stdcall LsaSetTrustedDomainInfoByName(ptr ptr long ptr) @ stdcall LsaSetTrustedDomainInformation(ptr ptr long ptr) @ stdcall LsaStorePrivateData(ptr ptr ptr) diff --git a/reactos/dll/win32/advapi32/sec/lsa.c b/reactos/dll/win32/advapi32/sec/lsa.c index d6587d185b1..24960c1f592 100644 --- a/reactos/dll/win32/advapi32/sec/lsa.c +++ b/reactos/dll/win32/advapi32/sec/lsa.c @@ -1027,7 +1027,8 @@ LsaRemoveAccountRights(IN LSA_HANDLE PolicyHandle, { LSAPR_USER_RIGHT_SET UserRightSet; - TRACE("(%p,%p,%d,%p,0x%08x) stub\n", PolicyHandle, AccountSid, AllRights, UserRights, CountOfRights); + TRACE("LsaRemoveAccountRights(%p %p %d %p 0x%08x) stub\n", + PolicyHandle, AccountSid, AllRights, UserRights, CountOfRights); UserRightSet.Entries = CountOfRights; UserRightSet.UserRights = (PRPC_UNICODE_STRING)UserRights; @@ -1089,7 +1090,8 @@ LsaSetInformationPolicy(IN LSA_HANDLE PolicyHandle, { NTSTATUS Status; - TRACE("(%p,0x%08x,%p)\n", PolicyHandle, InformationClass, Buffer); + TRACE("LsaSetInformationPolicy(%p 0x%08x %p)\n", + PolicyHandle, InformationClass, Buffer); RpcTryExcept { @@ -1108,18 +1110,107 @@ LsaSetInformationPolicy(IN LSA_HANDLE PolicyHandle, /* - * @unimplemented + * @implemented */ -NTSTATUS WINAPI LsaSetSecret( - IN LSA_HANDLE SecretHandle, - IN PLSA_UNICODE_STRING EncryptedCurrentValue, - IN PLSA_UNICODE_STRING EncryptedOldValue) +NTSTATUS +WINAPI +LsaSetSecret(IN LSA_HANDLE SecretHandle, + IN PLSA_UNICODE_STRING CurrentValue OPTIONAL, + IN PLSA_UNICODE_STRING OldValue OPTIONAL) { - FIXME("(%p,%p,%p) stub\n", SecretHandle, EncryptedCurrentValue, - EncryptedOldValue); - return STATUS_SUCCESS; + PLSAPR_CR_CIPHER_VALUE EncryptedCurrentValue = NULL; + PLSAPR_CR_CIPHER_VALUE EncryptedOldValue = NULL; + SIZE_T BufferSize; + NTSTATUS Status; + + TRACE("LsaSetSecret(%p,%p,%p)\n", + SecretHandle, EncryptedCurrentValue, EncryptedOldValue); + + if (CurrentValue != NULL) + { + BufferSize = sizeof(LSAPR_CR_CIPHER_VALUE) + CurrentValue->MaximumLength; + EncryptedCurrentValue = midl_user_allocate(BufferSize); + if (EncryptedCurrentValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + EncryptedCurrentValue->Length = CurrentValue->Length; + EncryptedCurrentValue->MaximumLength = CurrentValue->MaximumLength; + EncryptedCurrentValue->Buffer = (BYTE *)(EncryptedCurrentValue + 1); + if (EncryptedCurrentValue->Buffer != NULL) + memcpy(EncryptedCurrentValue->Buffer, CurrentValue->Buffer, CurrentValue->Length); + } + + if (OldValue != NULL) + { + BufferSize = sizeof(LSAPR_CR_CIPHER_VALUE) + OldValue->MaximumLength; + EncryptedOldValue = midl_user_allocate(BufferSize); + if (EncryptedOldValue == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + EncryptedOldValue->Length = OldValue->Length; + EncryptedOldValue->MaximumLength = OldValue->MaximumLength; + EncryptedOldValue->Buffer = (BYTE*)(EncryptedOldValue + 1); + if (EncryptedOldValue->Buffer != NULL) + memcpy(EncryptedOldValue->Buffer, OldValue->Buffer, OldValue->Length); + } + + RpcTryExcept + { + Status = LsarSetSecret((LSAPR_HANDLE)SecretHandle, + EncryptedCurrentValue, + EncryptedOldValue); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + +done: + if (EncryptedCurrentValue != NULL) + midl_user_free(EncryptedCurrentValue); + + if (EncryptedOldValue != NULL) + midl_user_free(EncryptedOldValue); + + return Status; } + +/* + * @implemented + */ +NTSTATUS +WINAPI +LsaSetSystemAccessAccount(IN LSA_HANDLE AccountHandle, + IN ULONG SystemAccess) +{ + NTSTATUS Status; + + TRACE("LsaSetSystemAccessAccount(%p 0x%lx)\n", + AccountHandle, SystemAccess); + + RpcTryExcept + { + Status = LsarSetSystemAccessAccount((LSAPR_HANDLE)AccountHandle, + SystemAccess); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + /* * @unimplemented */ diff --git a/reactos/dll/win32/lsasrv/lsarpc.c b/reactos/dll/win32/lsasrv/lsarpc.c index 1631143db42..2e7149eace8 100644 --- a/reactos/dll/win32/lsasrv/lsarpc.c +++ b/reactos/dll/win32/lsasrv/lsarpc.c @@ -1193,12 +1193,96 @@ done: /* Function 29 */ NTSTATUS WINAPI LsarSetSecret( - LSAPR_HANDLE *SecretHandle, + LSAPR_HANDLE SecretHandle, PLSAPR_CR_CIPHER_VALUE EncryptedCurrentValue, PLSAPR_CR_CIPHER_VALUE EncryptedOldValue) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PLSA_DB_OBJECT SecretObject; + PBYTE CurrentValue = NULL; + PBYTE OldValue = NULL; + ULONG CurrentValueLength = 0; + ULONG OldValueLength = 0; + LARGE_INTEGER Time; + NTSTATUS Status; + + /* Validate the SecretHandle */ + Status = LsapValidateDbObject(SecretHandle, + LsaDbSecretObject, + SECRET_SET_VALUE, + &SecretObject); + if (!NT_SUCCESS(Status)) + { + ERR("LsapValidateDbObject returned 0x%08lx\n", Status); + return Status; + } + + if (EncryptedCurrentValue != NULL) + { + /* FIXME: Decrypt the current value */ + CurrentValue = EncryptedCurrentValue->Buffer; + CurrentValueLength = EncryptedCurrentValue->MaximumLength; + } + + /* Set the current value */ + Status = LsapSetObjectAttribute(SecretObject, + L"CurrentValue", + CurrentValue, + CurrentValueLength); + if (!NT_SUCCESS(Status)) + { + ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Get the current time */ + Status = NtQuerySystemTime(&Time); + if (!NT_SUCCESS(Status)) + { + ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Set the current time */ + Status = LsapSetObjectAttribute(SecretObject, + L"CurrentTime", + &Time, + sizeof(LARGE_INTEGER)); + if (!NT_SUCCESS(Status)) + { + ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status); + goto done; + } + + if (EncryptedOldValue != NULL) + { + /* FIXME: Decrypt the old value */ + OldValue = EncryptedOldValue->Buffer; + OldValueLength = EncryptedOldValue->MaximumLength; + } + + /* Set the old value */ + Status = LsapSetObjectAttribute(SecretObject, + L"OldValue", + OldValue, + OldValueLength); + if (!NT_SUCCESS(Status)) + { + ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Set the old time */ + Status = LsapSetObjectAttribute(SecretObject, + L"OldTime", + &Time, + sizeof(LARGE_INTEGER)); + if (!NT_SUCCESS(Status)) + { + ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status); + } + +done: + return Status; } diff --git a/reactos/include/psdk/ntlsa.h b/reactos/include/psdk/ntlsa.h index 3202f1e0732..5f8d969d2ae 100644 --- a/reactos/include/psdk/ntlsa.h +++ b/reactos/include/psdk/ntlsa.h @@ -30,6 +30,8 @@ extern "C" { #define ACCOUNT_ADJUST_QUOTAS 4 #define ACCOUNT_ADJUST_SYSTEM_ACCESS 8 +#define SECRET_SET_VALUE 1 +#define SECRET_QUERY_VALUE 2 #ifdef __cplusplus diff --git a/reactos/include/psdk/ntsecapi.h b/reactos/include/psdk/ntsecapi.h index 765a137902d..3f6259ac0a4 100644 --- a/reactos/include/psdk/ntsecapi.h +++ b/reactos/include/psdk/ntsecapi.h @@ -735,6 +735,7 @@ NTSTATUS NTAPI LsaSetDomainInformationPolicy(LSA_HANDLE, NTSTATUS NTAPI LsaSetInformationPolicy(LSA_HANDLE,POLICY_INFORMATION_CLASS, PVOID); NTSTATUS NTAPI LsaSetLocalInformationPolicy(LSA_HANDLE, POLICY_LOCAL_INFORMATION_CLASS,PVOID); +NTSTATUS NTAPI LsaSetSecret(LSA_HANDLE, PLSA_UNICODE_STRING, PLSA_UNICODE_STRING); NTSTATUS NTAPI LsaSetSystemAccessAccount(LSA_HANDLE, ULONG); NTSTATUS NTAPI LsaSetTrustedDomainInformation(LSA_HANDLE,PSID, TRUSTED_INFORMATION_CLASS,PVOID); diff --git a/reactos/include/reactos/idl/lsa.idl b/reactos/include/reactos/idl/lsa.idl index c1484b481c3..453bde89337 100644 --- a/reactos/include/reactos/idl/lsa.idl +++ b/reactos/include/reactos/idl/lsa.idl @@ -775,7 +775,7 @@ interface lsarpc /* Function 29 */ NTSTATUS __stdcall LsarSetSecret( - [in] LSAPR_HANDLE *SecretHandle, + [in] LSAPR_HANDLE SecretHandle, [in, unique] PLSAPR_CR_CIPHER_VALUE EncryptedCurrentValue, [in, unique] PLSAPR_CR_CIPHER_VALUE EncryptedOldValue);