[SAMLIB]
authorEric Kohl <eric.kohl@reactos.org>
Sun, 18 Aug 2013 13:26:33 +0000 (13:26 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 18 Aug 2013 13:26:33 +0000 (13:26 +0000)
SamSetInformationUser.UserAllInformation: Pass hashed passwords to SamrSetInformationUser.

[SAMSRV]
SampSetUserAll:
- Get fixed user data at the start of the function and set it only if it has been modified.
- Set user password hashes.

svn path=/trunk/; revision=59770

reactos/dll/win32/samlib/samlib.c
reactos/dll/win32/samsrv/samrpc.c

index 961e2a5..471de04 100644 (file)
@@ -1847,7 +1847,7 @@ SamSetInformationUser(IN SAM_HANDLE UserHandle,
 {
     PSAMPR_USER_SET_PASSWORD_INFORMATION PasswordBuffer;
     SAMPR_USER_INTERNAL1_INFORMATION Internal1Buffer;
-    PUSER_ALL_INFORMATION AllBuffer;
+    USER_ALL_INFORMATION InternalAllBuffer;
     OEM_STRING LmPwdString;
     CHAR LmPwdBuffer[15];
     NTSTATUS Status;
@@ -1914,23 +1914,118 @@ SamSetInformationUser(IN SAM_HANDLE UserHandle,
         if (!NT_SUCCESS(Status))
         {
             TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status);
-            return Status;
         }
+
+        return Status;
     }
     else if (UserInformationClass == UserAllInformation)
     {
-        AllBuffer = (PUSER_ALL_INFORMATION)Buffer;
+        RtlCopyMemory(&InternalAllBuffer,
+                      Buffer,
+                      sizeof(USER_ALL_INFORMATION));
 
-        if (AllBuffer->WhichFields & (USER_ALL_LMPASSWORDPRESENT | USER_ALL_NTPASSWORDPRESENT))
+        if (InternalAllBuffer.WhichFields & (USER_ALL_LMPASSWORDPRESENT | USER_ALL_NTPASSWORDPRESENT))
         {
-            Status = SampCheckPassword(UserHandle,
-                                       &AllBuffer->NtPassword);
-            if (!NT_SUCCESS(Status))
+            if (InternalAllBuffer.WhichFields & USER_ALL_OWFPASSWORD)
             {
-                TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status);
-                return Status;
+                /* Check NT password hash */
+                if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT)
+                {
+                    if (InternalAllBuffer.NtPassword.Length != sizeof(ENCRYPTED_NT_OWF_PASSWORD))
+                        return STATUS_INVALID_PARAMETER;
+                }
+
+                /* Check LM password hash */
+                if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT)
+                {
+                    if (InternalAllBuffer.LmPassword.Length != sizeof(ENCRYPTED_LM_OWF_PASSWORD))
+                        return STATUS_INVALID_PARAMETER;
+                }
             }
+            else
+            {
+                /*
+                 * Only allow the NT password to be set.
+                 * The LM password will be created here.
+                 */
+                if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT)
+                {
+                    TRACE("Do not try to set a clear text LM password!\n");
+                    return STATUS_INVALID_PARAMETER;
+                }
+
+                if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT)
+                {
+                    Status = SampCheckPassword(UserHandle,
+                                               &InternalAllBuffer.NtPassword);
+                    if (!NT_SUCCESS(Status))
+                    {
+                        TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status);
+                        return Status;
+                    }
+
+                    /* Calculate the NT password hash */
+                    Status = SystemFunction007((PUNICODE_STRING)&InternalAllBuffer.NtPassword,
+                                               (LPBYTE)&Internal1Buffer.EncryptedNtOwfPassword);
+                    if (!NT_SUCCESS(Status))
+                    {
+                        TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
+                        return Status;
+                    }
+
+                    InternalAllBuffer.NtPasswordPresent = TRUE;
+                    InternalAllBuffer.LmPasswordPresent = FALSE;
+
+                    InternalAllBuffer.NtPassword.Length = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+                    InternalAllBuffer.NtPassword.MaximumLength = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+                    InternalAllBuffer.NtPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedNtOwfPassword;
+
+                    /* Build the LM password */
+                    LmPwdString.Length = 15;
+                    LmPwdString.MaximumLength = 15;
+                    LmPwdString.Buffer = LmPwdBuffer;
+                    ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
+
+                    Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
+                                                               (PUNICODE_STRING)&InternalAllBuffer.NtPassword,
+                                                               FALSE);
+                    if (NT_SUCCESS(Status))
+                    {
+                        /* Calculate the LM password hash */
+                        Status = SystemFunction006(LmPwdString.Buffer,
+                                                   (LPSTR)&Internal1Buffer.EncryptedLmOwfPassword);
+                        if (NT_SUCCESS(Status))
+                        {
+                            InternalAllBuffer.WhichFields |= USER_ALL_LMPASSWORDPRESENT;
+                            InternalAllBuffer.LmPasswordPresent = TRUE;
+
+                            InternalAllBuffer.LmPassword.Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+                            InternalAllBuffer.LmPassword.MaximumLength = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+                            InternalAllBuffer.LmPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedLmOwfPassword;
+                        }
+                    }
+                }
+            }
+        }
+
+        RpcTryExcept
+        {
+            Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
+                                            UserAllInformation,
+                                            (PVOID)&InternalAllBuffer);
+        }
+        RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = I_RpcMapWin32Status(RpcExceptionCode());
         }
+        RpcEndExcept;
+
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status);
+        }
+
+        return Status;
     }
 
     RpcTryExcept
