Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

527 lines
16 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
password.cxx
Abstract:
password
Author:
Larry Zhu (LZhu) December 1, 2001 Created
Environment:
User Mode
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "password.hxx"
VOID
Usage(
IN PCSTR pszApp
)
{
DebugPrintf(SSPI_ERROR, "\n\nUsage: %s [-p<package>] [-s] [-l] -r "
"-c<client name> -C<client realm> -o<old password> -n<new password>\n"
"Remarks: package default to NTLM, use -s to set password, -l local only\n"
" -r not impernating (self)\n\n", pszApp);
exit(-1);
}
NTSTATUS
MsvChangePasswordUser(
IN HANDLE LogonHandle,
IN ULONG PackageId,
IN BOOLEAN bCacheOnly,
IN UNICODE_STRING* pDomainName,
IN UNICODE_STRING* pUserName,
IN UNICODE_STRING* pOldPassword,
IN UNICODE_STRING* pNewPassword,
IN BOOLEAN bImpersonating
)
{
TNtStatus Status = STATUS_UNSUCCESSFUL;
NTSTATUS SubStatus = STATUS_UNSUCCESSFUL;
MSV1_0_CHANGEPASSWORD_RESPONSE* pResponse = NULL ;
ULONG cbResponseSize;
MSV1_0_CHANGEPASSWORD_REQUEST* pChangeRequest = NULL;
ULONG cbChangeRequestSize;
DebugPrintf(SSPI_LOG, "MsvChangePasswordUser PackageId %d, DomainName %wZ, "
"UserName %wZ, OldPass %wZ, NewPass %wZ, Impersonating %s\n",
PackageId, pDomainName, pUserName, pOldPassword, pNewPassword, bImpersonating ? "true" : "false");
cbChangeRequestSize = ROUND_UP_COUNT(sizeof(MSV1_0_CHANGEPASSWORD_REQUEST), sizeof(DWORD))
+ pUserName->Length
+ pDomainName->Length
+ pOldPassword->Length
+ pNewPassword->Length;
pChangeRequest = (MSV1_0_CHANGEPASSWORD_REQUEST*) new CHAR[cbChangeRequestSize];
Status DBGCHK = pChangeRequest ? STATUS_SUCCESS : STATUS_NO_MEMORY;
if (NT_SUCCESS(Status))
{
RtlZeroMemory(pChangeRequest, cbChangeRequestSize);
pChangeRequest->MessageType = bCacheOnly ? MsV1_0ChangeCachedPassword : MsV1_0ChangePassword;
pChangeRequest->AccountName = *pUserName;
pChangeRequest->AccountName.Buffer = (PWSTR) ROUND_UP_POINTER(sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) + (PBYTE) pChangeRequest, sizeof(DWORD));
RtlCopyMemory(
pChangeRequest->AccountName.Buffer,
pUserName->Buffer,
pUserName->Length
);
pChangeRequest->DomainName = *pDomainName;
pChangeRequest->DomainName.Buffer = pChangeRequest->AccountName.Buffer + pChangeRequest->AccountName.Length / sizeof(WCHAR);
RtlCopyMemory(
pChangeRequest->DomainName.Buffer,
pDomainName->Buffer,
pDomainName->Length
);
pChangeRequest->OldPassword = *pOldPassword;
pChangeRequest->OldPassword.Buffer = pChangeRequest->DomainName.Buffer + pChangeRequest->DomainName.Length / sizeof(WCHAR);
RtlCopyMemory(
pChangeRequest->OldPassword.Buffer,
pOldPassword->Buffer,
pOldPassword->Length
);
pChangeRequest->NewPassword = *pNewPassword;
pChangeRequest->NewPassword.Buffer = pChangeRequest->OldPassword.Buffer + pChangeRequest->OldPassword.Length / sizeof(WCHAR);
RtlCopyMemory(
pChangeRequest->NewPassword.Buffer,
pNewPassword->Buffer,
pNewPassword->Length
);
//
// We are running as the caller, so state we are impersonating
//
pChangeRequest->Impersonating = bImpersonating;
DebugPrintf(SSPI_LOG, "Msg type %#x\n", pChangeRequest->MessageType);
Status DBGCHK = LsaCallAuthenticationPackage(
LogonHandle,
PackageId,
pChangeRequest,
cbChangeRequestSize,
(VOID**) &pResponse,
&cbResponseSize,
&SubStatus
);
}
if (NT_SUCCESS(Status))
{
if (pResponse && pResponse->PasswordInfoValid)
{
DebugPrintf(SSPI_LOG, "SubStatus %#x, MinPasswordLength %d, PasswordHistoryLength %d\n",
SubStatus,
pResponse->DomainPasswordInfo.MinPasswordLength,
pResponse->DomainPasswordInfo.PasswordHistoryLength);
DebugPrintSysTimeAsLocalTime(SSPI_LOG, "MaxPasswordAge ", &pResponse->DomainPasswordInfo.MaxPasswordAge);
DebugPrintSysTimeAsLocalTime(SSPI_LOG, "MinPasswordAge ", &pResponse->DomainPasswordInfo.MinPasswordAge);
}
Status DBGCHK = SubStatus;
}
else
{
DebugPrintf(SSPI_LOG, "SubStatus %#x\n", SubStatus);
}
if (pResponse)
{
LsaFreeReturnBuffer(pResponse);
}
if (pChangeRequest)
{
delete [] pChangeRequest;
}
return Status;
}
NTSTATUS
KerbChangePasswordUser(
IN HANDLE LogonHandle,
IN ULONG PackageId,
IN BOOLEAN bImpersonating,
IN UNICODE_STRING* pDomainName,
IN UNICODE_STRING* pUserName,
IN UNICODE_STRING* pOldPassword,
IN UNICODE_STRING* pNewPassword
)
{
TNtStatus Status = STATUS_UNSUCCESSFUL;
NTSTATUS SubStatus = STATUS_UNSUCCESSFUL;
PVOID pResponse = NULL ;
ULONG cbResponseSize;
PKERB_CHANGEPASSWORD_REQUEST pChangeRequest = NULL;
ULONG cbChangeRequestSize;
DebugPrintf(SSPI_LOG, "KerbChangePasswordUser PackageId %d, DomainName %wZ, "
"UserName %wZ, OldPass %wZ, NewPass %wZ, Impersonating %s\n",
PackageId, pDomainName, pUserName, pOldPassword, pNewPassword, bImpersonating ? "true" : "false");
cbChangeRequestSize = ROUND_UP_COUNT(sizeof(KERB_CHANGEPASSWORD_REQUEST), sizeof(DWORD))
+ pUserName->Length + pDomainName->Length
+ pOldPassword->Length + pNewPassword->Length;
pChangeRequest = (PKERB_CHANGEPASSWORD_REQUEST) new CHAR[cbChangeRequestSize];
Status DBGCHK = pChangeRequest ? STATUS_SUCCESS : STATUS_NO_MEMORY;
if (NT_SUCCESS(Status))
{
RtlZeroMemory(pChangeRequest, cbChangeRequestSize);
pChangeRequest->MessageType = KerbChangePasswordMessage;
pChangeRequest->AccountName = *pUserName;
pChangeRequest->AccountName.Buffer = (PWSTR) ROUND_UP_POINTER(sizeof(KERB_CHANGEPASSWORD_REQUEST) + (PBYTE) pChangeRequest, sizeof(DWORD));
RtlCopyMemory(
pChangeRequest->AccountName.Buffer,
pUserName->Buffer,
pUserName->Length
);
pChangeRequest->DomainName = *pDomainName;
pChangeRequest->DomainName.Buffer = pChangeRequest->AccountName.Buffer + pChangeRequest->AccountName.Length / sizeof(WCHAR);
RtlCopyMemory(
pChangeRequest->DomainName.Buffer,
pDomainName->Buffer,
pDomainName->Length
);
pChangeRequest->OldPassword = *pOldPassword;
pChangeRequest->OldPassword.Buffer = pChangeRequest->DomainName.Buffer + pChangeRequest->DomainName.Length / sizeof(WCHAR);
RtlCopyMemory(
pChangeRequest->OldPassword.Buffer,
pOldPassword->Buffer,
pOldPassword->Length
);
pChangeRequest->NewPassword = *pNewPassword;
pChangeRequest->NewPassword.Buffer = pChangeRequest->OldPassword.Buffer + pChangeRequest->OldPassword.Length / sizeof(WCHAR);
RtlCopyMemory(
pChangeRequest->NewPassword.Buffer,
pNewPassword->Buffer,
pNewPassword->Length
);
//
// We are running as the caller, so state we are impersonating
//
pChangeRequest->Impersonating = bImpersonating;
Status DBGCHK = LsaCallAuthenticationPackage(
LogonHandle,
PackageId,
pChangeRequest,
cbChangeRequestSize,
&pResponse,
&cbResponseSize,
&SubStatus
);
}
if (NT_SUCCESS(Status))
{
Status DBGCHK = SubStatus;
}
else
{
DebugPrintf(SSPI_LOG, "SubStatus %#x\n", SubStatus);
}
if (pResponse)
{
LsaFreeReturnBuffer(pResponse);
}
if (pChangeRequest)
{
delete [] pChangeRequest;
}
return Status;
}
NTSTATUS
KerbSetPasswordUser(
IN HANDLE LogonHandle,
IN ULONG PackageId,
IN UNICODE_STRING* pDomainName,
IN UNICODE_STRING* pUserName,
IN UNICODE_STRING* pNewPassword,
IN OPTIONAL PCredHandle pCredentialsHandle
)
{
TNtStatus Status = STATUS_UNSUCCESSFUL;
NTSTATUS SubStatus = STATUS_UNSUCCESSFUL;
PVOID pResponse = NULL ;
ULONG cbResponseSize = NULL;
PKERB_SETPASSWORD_REQUEST pSetRequest = NULL;
ULONG cbChangeSize;
DebugPrintf(SSPI_LOG, "KerbSetPasswordUser PackageId %d, DomainName %wZ, "
"UserName %wZ, NewPassword %wZ, CredHandle %p\n",
PackageId, pDomainName, pUserName, pNewPassword, pCredentialsHandle);
cbChangeSize = ROUND_UP_COUNT(sizeof(KERB_SETPASSWORD_REQUEST), sizeof(DWORD))
+ pUserName->Length + pDomainName->Length + pNewPassword->Length;
pSetRequest = (PKERB_SETPASSWORD_REQUEST) new CHAR [cbChangeSize];
Status DBGCHK = pSetRequest ? STATUS_SUCCESS : STATUS_NO_MEMORY;
if (NT_SUCCESS(Status))
{
RtlZeroMemory(pSetRequest, cbChangeSize);
pSetRequest->MessageType = KerbSetPasswordMessage;
pSetRequest->AccountName = *pUserName;
pSetRequest->AccountName.Buffer = (PWSTR) ROUND_UP_POINTER(sizeof(KERB_SETPASSWORD_REQUEST) + (PBYTE) pSetRequest, sizeof(DWORD));
RtlCopyMemory(
pSetRequest->AccountName.Buffer,
pUserName->Buffer,
pUserName->Length
);
pSetRequest->DomainName = *pDomainName;
pSetRequest->DomainName.Buffer = pSetRequest->AccountName.Buffer + pSetRequest->AccountName.Length / sizeof(WCHAR);
RtlCopyMemory(
pSetRequest->DomainName.Buffer,
pDomainName->Buffer,
pDomainName->Length
);
pSetRequest->Password = *pNewPassword;
pSetRequest->Password.Buffer = pSetRequest->DomainName.Buffer + pSetRequest->DomainName.Length / sizeof(WCHAR);
RtlCopyMemory(
pSetRequest->Password.Buffer,
pNewPassword->Buffer,
pNewPassword->Length
);
if (pCredentialsHandle)
{
pSetRequest->CredentialsHandle = *pCredentialsHandle;
pSetRequest->Flags |= KERB_SETPASS_USE_CREDHANDLE;
}
Status DBGCHK = LsaCallAuthenticationPackage(
LogonHandle,
PackageId,
pSetRequest,
cbChangeSize,
&pResponse,
&cbResponseSize,
&SubStatus
);
}
if (NT_SUCCESS(Status))
{
Status DBGCHK = SubStatus;
}
if (pResponse)
{
LsaFreeReturnBuffer(pResponse);
}
if (pSetRequest)
{
delete [] pSetRequest;
}
return Status;
}
VOID __cdecl
main(
IN INT argc,
IN PSTR argv[]
)
{
TNtStatus Status = STATUS_SUCCESS;
HANDLE LogonHandle = NULL;
ULONG PackageId = -1;
UNICODE_STRING ClientName = {0};
UNICODE_STRING ClientRealm = {0};
UNICODE_STRING OldPassword = {0};
UNICODE_STRING NewPassword = {0};
BOOLEAN bIsSetPassword = FALSE;
BOOLEAN bCacheOnly = FALSE;
BOOLEAN bImpersonating = TRUE;
PCSTR pszPackageName = NTLMSP_NAME_A;
for (INT i = 1; NT_SUCCESS(Status) && (i < argc); i++)
{
if ((*argv[i] == '-') || (*argv[i] == '/'))
{
switch (argv[i][1])
{
case 'c':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &ClientName);
break;
case 'C':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &ClientRealm);
break;
case 'p':
pszPackageName = argv[i] + 2;
break;
case 'o':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &OldPassword);
break;
case 'n':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &NewPassword);
break;
case 'r':
bImpersonating = FALSE;
break;
case 's':
bIsSetPassword = TRUE;
break;
case 'l':
bCacheOnly = TRUE;
break;
case 'h':
case '?':
default:
Usage(argv[0]);
break;
}
}
else
{
Usage(argv[0]);
}
}
if (NT_SUCCESS(Status))
{
Status DBGCHK = GetLsaHandleAndPackageId(
pszPackageName,
&LogonHandle,
&PackageId
);
}
if (NT_SUCCESS(Status))
{
if (0 == _stricmp(NTLMSP_NAME_A, pszPackageName))
{
if (bIsSetPassword)
{
DebugPrintf(SSPI_ERROR, "SetPassword not supported\n");
Status DBGCHK = STATUS_NOT_SUPPORTED;
}
else
{
Status DBGCHK = MsvChangePasswordUser(
LogonHandle,
PackageId,
bCacheOnly,
&ClientRealm,
&ClientName,
&OldPassword,
&NewPassword,
bImpersonating
);
}
}
else if (0 == _stricmp(MICROSOFT_KERBEROS_NAME_A, pszPackageName))
{
if (bIsSetPassword)
{
Status DBGCHK = KerbSetPasswordUser(
LogonHandle,
PackageId,
&ClientRealm,
&ClientName,
&NewPassword,
NULL // no cred handle
);
}
else
{
Status DBGCHK = KerbChangePasswordUser(
LogonHandle,
PackageId,
bImpersonating,
&ClientRealm,
&ClientName,
&OldPassword,
&NewPassword
);
}
}
else
{
DebugPrintf(SSPI_ERROR, "%s not supported\n", pszPackageName);
Status DBGCHK = STATUS_NOT_SUPPORTED;
}
}
if (NT_SUCCESS(Status))
{
DebugPrintf(SSPI_LOG, "Operation succeeded\n");
}
else
{
DebugPrintf(SSPI_ERROR, "Operation failed\n");
}
if (LogonHandle)
{
LsaDeregisterLogonProcess(LogonHandle);
}
RtlFreeUnicodeString(&ClientName);
RtlFreeUnicodeString(&ClientRealm);
RtlFreeUnicodeString(&OldPassword);
RtlFreeUnicodeString(&NewPassword);
}