* PROGRAMER: Eric Kohl
*/
-/* INCLUDES *****************************************************************/
-
#include "precomp.h"
+#define NTOS_MODE_USER
+#include <ndk/rtlfuncs.h>
+#include <ntsam.h>
+#include <sam_c.h>
+
+#include <wine/debug.h>
+
WINE_DEFAULT_DEBUG_CHANNEL(samlib);
NTSTATUS
SystemFunction007(PUNICODE_STRING string,
LPBYTE hash);
+NTSTATUS
+WINAPI
+SystemFunction012(const BYTE *in,
+ const BYTE *key,
+ LPBYTE out);
+
/* GLOBALS *******************************************************************/
IN PUNICODE_STRING Password)
{
USER_DOMAIN_PASSWORD_INFORMATION DomainPasswordInformation;
+ LPWORD CharTypeBuffer = NULL;
ULONG PasswordLength;
- NTSTATUS Status;
+ ULONG i;
+ ULONG Upper = 0, Lower = 0, Digit = 0, Punct = 0, Alpha = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%p %p)\n", UserHandle, Password);
/* Check the password complexity */
if (DomainPasswordInformation.PasswordProperties & DOMAIN_PASSWORD_COMPLEX)
{
- /* FIXME */
+ CharTypeBuffer = midl_user_allocate(PasswordLength * sizeof(WORD));
+ if (CharTypeBuffer == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ GetStringTypeW(CT_CTYPE1,
+ Password->Buffer,
+ PasswordLength,
+ CharTypeBuffer);
+
+ for (i = 0; i < PasswordLength; i++)
+ {
+ TRACE("%lu: %C %s %s %s %s\n", i, Password->Buffer[i],
+ (CharTypeBuffer[i] & C1_UPPER) ? "C1_UPPER" : " ",
+ (CharTypeBuffer[i] & C1_LOWER) ? "C1_LOWER" : " ",
+ (CharTypeBuffer[i] & C1_DIGIT) ? "C1_DIGIT" : " ",
+ (CharTypeBuffer[i] & C1_PUNCT) ? "C1_PUNCT" : " ",
+ (CharTypeBuffer[i] & C1_ALPHA) ? "C1_ALPHA" : " ");
+
+ if (CharTypeBuffer[i] & C1_UPPER)
+ Upper = 1;
+
+ if (CharTypeBuffer[i] & C1_LOWER)
+ Lower = 1;
+
+ if (CharTypeBuffer[i] & C1_DIGIT)
+ Digit = 1;
+
+ if (CharTypeBuffer[i] & C1_PUNCT)
+ Punct = 1;
+
+ if ((CharTypeBuffer[i] & C1_ALPHA) &&
+ !(CharTypeBuffer[i] & C1_UPPER) &&
+ !(CharTypeBuffer[i] & C1_LOWER))
+ Alpha = 1;
+ }
+
+ TRACE("Upper: %lu\n", Upper);
+ TRACE("Lower: %lu\n", Lower);
+ TRACE("Digit: %lu\n", Digit);
+ TRACE("Punct: %lu\n", Punct);
+ TRACE("Alpha: %lu\n", Alpha);
+
+ TRACE("Total: %lu\n", Upper + Lower + Digit + Punct + Alpha);
+ if (Upper + Lower + Digit + Punct + Alpha < 3)
+ Status = STATUS_PASSWORD_RESTRICTION;
}
- return STATUS_SUCCESS;
+ if (CharTypeBuffer != NULL)
+ midl_user_free(CharTypeBuffer);
+
+ return Status;
}
BOOLEAN NewLmPasswordPresent = FALSE;
NTSTATUS Status;
+ ENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm;
+ ENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm;
+ ENCRYPTED_LM_OWF_PASSWORD OldNtEncryptedWithNewNt;
+ ENCRYPTED_LM_OWF_PASSWORD NewNtEncryptedWithOldNt;
+ PENCRYPTED_LM_OWF_PASSWORD pOldLmEncryptedWithNewLm = NULL;
+ PENCRYPTED_LM_OWF_PASSWORD pNewLmEncryptedWithOldLm = NULL;
+
/* Calculate the NT hash for the old password */
Status = SystemFunction007(OldPassword,
(LPBYTE)&OldNtPassword);
}
}
+ if (OldLmPasswordPresent && NewLmPasswordPresent)
+ {
+ Status = SystemFunction012((const BYTE *)&OldLmPassword,
+ (const BYTE *)&NewLmPassword,
+ (LPBYTE)&OldLmEncryptedWithNewLm);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ Status = SystemFunction012((const BYTE *)&NewLmPassword,
+ (const BYTE *)&OldLmPassword,
+ (LPBYTE)&NewLmEncryptedWithOldLm);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ pOldLmEncryptedWithNewLm = &OldLmEncryptedWithNewLm;
+ pNewLmEncryptedWithOldLm = &NewLmEncryptedWithOldLm;
+ }
+
+ Status = SystemFunction012((const BYTE *)&OldNtPassword,
+ (const BYTE *)&NewNtPassword,
+ (LPBYTE)&OldNtEncryptedWithNewNt);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ Status = SystemFunction012((const BYTE *)&NewNtPassword,
+ (const BYTE *)&OldNtPassword,
+ (LPBYTE)&NewNtEncryptedWithOldNt);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
RpcTryExcept
{
Status = SamrChangePasswordUser((SAMPR_HANDLE)UserHandle,
OldLmPasswordPresent && NewLmPasswordPresent,
- &OldLmPassword,
- &NewLmPassword,
+ pOldLmEncryptedWithNewLm,
+ pNewLmEncryptedWithOldLm,
TRUE,
- &OldNtPassword,
- &NewNtPassword,
+ &OldNtEncryptedWithNewNt,
+ &NewNtEncryptedWithOldNt,
FALSE,
NULL,
FALSE,