index 0f4ac20..3c8a952 100644 (file)
@@ -7115,10 +7115,25 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject,
     SAM_USER_FIXED_DATA FixedData;
     ULONG Length = 0;
     ULONG WhichFields;
+    PENCRYPTED_NT_OWF_PASSWORD NtPassword = NULL;
+    PENCRYPTED_LM_OWF_PASSWORD LmPassword = NULL;
+    BOOLEAN NtPasswordPresent = FALSE;
+    BOOLEAN LmPasswordPresent = FALSE;
+    BOOLEAN WriteFixedData = FALSE;
     NTSTATUS Status = STATUS_SUCCESS;
 
     WhichFields = Buffer->All.WhichFields;
 
+    /* Get the fixed size attributes */
+    Length = sizeof(SAM_USER_FIXED_DATA);
+    Status = SampGetObjectAttribute(UserObject,
+                                    L"F",
+                                    NULL,
+                                    (PVOID)&FixedData,
+                                    &Length);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
     if (WhichFields & USER_ALL_USERNAME)
     {
         Status = SampSetUserName(UserObject,
@@ -7234,39 +7249,72 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject,
             goto done;
     }
 
-    if (WhichFields & (USER_ALL_PRIMARYGROUPID |
-                       USER_ALL_ACCOUNTEXPIRES |
-                       USER_ALL_USERACCOUNTCONTROL |
-                       USER_ALL_COUNTRYCODE |
-                       USER_ALL_CODEPAGE))
+    if (WhichFields & USER_ALL_PRIMARYGROUPID)
     {
-        Length = sizeof(SAM_USER_FIXED_DATA);
-        Status = SampGetObjectAttribute(UserObject,
-                                        L"F",
-                                        NULL,
-                                        (PVOID)&FixedData,
-                                        &Length);
-        if (!NT_SUCCESS(Status))
-            goto done;
+        FixedData.PrimaryGroupId = Buffer->All.PrimaryGroupId;
+        WriteFixedData = TRUE;
+    }
 
-        if (WhichFields & USER_ALL_PRIMARYGROUPID)
-            FixedData.PrimaryGroupId = Buffer->All.PrimaryGroupId;
+    if (WhichFields & USER_ALL_ACCOUNTEXPIRES)
+    {
+        FixedData.AccountExpires.LowPart = Buffer->All.AccountExpires.LowPart;
+        FixedData.AccountExpires.HighPart = Buffer->All.AccountExpires.HighPart;
+        WriteFixedData = TRUE;
+    }
 
-        if (WhichFields & USER_ALL_ACCOUNTEXPIRES)
+    if (WhichFields & USER_ALL_USERACCOUNTCONTROL)
+    {
+        FixedData.UserAccountControl = Buffer->All.UserAccountControl;
+        WriteFixedData = TRUE;
+    }
+
+    if (WhichFields & USER_ALL_COUNTRYCODE)
+    {
+        FixedData.CountryCode = Buffer->All.CountryCode;
+        WriteFixedData = TRUE;
+    }
+
+    if (WhichFields & USER_ALL_CODEPAGE)
+    {
+        FixedData.CodePage = Buffer->All.CodePage;
+        WriteFixedData = TRUE;
+    }
+
+    if (WhichFields & (USER_ALL_NTPASSWORDPRESENT |
+                       USER_ALL_LMPASSWORDPRESENT))
+    {
+        if (WhichFields & USER_ALL_NTPASSWORDPRESENT)
         {
-            FixedData.AccountExpires.LowPart = Buffer->All.AccountExpires.LowPart;
-            FixedData.AccountExpires.HighPart = Buffer->All.AccountExpires.HighPart;
+            NtPassword = (PENCRYPTED_NT_OWF_PASSWORD)Buffer->All.NtOwfPassword.Buffer;
+            NtPasswordPresent = Buffer->All.NtPasswordPresent;
         }
 
-        if (WhichFields & USER_ALL_USERACCOUNTCONTROL)
-            FixedData.UserAccountControl = Buffer->All.UserAccountControl;
+        if (WhichFields & USER_ALL_LMPASSWORDPRESENT)
+        {
+            LmPassword = (PENCRYPTED_LM_OWF_PASSWORD)Buffer->All.LmOwfPassword.Buffer;
+            LmPasswordPresent = Buffer->All.LmPasswordPresent;
+        }
+
+        Status = SampSetUserPassword(UserObject,
+                                     NtPassword,
+                                     NtPasswordPresent,
+                                     LmPassword,
+                                     LmPasswordPresent);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        /* The password has just been set */
+        Status = NtQuerySystemTime(&FixedData.PasswordLastSet);
+        if (!NT_SUCCESS(Status))
+            goto done;
 
-        if (WhichFields & USER_ALL_COUNTRYCODE)
-            FixedData.CountryCode = Buffer->Preferences.CountryCode;
+        WriteFixedData = TRUE;
+    }
 
-        if (WhichFields & USER_ALL_CODEPAGE)
-            FixedData.CodePage = Buffer->Preferences.CodePage;
+    /* FIXME: USER_ALL_PASSWORDEXPIRED */
 
+    if (WriteFixedData == TRUE)
+    {
         Status = SampSetObjectAttribute(UserObject,
                                         L"F",
                                         REG_BINARY,
@@ -7276,15 +7324,7 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject,
             goto done;
     }
 
-/*
-FIXME:
-    USER_ALL_NTPASSWORDPRESENT
-    USER_ALL_LMPASSWORDPRESENT
-    USER_ALL_PASSWORDEXPIRED
-*/
-
 done:
-
     return Status;
 }