Author: ekohl
Date: Sun Jan 3 09:22:14 2016
New Revision: 70479
URL:
http://svn.reactos.org/svn/reactos?rev=70479&view=rev
Log:
[LSASRV]
Implement LsarStorePrivateData and LsarRetrievePrivateData.
[ADVAPI32]
Implement LsaRetrievePrivateData and LsaStorePrivateData.
Encryption of secrets (aka private data) is NOT implemented yet!
Modified:
trunk/reactos/dll/win32/advapi32/sec/lsa.c
trunk/reactos/dll/win32/lsasrv/lsarpc.c
Modified: trunk/reactos/dll/win32/advapi32/sec/lsa.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/sec/lsa…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/sec/lsa.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/sec/lsa.c [iso-8859-1] Sun Jan 3 09:22:14 2016
@@ -1400,7 +1400,7 @@
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
WINAPI
@@ -1683,7 +1683,7 @@
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
WINAPI
@@ -1691,9 +1691,64 @@
IN PLSA_UNICODE_STRING KeyName,
OUT PLSA_UNICODE_STRING *PrivateData)
{
- FIXME("LsaRetrievePrivateData(%p %p %p) stub\n",
+ PLSAPR_CR_CIPHER_VALUE EncryptedData = NULL;
+ PLSA_UNICODE_STRING DecryptedData = NULL;
+ SIZE_T BufferSize;
+ NTSTATUS Status;
+
+ TRACE("LsaRetrievePrivateData(%p %p %p)\n",
PolicyHandle, KeyName, PrivateData);
- return STATUS_OBJECT_NAME_NOT_FOUND;
+
+ RpcTryExcept
+ {
+ Status = LsarRetrievePrivateData((LSAPR_HANDLE)PolicyHandle,
+ (PRPC_UNICODE_STRING)KeyName,
+ &EncryptedData);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+
+ if (EncryptedData == NULL)
+ {
+ *PrivateData = NULL;
+ }
+ else
+ {
+ BufferSize = sizeof(LSA_UNICODE_STRING) + EncryptedData->MaximumLength;
+ DecryptedData = midl_user_allocate(BufferSize);
+ if (DecryptedData == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ DecryptedData->Length = (USHORT)EncryptedData->Length;
+ DecryptedData->MaximumLength = (USHORT)EncryptedData->MaximumLength;
+ DecryptedData->Buffer = (PWSTR)(DecryptedData + 1);
+ RtlCopyMemory(DecryptedData->Buffer,
+ EncryptedData->Buffer,
+ EncryptedData->Length);
+
+ *PrivateData = DecryptedData;
+ }
+
+done:
+ if (!NT_SUCCESS(Status))
+ {
+ if (DecryptedData != NULL)
+ midl_user_free(DecryptedData);
+
+ *PrivateData = NULL;
+ }
+
+ if (EncryptedData != NULL)
+ midl_user_free(EncryptedData);
+
+ return Status;
}
@@ -2024,7 +2079,7 @@
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
WINAPI
@@ -2032,9 +2087,49 @@
IN PLSA_UNICODE_STRING KeyName,
IN PLSA_UNICODE_STRING PrivateData OPTIONAL)
{
- FIXME("LsaStorePrivateData(%p %p %p) stub\n",
+ PLSAPR_CR_CIPHER_VALUE EncryptedData = NULL;
+ SIZE_T BufferSize;
+ NTSTATUS Status;
+
+ TRACE("LsaStorePrivateData(%p %p %p)\n",
PolicyHandle, KeyName, PrivateData);
- return STATUS_OBJECT_NAME_NOT_FOUND;
+
+ if (PrivateData != NULL)
+ {
+ BufferSize = sizeof(LSAPR_CR_CIPHER_VALUE) + PrivateData->MaximumLength;
+ EncryptedData = midl_user_allocate(BufferSize);
+ if (EncryptedData == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ EncryptedData->Length = PrivateData->Length;
+ EncryptedData->MaximumLength = PrivateData->MaximumLength;
+ EncryptedData->Buffer = (BYTE *)(EncryptedData + 1);
+ if (EncryptedData->Buffer != NULL)
+ RtlCopyMemory(EncryptedData->Buffer,
+ PrivateData->Buffer,
+ PrivateData->Length);
+ }
+
+ RpcTryExcept
+ {
+ Status = LsarStorePrivateData((LSAPR_HANDLE)PolicyHandle,
+ (PRPC_UNICODE_STRING)KeyName,
+ EncryptedData);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+done:
+ if (EncryptedData != NULL)
+ midl_user_free(EncryptedData);
+
+ return Status;
}
/* EOF */
Modified: trunk/reactos/dll/win32/lsasrv/lsarpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/lsasrv/lsarpc.c?…
==============================================================================
--- trunk/reactos/dll/win32/lsasrv/lsarpc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/lsasrv/lsarpc.c [iso-8859-1] Sun Jan 3 09:22:14 2016
@@ -2386,8 +2386,151 @@
PRPC_UNICODE_STRING KeyName,
PLSAPR_CR_CIPHER_VALUE EncryptedData)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PLSA_DB_OBJECT PolicyObject = NULL;
+ PLSA_DB_OBJECT SecretsObject = NULL;
+ PLSA_DB_OBJECT SecretObject = NULL;
+ LARGE_INTEGER Time;
+ PBYTE Value = NULL;
+ ULONG ValueLength = 0;
+ NTSTATUS Status;
+
+ TRACE("LsarStorePrivateData(%p %p %p)\n",
+ PolicyHandle, KeyName, EncryptedData);
+
+ /* Validate the SecretHandle */
+ Status = LsapValidateDbObject(PolicyHandle,
+ LsaDbPolicyObject,
+ POLICY_CREATE_SECRET,
+ &PolicyObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* Open the 'Secrets' object */
+ Status = LsapOpenDbObject(PolicyObject,
+ NULL,
+ L"Secrets",
+ LsaDbIgnoreObject,
+ 0,
+ PolicyObject->Trusted,
+ &SecretsObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ if (EncryptedData == NULL)
+ {
+ /* Open the Secret object */
+ Status = LsapOpenDbObject(SecretsObject,
+ NULL,
+ KeyName->Buffer,
+ LsaDbSecretObject,
+ 0,
+ PolicyObject->Trusted,
+ &SecretObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Delete the secret */
+ Status = LsapDeleteDbObject(SecretObject);
+ if (NT_SUCCESS(Status))
+ SecretObject = NULL;
+ }
+ else
+ {
+ /* Create the Secret object */
+ Status = LsapCreateDbObject(SecretsObject,
+ NULL,
+ KeyName->Buffer,
+ LsaDbSecretObject,
+ 0,
+ PolicyObject->Trusted,
+ &SecretObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapCreateDbObject failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* FIXME: Decrypt data */
+ Value = EncryptedData->Buffer;
+ ValueLength = EncryptedData->MaximumLength;
+
+ /* Get the current time */
+ Status = NtQuerySystemTime(&Time);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Set the current value */
+ Status = LsapSetObjectAttribute(SecretObject,
+ L"CurrentValue",
+ Value,
+ ValueLength);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapSetObjectAttribute 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;
+ }
+
+ /* Get the current time */
+ Status = NtQuerySystemTime(&Time);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Set the old value */
+ Status = LsapSetObjectAttribute(SecretObject,
+ L"OldValue",
+ NULL,
+ 0);
+ 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:
+ if (SecretObject != NULL)
+ LsapCloseDbObject(SecretObject);
+
+ if (SecretsObject != NULL)
+ LsapCloseDbObject(SecretsObject);
+
+ return Status;
}
@@ -2397,8 +2540,97 @@
PRPC_UNICODE_STRING KeyName,
PLSAPR_CR_CIPHER_VALUE *EncryptedData)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PLSA_DB_OBJECT PolicyObject = NULL;
+ PLSA_DB_OBJECT SecretObject = NULL;
+ PLSAPR_CR_CIPHER_VALUE EncCurrentValue = NULL;
+ ULONG CurrentValueLength = 0;
+ PBYTE CurrentValue = NULL;
+ NTSTATUS Status;
+
+ /* Validate the SecretHandle */
+ Status = LsapValidateDbObject(PolicyHandle,
+ LsaDbPolicyObject,
+ POLICY_CREATE_SECRET,
+ &PolicyObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* Open the secret object */
+ Status = LsapOpenDbObject(PolicyObject,
+ L"Secrets",
+ KeyName->Buffer,
+ LsaDbSecretObject,
+ 0,
+ PolicyObject->Trusted,
+ &SecretObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* 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) +
CurrentValueLength);
+ 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)(EncCurrentValue + 1);
+ RtlCopyMemory(EncCurrentValue->Buffer,
+ CurrentValue,
+ CurrentValueLength);
+
+done:
+ if (NT_SUCCESS(Status))
+ {
+ if (EncryptedData != NULL)
+ *EncryptedData = EncCurrentValue;
+ }
+ else
+ {
+ if (EncryptedData != NULL)
+ *EncryptedData = NULL;
+
+ if (EncCurrentValue != NULL)
+ midl_user_free(EncCurrentValue);
+
+ if (SecretObject != NULL)
+ LsapCloseDbObject(SecretObject);
+ }
+
+ return Status;
}