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.

293 lines
9.8 KiB

  1. #include <stdafx.h>
  2. #include "CPasswdP.h"
  3. #include "AccntWiz.h"
  4. #include "proputil.h"
  5. #include <imm.h>
  6. #include <dsgetdc.h>
  7. #define PASSWD_NOCHANGE 0x01
  8. #define PASSWD_CANCHANGE 0x02
  9. #define PASSWD_MUSTCHANGE 0x04
  10. // --------------------------------------------------------------------------------------------------------------------------------
  11. // CPasswdPage class
  12. // --------------------------------------------------------------------------------------------------------------------------------
  13. // ----------------------------------------------------------------------------
  14. // Constructor
  15. // ----------------------------------------------------------------------------
  16. CPasswdPage::CPasswdPage( CAddUser_AccntWiz* pASW ) :
  17. m_csUserOU(),
  18. m_csPasswd1a(),
  19. m_csPasswd1b()
  20. {
  21. m_pASW = pASW;
  22. m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  23. m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PASSWD_GEN_TITLE);
  24. m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PASSWD_GEN_SUBTITLE);
  25. // Defaults
  26. m_fInit = TRUE;
  27. m_dwOptions = 0;
  28. }
  29. // ----------------------------------------------------------------------------
  30. // Destructor
  31. // ----------------------------------------------------------------------------
  32. CPasswdPage::~CPasswdPage( )
  33. {
  34. }
  35. // ----------------------------------------------------------------------------
  36. // OnDestroy()
  37. // ----------------------------------------------------------------------------
  38. LRESULT CPasswdPage::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  39. {
  40. // Detach all of our controls from the windows.
  41. m_ctrlPasswd1a.Detach();
  42. m_ctrlPasswd1b.Detach();
  43. m_ctrlRad2Must.Detach();
  44. m_ctrlRad2Cannot.Detach();
  45. m_ctrlRad2Can.Detach();
  46. return 0;
  47. }
  48. // ----------------------------------------------------------------------------
  49. // OnInitDialog()
  50. // ----------------------------------------------------------------------------
  51. LRESULT CPasswdPage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  52. {
  53. // Attach controls.
  54. m_ctrlPasswd1a.Attach ( GetDlgItem(IDC_PASSWD_1A) );
  55. m_ctrlPasswd1b.Attach ( GetDlgItem(IDC_PASSWD_1B) );
  56. m_ctrlRad2Must.Attach ( GetDlgItem(IDC_RAD_2_MUST) );
  57. m_ctrlRad2Cannot.Attach ( GetDlgItem(IDC_RAD_2_CANNOT) );
  58. m_ctrlRad2Can.Attach ( GetDlgItem(IDC_RAD_2_CAN) );
  59. // Limit the Edit boxes
  60. m_ctrlPasswd1a.SetLimitText( PWLEN );
  61. m_ctrlPasswd1b.SetLimitText( PWLEN );
  62. // Initialize the controls' state
  63. m_ctrlRad2Can.SetCheck(1);
  64. // Disable IME for the controls.
  65. ::ImmAssociateContext( m_ctrlPasswd1a.m_hWnd, NULL );
  66. ::ImmAssociateContext( m_ctrlPasswd1b.m_hWnd, NULL );
  67. return(0);
  68. }
  69. // ----------------------------------------------------------------------------
  70. // Init()
  71. //
  72. // Initializes the controls on the page with the values from the property bag.
  73. // NOTE: This is called from OnSetActive(), but only on the first SetActive.
  74. // This is because even though the control attaching could be done in
  75. // the WM_INITDIALOG handler, setting the values of the controls from
  76. // the values read from the property bag can only safely be done in the
  77. // PSN_SETACTIVE.
  78. // ----------------------------------------------------------------------------
  79. LRESULT CPasswdPage::Init( )
  80. {
  81. return 0;
  82. }
  83. // ----------------------------------------------------------------------------
  84. // ReadProperties()
  85. // ----------------------------------------------------------------------------
  86. HRESULT CPasswdPage::ReadProperties( IPropertyPagePropertyBag * pPPPBag )
  87. {
  88. return S_OK;
  89. }
  90. // ----------------------------------------------------------------------------
  91. // WriteProperties()
  92. // ----------------------------------------------------------------------------
  93. HRESULT CPasswdPage::WriteProperties( IPropertyPagePropertyBag * pPPPBag )
  94. {
  95. m_dwOptions = 0;
  96. if ( !m_fInit ) // IF the page has already been initialized...
  97. {
  98. // Get the values from the edit boxes.
  99. m_csPasswd1a = StrGetWindowText( m_ctrlPasswd1a.m_hWnd ).c_str();
  100. if( m_ctrlRad2Must.GetCheck() )
  101. {
  102. m_dwOptions |= PASSWD_MUSTCHANGE;
  103. }
  104. else if( m_ctrlRad2Cannot.GetCheck() )
  105. {
  106. m_dwOptions |= PASSWD_NOCHANGE;
  107. }
  108. else
  109. {
  110. m_dwOptions |= PASSWD_CANCHANGE;
  111. }
  112. }
  113. // Write the values to the property bag.
  114. WriteString( pPPPBag, PROP_PASSWD_GUID_STRING, m_csPasswd1a, FALSE );
  115. WriteInt4 ( pPPPBag, PROP_ACCOUNT_OPT_GUID_STRING, (LONG)m_dwOptions, FALSE );
  116. return S_OK;
  117. }
  118. // ----------------------------------------------------------------------------
  119. // ProvideFinishText()
  120. // ----------------------------------------------------------------------------
  121. HRESULT CPasswdPage::ProvideFinishText( CString &str )
  122. {
  123. if ( m_fInit )
  124. return E_FAIL;
  125. return S_OK;
  126. }
  127. // ----------------------------------------------------------------------------
  128. // DeleteProperties()
  129. // ----------------------------------------------------------------------------
  130. HRESULT CPasswdPage::DeleteProperties( IPropertyPagePropertyBag * pPPPBag )
  131. {
  132. return S_OK;
  133. }
  134. // ----------------------------------------------------------------------------
  135. // OnSetActive()
  136. // ----------------------------------------------------------------------------
  137. BOOL CPasswdPage::OnSetActive()
  138. {
  139. CWaitCursor cWaitCur;
  140. // Enable the next and back buttons.
  141. ::SendMessage( GetParent(), PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT );
  142. // Our fake InitDialog()
  143. // NOTE: This is because if this is the first wizard page, it will get
  144. // the WM_INITDIALOG message before its ReadProperties() function
  145. // has been called.
  146. if ( m_fInit ) // Is this the first SetActive?
  147. {
  148. Init(); // Call our init function.
  149. m_fInit = FALSE; // And mark that this isn't the first SetActive.
  150. }
  151. return TRUE;
  152. }
  153. // ----------------------------------------------------------------------------
  154. // OnWizardBack()
  155. // ----------------------------------------------------------------------------
  156. int CPasswdPage::OnWizardBack()
  157. {
  158. return 0; // Go back.
  159. }
  160. // ----------------------------------------------------------------------------
  161. // OnWizardNext()
  162. // ----------------------------------------------------------------------------
  163. int CPasswdPage::OnWizardNext()
  164. {
  165. CWaitCursor cWaitCur;
  166. CString csPasswd;
  167. CString csTitle;
  168. CString csError;
  169. HWND hWndPasswd;
  170. HRESULT hr = S_OK;
  171. // Get the values from the edit boxes.
  172. m_csPasswd1a = StrGetWindowText( m_ctrlPasswd1a.m_hWnd ).c_str();
  173. m_csPasswd1b = StrGetWindowText( m_ctrlPasswd1b.m_hWnd ).c_str();
  174. hWndPasswd = m_ctrlPasswd1a.m_hWnd;
  175. csPasswd = m_csPasswd1a;
  176. // Make sure they match...
  177. if ( _tcscmp((LPCTSTR)m_csPasswd1a, (LPCTSTR)m_csPasswd1b) )
  178. {
  179. csError.LoadString(IDS_ERROR_PASSWD_MATCH);
  180. csTitle.LoadString(IDS_TITLE);
  181. ::MessageBox(m_hWnd, (LPCTSTR)csError, (LPCTSTR)csTitle, MB_OK | MB_TASKMODAL | MB_ICONERROR);
  182. ::SetFocus(hWndPasswd);
  183. return(-1);
  184. }
  185. // Make sure it meets the minimum length requirements. (bug 4210)
  186. CString csDns = _T("");
  187. CString csDCName = _T("");
  188. PDOMAIN_CONTROLLER_INFO pDCI = NULL;
  189. hr = DsGetDcName( NULL, NULL, NULL, NULL, DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME, &pDCI );
  190. if( (hr == S_OK) && (pDCI != NULL) )
  191. {
  192. csDns = pDCI->DomainName;
  193. NetApiBufferFree (pDCI);
  194. pDCI = NULL;
  195. }
  196. tstring strDomain = GetDomainPath((LPCTSTR)csDns);
  197. csDCName = L"LDAP://";
  198. csDCName += strDomain.c_str();
  199. // Now open the IADs object for the LDAP version of the DC..
  200. // Then convert to WinNT version.
  201. CComPtr<IADs> spADs = NULL;
  202. hr = ::ADsGetObject( (LPTSTR)(LPCTSTR)csDCName, IID_IADs, (VOID**)&spADs );
  203. if( SUCCEEDED(hr) )
  204. {
  205. CComVariant var;
  206. CComBSTR bstrProp = _T("dc");
  207. spADs->Get( bstrProp, &var );
  208. csDCName = L"WinNT://";
  209. csDCName += V_BSTR(&var);
  210. }
  211. CComPtr<IADsDomain> spADsDomain = NULL;
  212. hr = ::ADsOpenObject( (LPTSTR)(LPCTSTR)csDCName, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsDomain, (VOID**)&spADsDomain );
  213. if( SUCCEEDED(hr) )
  214. {
  215. long lMinLength = 0;
  216. spADsDomain->get_MinPasswordLength( &lMinLength );
  217. if( csPasswd.GetLength() < lMinLength )
  218. {
  219. TCHAR szMin[128];
  220. _itot(lMinLength, szMin, 10);
  221. csError.FormatMessage(IDS_ERROR_PASSWDLEN, szMin);
  222. csTitle.LoadString(IDS_TITLE);
  223. ::MessageBox(m_hWnd, (LPCTSTR)csError, (LPCTSTR)csTitle, MB_OK | MB_TASKMODAL | MB_ICONERROR);
  224. ::SetFocus(hWndPasswd);
  225. return(-1);
  226. }
  227. }
  228. // Finally Check if it is more than 14 characters.
  229. if( csPasswd.GetLength() > LM20_PWLEN )
  230. {
  231. csError.LoadString(IDS_ERROR_LONGPW);
  232. csTitle.LoadString(IDS_TITLE);
  233. if( ::MessageBox( m_hWnd, (LPCTSTR)csError, (LPCTSTR)csTitle, MB_YESNO | MB_ICONWARNING ) == IDNO )
  234. {
  235. ::SetFocus( hWndPasswd );
  236. return -1;
  237. }
  238. }
  239. return 0; // Go next.
  240. }