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.
293 lines
9.8 KiB
293 lines
9.8 KiB
#include <stdafx.h>
|
|
#include "CPasswdP.h"
|
|
|
|
#include "AccntWiz.h"
|
|
#include "proputil.h"
|
|
|
|
#include <imm.h>
|
|
#include <dsgetdc.h>
|
|
|
|
#define PASSWD_NOCHANGE 0x01
|
|
#define PASSWD_CANCHANGE 0x02
|
|
#define PASSWD_MUSTCHANGE 0x04
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------------------
|
|
// CPasswdPage class
|
|
// --------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Constructor
|
|
// ----------------------------------------------------------------------------
|
|
CPasswdPage::CPasswdPage( CAddUser_AccntWiz* pASW ) :
|
|
m_csUserOU(),
|
|
m_csPasswd1a(),
|
|
m_csPasswd1b()
|
|
{
|
|
m_pASW = pASW;
|
|
m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
|
|
m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PASSWD_GEN_TITLE);
|
|
m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PASSWD_GEN_SUBTITLE);
|
|
|
|
// Defaults
|
|
m_fInit = TRUE;
|
|
m_dwOptions = 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Destructor
|
|
// ----------------------------------------------------------------------------
|
|
CPasswdPage::~CPasswdPage( )
|
|
{
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// OnDestroy()
|
|
// ----------------------------------------------------------------------------
|
|
LRESULT CPasswdPage::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
// Detach all of our controls from the windows.
|
|
m_ctrlPasswd1a.Detach();
|
|
m_ctrlPasswd1b.Detach();
|
|
m_ctrlRad2Must.Detach();
|
|
m_ctrlRad2Cannot.Detach();
|
|
m_ctrlRad2Can.Detach();
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// OnInitDialog()
|
|
// ----------------------------------------------------------------------------
|
|
LRESULT CPasswdPage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
|
|
{
|
|
// Attach controls.
|
|
m_ctrlPasswd1a.Attach ( GetDlgItem(IDC_PASSWD_1A) );
|
|
m_ctrlPasswd1b.Attach ( GetDlgItem(IDC_PASSWD_1B) );
|
|
m_ctrlRad2Must.Attach ( GetDlgItem(IDC_RAD_2_MUST) );
|
|
m_ctrlRad2Cannot.Attach ( GetDlgItem(IDC_RAD_2_CANNOT) );
|
|
m_ctrlRad2Can.Attach ( GetDlgItem(IDC_RAD_2_CAN) );
|
|
|
|
// Limit the Edit boxes
|
|
m_ctrlPasswd1a.SetLimitText( PWLEN );
|
|
m_ctrlPasswd1b.SetLimitText( PWLEN );
|
|
|
|
// Initialize the controls' state
|
|
m_ctrlRad2Can.SetCheck(1);
|
|
|
|
// Disable IME for the controls.
|
|
::ImmAssociateContext( m_ctrlPasswd1a.m_hWnd, NULL );
|
|
::ImmAssociateContext( m_ctrlPasswd1b.m_hWnd, NULL );
|
|
|
|
return(0);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Init()
|
|
//
|
|
// Initializes the controls on the page with the values from the property bag.
|
|
// NOTE: This is called from OnSetActive(), but only on the first SetActive.
|
|
// This is because even though the control attaching could be done in
|
|
// the WM_INITDIALOG handler, setting the values of the controls from
|
|
// the values read from the property bag can only safely be done in the
|
|
// PSN_SETACTIVE.
|
|
// ----------------------------------------------------------------------------
|
|
LRESULT CPasswdPage::Init( )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ReadProperties()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT CPasswdPage::ReadProperties( IPropertyPagePropertyBag * pPPPBag )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// WriteProperties()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT CPasswdPage::WriteProperties( IPropertyPagePropertyBag * pPPPBag )
|
|
{
|
|
m_dwOptions = 0;
|
|
|
|
if ( !m_fInit ) // IF the page has already been initialized...
|
|
{
|
|
// Get the values from the edit boxes.
|
|
m_csPasswd1a = StrGetWindowText( m_ctrlPasswd1a.m_hWnd ).c_str();
|
|
|
|
if( m_ctrlRad2Must.GetCheck() )
|
|
{
|
|
m_dwOptions |= PASSWD_MUSTCHANGE;
|
|
}
|
|
else if( m_ctrlRad2Cannot.GetCheck() )
|
|
{
|
|
m_dwOptions |= PASSWD_NOCHANGE;
|
|
}
|
|
else
|
|
{
|
|
m_dwOptions |= PASSWD_CANCHANGE;
|
|
}
|
|
}
|
|
|
|
// Write the values to the property bag.
|
|
WriteString( pPPPBag, PROP_PASSWD_GUID_STRING, m_csPasswd1a, FALSE );
|
|
WriteInt4 ( pPPPBag, PROP_ACCOUNT_OPT_GUID_STRING, (LONG)m_dwOptions, FALSE );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ProvideFinishText()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT CPasswdPage::ProvideFinishText( CString &str )
|
|
{
|
|
if ( m_fInit )
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// DeleteProperties()
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT CPasswdPage::DeleteProperties( IPropertyPagePropertyBag * pPPPBag )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// OnSetActive()
|
|
// ----------------------------------------------------------------------------
|
|
BOOL CPasswdPage::OnSetActive()
|
|
{
|
|
CWaitCursor cWaitCur;
|
|
|
|
// Enable the next and back buttons.
|
|
::SendMessage( GetParent(), PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT );
|
|
|
|
// Our fake InitDialog()
|
|
// NOTE: This is because if this is the first wizard page, it will get
|
|
// the WM_INITDIALOG message before its ReadProperties() function
|
|
// has been called.
|
|
if ( m_fInit ) // Is this the first SetActive?
|
|
{
|
|
Init(); // Call our init function.
|
|
m_fInit = FALSE; // And mark that this isn't the first SetActive.
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// OnWizardBack()
|
|
// ----------------------------------------------------------------------------
|
|
int CPasswdPage::OnWizardBack()
|
|
{
|
|
return 0; // Go back.
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// OnWizardNext()
|
|
// ----------------------------------------------------------------------------
|
|
int CPasswdPage::OnWizardNext()
|
|
{
|
|
CWaitCursor cWaitCur;
|
|
CString csPasswd;
|
|
CString csTitle;
|
|
CString csError;
|
|
HWND hWndPasswd;
|
|
HRESULT hr = S_OK;
|
|
|
|
// Get the values from the edit boxes.
|
|
m_csPasswd1a = StrGetWindowText( m_ctrlPasswd1a.m_hWnd ).c_str();
|
|
m_csPasswd1b = StrGetWindowText( m_ctrlPasswd1b.m_hWnd ).c_str();
|
|
|
|
hWndPasswd = m_ctrlPasswd1a.m_hWnd;
|
|
csPasswd = m_csPasswd1a;
|
|
|
|
// Make sure they match...
|
|
if ( _tcscmp((LPCTSTR)m_csPasswd1a, (LPCTSTR)m_csPasswd1b) )
|
|
{
|
|
csError.LoadString(IDS_ERROR_PASSWD_MATCH);
|
|
csTitle.LoadString(IDS_TITLE);
|
|
|
|
::MessageBox(m_hWnd, (LPCTSTR)csError, (LPCTSTR)csTitle, MB_OK | MB_TASKMODAL | MB_ICONERROR);
|
|
::SetFocus(hWndPasswd);
|
|
|
|
return(-1);
|
|
}
|
|
|
|
// Make sure it meets the minimum length requirements. (bug 4210)
|
|
CString csDns = _T("");
|
|
CString csDCName = _T("");
|
|
PDOMAIN_CONTROLLER_INFO pDCI = NULL;
|
|
|
|
hr = DsGetDcName( NULL, NULL, NULL, NULL, DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME, &pDCI );
|
|
if( (hr == S_OK) && (pDCI != NULL) )
|
|
{
|
|
csDns = pDCI->DomainName;
|
|
|
|
NetApiBufferFree (pDCI);
|
|
pDCI = NULL;
|
|
}
|
|
|
|
tstring strDomain = GetDomainPath((LPCTSTR)csDns);
|
|
csDCName = L"LDAP://";
|
|
csDCName += strDomain.c_str();
|
|
|
|
// Now open the IADs object for the LDAP version of the DC..
|
|
// Then convert to WinNT version.
|
|
CComPtr<IADs> spADs = NULL;
|
|
|
|
hr = ::ADsGetObject( (LPTSTR)(LPCTSTR)csDCName, IID_IADs, (VOID**)&spADs );
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
CComVariant var;
|
|
CComBSTR bstrProp = _T("dc");
|
|
spADs->Get( bstrProp, &var );
|
|
|
|
csDCName = L"WinNT://";
|
|
csDCName += V_BSTR(&var);
|
|
}
|
|
|
|
CComPtr<IADsDomain> spADsDomain = NULL;
|
|
|
|
hr = ::ADsOpenObject( (LPTSTR)(LPCTSTR)csDCName, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsDomain, (VOID**)&spADsDomain );
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
long lMinLength = 0;
|
|
|
|
spADsDomain->get_MinPasswordLength( &lMinLength );
|
|
|
|
if( csPasswd.GetLength() < lMinLength )
|
|
{
|
|
TCHAR szMin[128];
|
|
|
|
_itot(lMinLength, szMin, 10);
|
|
|
|
csError.FormatMessage(IDS_ERROR_PASSWDLEN, szMin);
|
|
csTitle.LoadString(IDS_TITLE);
|
|
|
|
::MessageBox(m_hWnd, (LPCTSTR)csError, (LPCTSTR)csTitle, MB_OK | MB_TASKMODAL | MB_ICONERROR);
|
|
::SetFocus(hWndPasswd);
|
|
|
|
return(-1);
|
|
}
|
|
}
|
|
|
|
// Finally Check if it is more than 14 characters.
|
|
if( csPasswd.GetLength() > LM20_PWLEN )
|
|
{
|
|
csError.LoadString(IDS_ERROR_LONGPW);
|
|
csTitle.LoadString(IDS_TITLE);
|
|
|
|
if( ::MessageBox( m_hWnd, (LPCTSTR)csError, (LPCTSTR)csTitle, MB_YESNO | MB_ICONWARNING ) == IDNO )
|
|
{
|
|
::SetFocus( hWndPasswd );
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0; // Go next.
|
|
}
|