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
This commit is contained in:
Eric Kohl
2013-08-18 13:26:33 +00:00
parent cb93ccc1d2
commit 5d3a6f8098
2 changed files with 178 additions and 43 deletions
+104 -9
View 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
+74 -34
View 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);
FixedData.PrimaryGroupId = Buffer->All.PrimaryGroupId;
WriteFixedData = TRUE;
}
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_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)
{
NtPassword = (PENCRYPTED_NT_OWF_PASSWORD)Buffer->All.NtOwfPassword.Buffer;
NtPasswordPresent = Buffer->All.NtPasswordPresent;
}
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;
if (WhichFields & USER_ALL_PRIMARYGROUPID)
FixedData.PrimaryGroupId = Buffer->All.PrimaryGroupId;
/* The password has just been set */
Status = NtQuerySystemTime(&FixedData.PasswordLastSet);
if (!NT_SUCCESS(Status))
goto done;
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_USERACCOUNTCONTROL)
FixedData.UserAccountControl = Buffer->All.UserAccountControl;
if (WhichFields & USER_ALL_COUNTRYCODE)
FixedData.CountryCode = Buffer->Preferences.CountryCode;
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;
}