Source code of Windows XP (NT5)
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.

1139 lines
35 KiB

  1. /////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000-2001.
  5. //
  6. // File: TemplateGeneralPropertyPage.cpp
  7. //
  8. // Contents: Implementation of CTemplateGeneralPropertyPage
  9. //
  10. //----------------------------------------------------------------------------
  11. // TemplateGeneralPropertyPage.cpp : implementation file
  12. //
  13. #include "stdafx.h"
  14. #include "CompData.h"
  15. #include "TemplateGeneralPropertyPage.h"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CTemplateGeneralPropertyPage property page
  23. CTemplateGeneralPropertyPage::CTemplateGeneralPropertyPage(
  24. CCertTemplate& rCertTemplate,
  25. const CCertTmplComponentData* pCompData) :
  26. CHelpPropertyPage(CTemplateGeneralPropertyPage::IDD),
  27. m_rCertTemplate (rCertTemplate),
  28. m_strOriginalName (rCertTemplate.GetTemplateName ()),
  29. m_pReleaseMe (0),
  30. m_dwCurrentValidityUnits (PERIOD_TYPE_NONE),
  31. m_dwCurrentRenewalUnits (PERIOD_TYPE_NONE),
  32. m_lNotifyHandle (0),
  33. m_bIsDirty (false),
  34. m_nRenewalDays (0),
  35. m_nValidityDays (0),
  36. m_pCompData (pCompData),
  37. m_nTemplateV2AuthPageNumber (-1),
  38. m_nTemplateV2RequestPageNumber (-1)
  39. {
  40. _TRACE (1, L"Entering CTemplateGeneralPropertyPage::CTemplateGeneralPropertyPage ()\n");
  41. //{{AFX_DATA_INIT(CTemplateGeneralPropertyPage)
  42. m_strDisplayName = _T("");
  43. m_strTemplateName = _T("");
  44. //}}AFX_DATA_INIT
  45. m_rCertTemplate.AddRef ();
  46. _TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::CTemplateGeneralPropertyPage ()\n");
  47. }
  48. CTemplateGeneralPropertyPage::~CTemplateGeneralPropertyPage()
  49. {
  50. _TRACE (1, L"Entering CTemplateGeneralPropertyPage::~CTemplateGeneralPropertyPage ()\n");
  51. m_rCertTemplate.Release ();
  52. if ( m_pReleaseMe )
  53. {
  54. m_pReleaseMe->Release ();
  55. m_pReleaseMe = 0;
  56. }
  57. if ( m_lNotifyHandle )
  58. {
  59. MMCFreeNotifyHandle (m_lNotifyHandle);
  60. m_lNotifyHandle = 0;
  61. }
  62. _TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::~CTemplateGeneralPropertyPage ()\n");
  63. }
  64. void CTemplateGeneralPropertyPage::DoDataExchange(CDataExchange* pDX)
  65. {
  66. CHelpPropertyPage::DoDataExchange(pDX);
  67. //{{AFX_DATA_MAP(CTemplateGeneralPropertyPage)
  68. DDX_Control(pDX, IDC_VALIDITY_UNITS, m_validityUnits);
  69. DDX_Control(pDX, IDC_RENEWAL_UNITS, m_renewalUnits);
  70. DDX_Text(pDX, IDC_DISPLAY_NAME, m_strDisplayName);
  71. DDX_Text(pDX, IDC_TEMPLATE_NAME, m_strTemplateName);
  72. //}}AFX_DATA_MAP
  73. }
  74. BEGIN_MESSAGE_MAP(CTemplateGeneralPropertyPage, CHelpPropertyPage)
  75. //{{AFX_MSG_MAP(CTemplateGeneralPropertyPage)
  76. ON_EN_CHANGE(IDC_DISPLAY_NAME, OnChangeDisplayName)
  77. ON_CBN_SELCHANGE(IDC_RENEWAL_UNITS, OnSelchangeRenewalUnits)
  78. ON_CBN_SELCHANGE(IDC_VALIDITY_UNITS, OnSelchangeValidityUnits)
  79. ON_EN_CHANGE(IDC_RENEWAL_EDIT, OnChangeRenewalEdit)
  80. ON_EN_CHANGE(IDC_VALIDITY_EDIT, OnChangeValidityEdit)
  81. ON_BN_CLICKED(IDC_PUBLISH_TO_AD, OnPublishToAd)
  82. ON_BN_CLICKED(IDC_USE_AD_CERT_FOR_REENROLLMENT, OnUseADCert)
  83. ON_EN_CHANGE(IDC_TEMPLATE_NAME, OnChangeTemplateName)
  84. ON_EN_KILLFOCUS(IDC_VALIDITY_EDIT, OnKillfocusValidityEdit)
  85. ON_CBN_KILLFOCUS(IDC_VALIDITY_UNITS, OnKillfocusValidityUnits)
  86. //}}AFX_MSG_MAP
  87. END_MESSAGE_MAP()
  88. /////////////////////////////////////////////////////////////////////////////
  89. // CTemplateGeneralPropertyPage message handlers
  90. BOOL CTemplateGeneralPropertyPage::OnInitDialog()
  91. {
  92. _TRACE (1, L"Entering CTemplateGeneralPropertyPage::OnInitDialog ()\n");
  93. CHelpPropertyPage::OnInitDialog();
  94. SendDlgItemMessage (IDC_VALIDITY_EDIT, EM_LIMITTEXT, 4, 0);
  95. SendDlgItemMessage (IDC_RENEWAL_EDIT, EM_LIMITTEXT, 4, 0);
  96. CString version;
  97. if ( 1 == m_rCertTemplate.GetType () )
  98. {
  99. VERIFY (version.LoadString (IDS_WINDOWS_2000_AND_LATER));
  100. }
  101. else
  102. {
  103. VERIFY (version.LoadString (IDS_WINDOWS_2002_AND_LATER));
  104. }
  105. SetDlgItemText (IDC_TEMPLATE_VERSION, version);
  106. if ( m_rCertTemplate.IsClone () )
  107. {
  108. GetDlgItem (IDC_CANT_CHANGE_TEMPLATE_NAME)->ShowWindow (SW_SHOW);
  109. }
  110. else
  111. {
  112. // The template name is only editable if the template is a clone. Since
  113. // this is not a clone, disable the template name fields.
  114. GetDlgItem (IDC_TEMPLATE_NAME)->EnableWindow (FALSE);
  115. GetDlgItem (IDC_TEMPLATE_NAME_LABEL)->EnableWindow (FALSE);
  116. // #NTRAID 360650: Cert Server: Cannot rename cert templates
  117. GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
  118. GetDlgItem (IDC_DISPLAY_NAME_LABEL)->EnableWindow (FALSE);
  119. }
  120. m_strTemplateName = m_rCertTemplate.GetTemplateName ();
  121. m_strOriginalDisplayName = m_strDisplayName = m_rCertTemplate.GetDisplayName ();
  122. // Get validity period, determine current units and then initialize drop down
  123. HRESULT hr = m_rCertTemplate.GetValidityPeriod (m_nValidityDays);
  124. if ( SUCCEEDED (hr) )
  125. {
  126. int nValue = m_nValidityDays;
  127. if ( nValue % 365 == 0 )
  128. {
  129. nValue /= 365;
  130. m_dwCurrentValidityUnits = PERIOD_TYPE_YEAR;
  131. }
  132. else if ( nValue % 30 == 0 )
  133. {
  134. nValue /= 30;
  135. m_dwCurrentValidityUnits = PERIOD_TYPE_MONTH;
  136. }
  137. else if ( nValue % 7 == 0 )
  138. {
  139. nValue /= 7;
  140. m_dwCurrentValidityUnits = PERIOD_TYPE_WEEK;
  141. }
  142. else
  143. m_dwCurrentValidityUnits = PERIOD_TYPE_DAY;
  144. SetDlgItemInt (IDC_VALIDITY_EDIT, (UINT) nValue, FALSE);
  145. }
  146. hr = m_rCertTemplate.GetRenewalPeriod (m_nRenewalDays);
  147. if ( SUCCEEDED (hr) )
  148. {
  149. int nValue = m_nRenewalDays;
  150. if ( nValue % 365 == 0 )
  151. {
  152. nValue /= 365;
  153. m_dwCurrentRenewalUnits = PERIOD_TYPE_YEAR;
  154. }
  155. else if ( nValue % 30 == 0 )
  156. {
  157. nValue /= 30;
  158. m_dwCurrentRenewalUnits = PERIOD_TYPE_MONTH;
  159. }
  160. else if ( nValue % 7 == 0 )
  161. {
  162. nValue /= 7;
  163. m_dwCurrentRenewalUnits = PERIOD_TYPE_WEEK;
  164. }
  165. else
  166. m_dwCurrentRenewalUnits = PERIOD_TYPE_DAY;
  167. SetDlgItemInt (IDC_RENEWAL_EDIT, (UINT) nValue, FALSE);
  168. }
  169. // Now that we know what units the validity and renewal periods are
  170. // to be displayed in, initialize the dropdowns and select the
  171. // appropriate unit
  172. // Initialize validity and renewal period dropdowns
  173. CString text;
  174. VERIFY (text.LoadString (IDS_DAYS));
  175. int nIndex = m_validityUnits.AddString (text);
  176. if ( nIndex >= 0 )
  177. {
  178. m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_DAY);
  179. if ( PERIOD_TYPE_DAY == m_dwCurrentValidityUnits )
  180. m_validityUnits.SetCurSel (nIndex);
  181. }
  182. nIndex = m_renewalUnits.AddString (text);
  183. if ( nIndex >= 0 )
  184. {
  185. m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_DAY);
  186. if ( PERIOD_TYPE_DAY == m_dwCurrentRenewalUnits )
  187. m_renewalUnits.SetCurSel (nIndex);
  188. }
  189. VERIFY (text.LoadString (IDS_WEEKS));
  190. nIndex = m_validityUnits.AddString (text);
  191. if ( nIndex >= 0 )
  192. {
  193. m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_WEEK);
  194. if ( PERIOD_TYPE_WEEK == m_dwCurrentValidityUnits )
  195. m_validityUnits.SetCurSel (nIndex);
  196. }
  197. nIndex = m_renewalUnits.AddString (text);
  198. if ( nIndex >= 0 )
  199. {
  200. m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_WEEK);
  201. if ( PERIOD_TYPE_WEEK == m_dwCurrentRenewalUnits )
  202. m_renewalUnits.SetCurSel (nIndex);
  203. }
  204. VERIFY (text.LoadString (IDS_MONTHS));
  205. nIndex = m_validityUnits.AddString (text);
  206. if ( nIndex >= 0 )
  207. {
  208. m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_MONTH);
  209. if ( PERIOD_TYPE_MONTH == m_dwCurrentValidityUnits )
  210. m_validityUnits.SetCurSel (nIndex);
  211. }
  212. nIndex = m_renewalUnits.AddString (text);
  213. if ( nIndex >= 0 )
  214. {
  215. m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_MONTH);
  216. if ( PERIOD_TYPE_MONTH == m_dwCurrentRenewalUnits )
  217. m_renewalUnits.SetCurSel (nIndex);
  218. }
  219. VERIFY (text.LoadString (IDS_YEARS));
  220. nIndex = m_validityUnits.AddString (text);
  221. if ( nIndex >= 0 )
  222. {
  223. m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_YEAR);
  224. if ( PERIOD_TYPE_YEAR == m_dwCurrentValidityUnits )
  225. m_validityUnits.SetCurSel (nIndex);
  226. }
  227. nIndex = m_renewalUnits.AddString (text);
  228. if ( nIndex >= 0 )
  229. {
  230. m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_YEAR);
  231. if ( PERIOD_TYPE_YEAR == m_dwCurrentRenewalUnits )
  232. m_renewalUnits.SetCurSel (nIndex);
  233. }
  234. if ( m_rCertTemplate.PublishToDS () )
  235. SendDlgItemMessage (IDC_PUBLISH_TO_AD, BM_SETCHECK, BST_CHECKED);
  236. if ( m_rCertTemplate.CheckDSCert () )
  237. SendDlgItemMessage (IDC_USE_AD_CERT_FOR_REENROLLMENT, BM_SETCHECK, BST_CHECKED);
  238. EnableControls ();
  239. UpdateData (FALSE);
  240. m_bIsDirty = false; // because SetDlgItemInt () sets it to true
  241. if ( m_rCertTemplate.IsClone () )
  242. {
  243. SetModified ();
  244. m_bIsDirty = true;
  245. }
  246. _TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::OnInitDialog ()\n");
  247. return TRUE; // return TRUE unless you set the focus to a control
  248. // EXCEPTION: OCX Property Pages should return FALSE
  249. }
  250. void CTemplateGeneralPropertyPage::EnableControls ()
  251. {
  252. if ( 1 == m_rCertTemplate.GetType () || m_rCertTemplate.ReadOnly () )
  253. {
  254. GetDlgItem (IDC_TEMPLATE_NAME)->EnableWindow (FALSE);
  255. GetDlgItem (IDC_TEMPLATE_NAME_LABEL)->EnableWindow (FALSE);
  256. GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
  257. GetDlgItem (IDC_DISPLAY_NAME_LABEL)->EnableWindow (FALSE);
  258. GetDlgItem (IDC_VALIDITY_UNITS)->EnableWindow (FALSE);
  259. GetDlgItem (IDC_VALIDITY_EDIT)->EnableWindow (FALSE);
  260. GetDlgItem (IDC_RENEWAL_UNITS)->EnableWindow (FALSE);
  261. GetDlgItem (IDC_RENEWAL_EDIT)->EnableWindow (FALSE);
  262. GetDlgItem (IDC_PUBLISH_TO_AD)->EnableWindow (FALSE);
  263. GetDlgItem (IDC_USE_AD_CERT_FOR_REENROLLMENT)->EnableWindow (FALSE);
  264. }
  265. else if ( m_rCertTemplate.IsDefault () )
  266. {
  267. GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
  268. }
  269. else
  270. {
  271. if ( BST_CHECKED == SendDlgItemMessage (IDC_PUBLISH_TO_AD, BM_GETCHECK) )
  272. GetDlgItem (IDC_USE_AD_CERT_FOR_REENROLLMENT)->EnableWindow (TRUE);
  273. else
  274. GetDlgItem (IDC_USE_AD_CERT_FOR_REENROLLMENT)->EnableWindow (FALSE);
  275. }
  276. }
  277. void CTemplateGeneralPropertyPage::OnCancel()
  278. {
  279. if ( !m_rCertTemplate.IsClone () )
  280. m_rCertTemplate.Cancel ();
  281. CHelpPropertyPage::OnCancel ();
  282. }
  283. int CTemplateGeneralPropertyPage::SetRenewalPeriod (int nMaxRenewalDays, bool bSilent)
  284. {
  285. CThemeContextActivator activator;
  286. CString caption;
  287. CString text;
  288. CString timeUnit;
  289. int nAmount = 0;
  290. VERIFY (caption.LoadString (IDS_CERTTMPL));
  291. if ( nMaxRenewalDays % 365 == 0 )
  292. {
  293. nAmount = nMaxRenewalDays/365;
  294. if ( 1 == nAmount )
  295. VERIFY (timeUnit.LoadString (IDS_YEAR));
  296. else
  297. VERIFY (timeUnit.LoadString (IDS_YEARS));
  298. }
  299. else if ( nMaxRenewalDays % 30 == 0 )
  300. {
  301. nAmount = nMaxRenewalDays/30;
  302. if ( 1 == nAmount )
  303. VERIFY (timeUnit.LoadString (IDS_MONTH));
  304. else
  305. VERIFY (timeUnit.LoadString (IDS_MONTHS));
  306. }
  307. else if ( nMaxRenewalDays % 7 == 0 )
  308. {
  309. nAmount = nMaxRenewalDays/7;
  310. if ( 1 == nAmount )
  311. VERIFY (timeUnit.LoadString (IDS_WEEK));
  312. else
  313. VERIFY (timeUnit.LoadString (IDS_WEEKS));
  314. }
  315. else
  316. {
  317. nAmount = nMaxRenewalDays;
  318. if ( 1 == nMaxRenewalDays )
  319. VERIFY (timeUnit.LoadString (IDS_DAY));
  320. else
  321. VERIFY (timeUnit.LoadString (IDS_DAYS));
  322. }
  323. text.FormatMessage (IDS_RENEWAL_MUST_BE_LESS_THAN_VALIDITY,
  324. nAmount, timeUnit);
  325. int nRetVal = IDOK;
  326. if ( !bSilent )
  327. nRetVal = MessageBox (text, caption, MB_OKCANCEL);
  328. if ( IDOK == nRetVal )
  329. {
  330. HRESULT hr = m_rCertTemplate.SetRenewalPeriod (nMaxRenewalDays);
  331. if ( SUCCEEDED (hr) )
  332. {
  333. m_nRenewalDays = nMaxRenewalDays;
  334. int nValue = m_nRenewalDays;
  335. if ( nValue % 365 == 0 )
  336. {
  337. nValue /= 365;
  338. m_dwCurrentRenewalUnits = PERIOD_TYPE_YEAR;
  339. }
  340. else if ( nValue % 30 == 0 )
  341. {
  342. nValue /= 30;
  343. m_dwCurrentRenewalUnits = PERIOD_TYPE_MONTH;
  344. }
  345. else if ( nValue % 7 == 0 )
  346. {
  347. nValue /= 7;
  348. m_dwCurrentRenewalUnits = PERIOD_TYPE_WEEK;
  349. }
  350. else
  351. m_dwCurrentRenewalUnits = PERIOD_TYPE_DAY;
  352. int nCnt = m_renewalUnits.GetCount ();
  353. while (--nCnt >= 0)
  354. {
  355. if ( m_dwCurrentRenewalUnits == (PERIOD_TYPE) m_renewalUnits.GetItemData (nCnt) )
  356. {
  357. m_renewalUnits.SetCurSel (nCnt);
  358. break;
  359. }
  360. }
  361. // Must set this after the units
  362. SetDlgItemInt (IDC_RENEWAL_EDIT, (UINT) nValue, FALSE);
  363. SetModified ();
  364. m_bIsDirty = true;
  365. }
  366. }
  367. return nRetVal;
  368. }
  369. #define ILLEGAL_FAT_CHARS L"\"+,;<=>"
  370. bool CTemplateGeneralPropertyPage::ValidateTemplateName(const CString& m_szTemplateName)
  371. {
  372. bool bRVal = true;
  373. PCWSTR szInvalidCharSet = ILLEGAL_FAT_CHARS;
  374. if ( -1 != m_szTemplateName.FindOneOf (szInvalidCharSet) )
  375. {
  376. bRVal = false;
  377. CString text;
  378. CString caption;
  379. VERIFY (caption.LoadString (IDS_CERTTMPL));
  380. CString charsWithSpaces;
  381. UINT nIndex = 0;
  382. while (szInvalidCharSet[nIndex])
  383. {
  384. charsWithSpaces += szInvalidCharSet[nIndex];
  385. charsWithSpaces += L" ";
  386. nIndex++;
  387. }
  388. text.FormatMessage (IDS_TEMPLATE_NAME_CONTAINS_INVALID_CHARS, charsWithSpaces);
  389. MessageBox (text, caption, MB_OK);
  390. GetDlgItem (IDC_TEMPLATE_NAME)->SetFocus ();
  391. }
  392. return bRVal;
  393. }
  394. BOOL CTemplateGeneralPropertyPage::OnApply()
  395. {
  396. UpdateData (TRUE);
  397. if ( m_rCertTemplate.GetType () > 1 && m_bIsDirty )
  398. {
  399. HRESULT hr = S_OK;
  400. if ( m_rCertTemplate.IssuancePoliciesRequired () )
  401. {
  402. CString text;
  403. CString caption;
  404. VERIFY (caption.LoadString (IDS_CERTTMPL));
  405. VERIFY (text.LoadString (IDS_MUST_ADD_RA_ISSUANCE_POLICY));
  406. MessageBox (text, caption, MB_OK);
  407. if ( -1 != m_nTemplateV2AuthPageNumber )
  408. {
  409. CWnd* pParent = GetParent ();
  410. if ( pParent )
  411. {
  412. pParent->SendMessage (PSM_SETCURSEL,
  413. m_nTemplateV2AuthPageNumber);
  414. }
  415. }
  416. return FALSE;
  417. }
  418. // NTRAID# 331178 Certtmpl: All Certificate Templates must enforce
  419. // that the certificate Renewal Period < = 75% of the Validity Period
  420. int nMaxRenewalDays = (m_nValidityDays * 3) / 4;
  421. if ( nMaxRenewalDays < m_nRenewalDays )
  422. {
  423. if ( IDOK != SetRenewalPeriod (nMaxRenewalDays, false) )
  424. {
  425. CWnd* pParent = GetParent ();
  426. if ( pParent )
  427. pParent->SendMessage (PSM_SETCURSEL, 0);
  428. GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
  429. return FALSE;
  430. }
  431. }
  432. // NTRAID# 353945: Certtmpl: Changing V2 certificate template validity
  433. // period to 1 Day, automatically sets the renewal period to 0 years
  434. if ( m_nValidityDays < 2 )
  435. {
  436. CString text;
  437. CString caption;
  438. VERIFY (caption.LoadString (IDS_CERTTMPL));
  439. VERIFY (text.LoadString (IDS_2_DAY_SMALLEST_VALIDITY));
  440. MessageBox (text, caption, MB_OK);
  441. CWnd* pParent = GetParent ();
  442. if ( pParent )
  443. pParent->SendMessage (PSM_SETCURSEL, 0);
  444. GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
  445. return FALSE;
  446. }
  447. // Note: The CERTYPE_PROP_CN resets the CERTTYPE_PROP_FRIENDLY_NAME
  448. // and so must be set before it.
  449. bool bResetDisplayName = false;
  450. if ( LocaleStrCmp (m_strTemplateName, m_rCertTemplate.GetTemplateName ()) )
  451. {
  452. bResetDisplayName = true;
  453. // Check new name for invalid characters
  454. m_strTemplateName.TrimLeft ();
  455. m_strTemplateName.TrimRight ();
  456. if ( !ValidateTemplateName (m_strTemplateName) )
  457. return FALSE;
  458. if ( _wcsicmp (m_strOriginalName, m_strTemplateName) ) // was renamed
  459. {
  460. // Ensure that the selected name is unique
  461. HCERTTYPE hCertType = 0;
  462. bool bFound = false;
  463. hr = CAFindCertTypeByName (m_rCertTemplate.GetTemplateName (),
  464. NULL,
  465. CT_ENUM_MACHINE_TYPES | CT_ENUM_USER_TYPES | CT_FLAG_NO_CACHE_LOOKUP,
  466. &hCertType);
  467. if ( SUCCEEDED (hr) )
  468. {
  469. bFound = TRUE;
  470. hr = CACloseCertType (hCertType);
  471. if ( FAILED (hr) )
  472. {
  473. _TRACE (0, L"CACloseCertType () failed: 0x%x", hr);
  474. }
  475. }
  476. else
  477. {
  478. if ( m_pCompData )
  479. {
  480. POSITION pos = 0;
  481. for (pos = m_pCompData->m_globalTemplateNameList.GetHeadPosition (); pos;)
  482. {
  483. if ( !_wcsicmp (m_strTemplateName,
  484. m_pCompData->m_globalTemplateNameList.GetNext (pos)) )
  485. {
  486. bFound = true;
  487. break;
  488. }
  489. }
  490. }
  491. }
  492. if ( bFound )
  493. {
  494. CString caption;
  495. CString text;
  496. VERIFY (caption.LoadString (IDS_CERTTMPL));
  497. text.FormatMessage (IDS_ENTER_UNIQUE_TEMPLATE_NAME,
  498. m_strTemplateName);
  499. MessageBox (text, caption, MB_OK);
  500. GetDlgItem (IDC_TEMPLATE_NAME)->SetFocus ();
  501. return FALSE;
  502. }
  503. }
  504. hr = m_rCertTemplate.SetTemplateName (m_strTemplateName);
  505. if ( FAILED (hr) )
  506. {
  507. CString caption;
  508. CString text;
  509. VERIFY (caption.LoadString (IDS_CERTTMPL));
  510. text.FormatMessage (IDS_CANNOT_CHANGE_TEMPLATE_NAME, hr);
  511. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  512. CWnd* pParent = GetParent ();
  513. if ( pParent )
  514. pParent->SendMessage (PSM_SETCURSEL, 0);
  515. GetDlgItem (IDC_TEMPLATE_NAME)->SetFocus ();
  516. return FALSE;
  517. }
  518. }
  519. // Check if the display name has changed. Don't allow reuse of existing names.
  520. if ( bResetDisplayName || _wcsicmp (m_strDisplayName, m_strOriginalDisplayName) )
  521. {
  522. bool bFound = false;
  523. if ( m_pCompData )
  524. {
  525. POSITION pos = 0;
  526. for (pos = m_pCompData->m_globalFriendlyNameList.GetHeadPosition (); pos;)
  527. {
  528. if ( !_wcsicmp (m_strDisplayName,
  529. m_pCompData->m_globalFriendlyNameList.GetNext (pos)) )
  530. {
  531. bFound = true;
  532. break;
  533. }
  534. }
  535. }
  536. else
  537. {
  538. // Generate list of templates and search for name. This should only be called
  539. // from the shell extension because it doesn't build the list of templates
  540. // beforehand
  541. hr = FindFriendlyNameInEnterpriseTemplates (
  542. m_strDisplayName,
  543. bFound);
  544. }
  545. if ( bFound )
  546. {
  547. CString caption;
  548. CString text;
  549. VERIFY (caption.LoadString (IDS_CERTTMPL));
  550. text.FormatMessage (IDS_FRIENDLY_NAME_ALREADY_USED, m_strDisplayName);
  551. MessageBox (text, caption, MB_OK);
  552. return FALSE;
  553. }
  554. else
  555. {
  556. hr = m_rCertTemplate.SetDisplayName (m_strDisplayName, true);
  557. if ( FAILED (hr) )
  558. {
  559. CString caption;
  560. CString text;
  561. VERIFY (caption.LoadString (IDS_CERTTMPL));
  562. text.FormatMessage (IDS_CANNOT_CHANGE_DISPLAY_NAME, hr);
  563. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  564. GetDlgItem (IDC_DISPLAY_NAME)->SetFocus ();
  565. return FALSE;
  566. }
  567. }
  568. }
  569. // // NTRAID# 276180 Certificate Template Snap-in: Grey out "Allow
  570. // // Autoenrollment" context menu based on properties of the template
  571. // DWORD dwNumSignatures = 0;
  572. // m_rCertTemplate.GetRANumSignaturesRequired (dwNumSignatures);
  573. // if ( m_rCertTemplate.RequireSubjectInRequest () ||
  574. // dwNumSignatures >= 2 && !m_rCertTemplate.ReenrollmentValidWithPreviousApproval () )
  575. // {
  576. // m_rCertTemplate.SetAutoEnrollment (false);
  577. // }
  578. hr = m_rCertTemplate.SaveChanges ();
  579. if ( SUCCEEDED (hr) )
  580. {
  581. m_strOriginalName = m_strTemplateName;
  582. hr = MMCPropertyChangeNotify (m_lNotifyHandle, // handle to a notification
  583. (LPARAM) &m_rCertTemplate); // unique identifier
  584. // Now that the template has been saved, never allow the internal
  585. // name to be edited.
  586. GetDlgItem (IDC_TEMPLATE_NAME)->EnableWindow (FALSE);
  587. GetDlgItem (IDC_TEMPLATE_NAME_LABEL)->EnableWindow (FALSE);
  588. // #NTRAID 360650: Cert Server: Cannot rename cert templates
  589. GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
  590. GetDlgItem (IDC_DISPLAY_NAME_LABEL)->EnableWindow (FALSE);
  591. }
  592. else
  593. {
  594. CString caption;
  595. CString text;
  596. VERIFY (caption.LoadString (IDS_CERTTMPL));
  597. text.FormatMessage (IDS_UNABLE_TO_SAVE_CERT_TEMPLATE_CHANGES, GetSystemMessage (hr));
  598. MessageBox (text, caption, MB_OK | MB_ICONWARNING);
  599. return FALSE;
  600. }
  601. m_bIsDirty = false;
  602. }
  603. return CHelpPropertyPage::OnApply();
  604. }
  605. void CTemplateGeneralPropertyPage::OnChangeDisplayName()
  606. {
  607. SetModified ();
  608. m_bIsDirty = true;
  609. if ( m_rCertTemplate.IsClone () )
  610. {
  611. CString text;
  612. GetDlgItemText (IDC_DISPLAY_NAME, text);
  613. // strip out spaces
  614. PCWSTR pszSrc = (PCWSTR) text;
  615. const int LEN = text.GetLength () + 1;
  616. PWSTR pszTgt = new WCHAR[LEN];
  617. PWSTR pszTgtPtr = pszTgt;
  618. ::ZeroMemory (pszTgt, LEN * sizeof (WCHAR));
  619. for (; *pszSrc; pszSrc++)
  620. {
  621. if ( !iswspace (*pszSrc) )
  622. {
  623. *pszTgtPtr = *pszSrc;
  624. pszTgtPtr++;
  625. }
  626. }
  627. SetDlgItemText (IDC_TEMPLATE_NAME, pszTgt);
  628. delete [] pszTgt;
  629. }
  630. }
  631. void CTemplateGeneralPropertyPage::OnChangeTemplateName()
  632. {
  633. UpdateData (TRUE);
  634. SetModified ();
  635. m_bIsDirty = true;
  636. }
  637. void CTemplateGeneralPropertyPage::OnSelchangeRenewalUnits()
  638. {
  639. OnChangeRenewalEdit ();
  640. }
  641. void CTemplateGeneralPropertyPage::OnSelchangeValidityUnits()
  642. {
  643. OnChangeValidityEdit ();
  644. }
  645. void CTemplateGeneralPropertyPage::OnChangeRenewalEdit()
  646. {
  647. HRESULT hr = S_OK;
  648. int nCurSel = m_renewalUnits.GetCurSel ();
  649. if ( nCurSel < 0 )
  650. return;
  651. int nCurVal = GetDlgItemInt (IDC_RENEWAL_EDIT);
  652. DWORD dwRenewalUnits = (PERIOD_TYPE) m_renewalUnits.GetItemData (nCurSel);
  653. // convert to days
  654. switch ( dwRenewalUnits )
  655. {
  656. case PERIOD_TYPE_DAY:
  657. break; // do nothing - is already days
  658. case PERIOD_TYPE_WEEK:
  659. nCurVal *= 7;
  660. break;
  661. case PERIOD_TYPE_MONTH:
  662. nCurVal *= 30;
  663. break;
  664. case PERIOD_TYPE_YEAR:
  665. nCurVal *= 365;
  666. break;
  667. case PERIOD_TYPE_NONE:
  668. default:
  669. _ASSERT (0);
  670. hr = E_FAIL; //don't know what the units are
  671. break;
  672. }
  673. if ( SUCCEEDED (hr) )
  674. {
  675. hr = m_rCertTemplate.SetRenewalPeriod (nCurVal);
  676. if ( SUCCEEDED (hr) )
  677. {
  678. m_nRenewalDays = nCurVal;
  679. SetModified ();
  680. m_bIsDirty = true;
  681. }
  682. }
  683. }
  684. void CTemplateGeneralPropertyPage::OnChangeValidityEdit()
  685. {
  686. HRESULT hr = S_OK;
  687. int nCurSel = m_validityUnits.GetCurSel ();
  688. if ( nCurSel < 0 )
  689. return;
  690. int nCurVal = GetDlgItemInt (IDC_VALIDITY_EDIT);
  691. DWORD dwValidityUnits = (PERIOD_TYPE) m_validityUnits.GetItemData (nCurSel);
  692. // convert to days
  693. switch ( dwValidityUnits )
  694. {
  695. case PERIOD_TYPE_DAY:
  696. break; // do nothing - is already days
  697. case PERIOD_TYPE_WEEK:
  698. nCurVal *= 7;
  699. break;
  700. case PERIOD_TYPE_MONTH:
  701. nCurVal *= 30;
  702. break;
  703. case PERIOD_TYPE_YEAR:
  704. nCurVal *= 365;
  705. break;
  706. case PERIOD_TYPE_NONE:
  707. default:
  708. _ASSERT (0);
  709. hr = E_FAIL; //don't know what the units are
  710. break;
  711. }
  712. if ( SUCCEEDED (hr) )
  713. {
  714. hr = m_rCertTemplate.SetValidityPeriod (nCurVal);
  715. if ( SUCCEEDED (hr) )
  716. {
  717. m_nValidityDays = nCurVal;
  718. SetModified ();
  719. m_bIsDirty = true;
  720. }
  721. }
  722. }
  723. void CTemplateGeneralPropertyPage::OnPublishToAd()
  724. {
  725. bool bPublishToAD = BST_CHECKED == SendDlgItemMessage (IDC_PUBLISH_TO_AD, BM_GETCHECK);
  726. m_rCertTemplate.SetPublishToDS (bPublishToAD);
  727. if ( !bPublishToAD )
  728. {
  729. SendDlgItemMessage (IDC_USE_AD_CERT_FOR_REENROLLMENT, BM_SETCHECK, BST_UNCHECKED);
  730. m_rCertTemplate.SetCheckDSCert (false);
  731. }
  732. SetModified ();
  733. m_bIsDirty = true;
  734. EnableControls ();
  735. }
  736. void CTemplateGeneralPropertyPage::DoContextHelp (HWND hWndControl)
  737. {
  738. _TRACE(1, L"Entering CTemplateGeneralPropertyPage::DoContextHelp\n");
  739. switch (::GetDlgCtrlID (hWndControl))
  740. {
  741. case IDC_STATIC:
  742. break;
  743. default:
  744. // Display context help for a control
  745. if ( !::WinHelp (
  746. hWndControl,
  747. GetContextHelpFile (),
  748. HELP_WM_HELP,
  749. (DWORD_PTR) g_aHelpIDs_IDD_TEMPLATE_GENERAL) )
  750. {
  751. _TRACE(0, L"WinHelp () failed: 0x%x\n", GetLastError ());
  752. }
  753. break;
  754. }
  755. _TRACE(-1, L"Leaving CTemplateGeneralPropertyPage::DoContextHelp\n");
  756. }
  757. void CTemplateGeneralPropertyPage::OnUseADCert()
  758. {
  759. bool bCheck = (BST_CHECKED == SendDlgItemMessage (IDC_USE_AD_CERT_FOR_REENROLLMENT, BM_GETCHECK) );
  760. m_rCertTemplate.SetCheckDSCert (bCheck);
  761. m_bIsDirty = true;
  762. SetModified ();
  763. }
  764. HRESULT CTemplateGeneralPropertyPage::EnumerateTemplates (
  765. IDirectoryObject* pTemplateContObj,
  766. const CString& szFriendlyName,
  767. bool& bFound)
  768. {
  769. _TRACE (1, L"Entering CTemplateGeneralPropertyPage::EnumerateTemplates\n");
  770. CComPtr<IDirectorySearch> spDsSearch;
  771. HRESULT hr = pTemplateContObj->QueryInterface (IID_PPV_ARG(IDirectorySearch, &spDsSearch));
  772. if ( SUCCEEDED (hr) )
  773. {
  774. ASSERT (!!spDsSearch);
  775. ADS_SEARCHPREF_INFO pSearchPref[1];
  776. DWORD dwNumPref = 1;
  777. pSearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  778. pSearchPref[0].vValue.dwType = ADSTYPE_INTEGER;
  779. pSearchPref[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  780. hr = spDsSearch->SetSearchPreference(
  781. pSearchPref,
  782. dwNumPref
  783. );
  784. if ( SUCCEEDED (hr) )
  785. {
  786. static const DWORD cAttrs = 1; //2;
  787. static PWSTR rgszAttrList[cAttrs] = {L"displayName"}; //, L"cn"};
  788. ADS_SEARCH_HANDLE hSearchHandle = 0;
  789. wstring strQuery;
  790. ADS_SEARCH_COLUMN Column;
  791. Column.pszAttrName = 0;
  792. strQuery = L"objectClass=pKICertificateTemplate";
  793. hr = spDsSearch->ExecuteSearch(
  794. const_cast <PWSTR>(strQuery.c_str ()),
  795. rgszAttrList,
  796. cAttrs,
  797. &hSearchHandle
  798. );
  799. if ( SUCCEEDED (hr) )
  800. {
  801. while ((hr = spDsSearch->GetNextRow (hSearchHandle)) != S_ADS_NOMORE_ROWS )
  802. {
  803. if (FAILED(hr))
  804. continue;
  805. //
  806. // Getting current row's information
  807. //
  808. hr = spDsSearch->GetColumn(
  809. hSearchHandle,
  810. rgszAttrList[0],
  811. &Column
  812. );
  813. if ( SUCCEEDED (hr) )
  814. {
  815. CString strDisplayName = Column.pADsValues->CaseIgnoreString;
  816. if ( !_wcsicmp (strDisplayName, szFriendlyName) )
  817. {
  818. bFound = true;
  819. }
  820. spDsSearch->FreeColumn (&Column);
  821. if ( bFound )
  822. break;
  823. }
  824. else if ( hr != E_ADS_COLUMN_NOT_SET )
  825. {
  826. break;
  827. }
  828. else
  829. {
  830. _TRACE (0, L"IDirectorySearch::GetColumn () failed: 0x%x\n", hr);
  831. }
  832. }
  833. }
  834. else
  835. {
  836. _TRACE (0, L"IDirectorySearch::ExecuteSearch () failed: 0x%x\n", hr);
  837. }
  838. spDsSearch->CloseSearchHandle(hSearchHandle);
  839. }
  840. else
  841. {
  842. _TRACE (0, L"IDirectorySearch::SetSearchPreference () failed: 0x%x\n", hr);
  843. }
  844. }
  845. else
  846. {
  847. _TRACE (0, L"IDirectoryObject::QueryInterface (IDirectorySearch) failed: 0x%x\n", hr);
  848. }
  849. _TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::EnumerateTemplates: 0x%x\n", hr);
  850. return hr;
  851. }
  852. HRESULT CTemplateGeneralPropertyPage::FindFriendlyNameInEnterpriseTemplates (
  853. const CString& szFriendlyName,
  854. bool& bFound)
  855. {
  856. _TRACE (1, L"Entering CTemplateGeneralPropertyPage::FindFriendlyNameInEnterpriseTemplates\n");
  857. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  858. HRESULT hr = S_OK;
  859. CComPtr<IADsPathname> spPathname;
  860. //
  861. // Constructing the directory paths
  862. //
  863. hr = CoCreateInstance(
  864. CLSID_Pathname,
  865. NULL,
  866. CLSCTX_ALL,
  867. IID_PPV_ARG (IADsPathname, &spPathname));
  868. if ( SUCCEEDED (hr) )
  869. {
  870. ASSERT (!!spPathname);
  871. hr = spPathname->Set(const_cast <PWSTR> (CERTTMPL_LDAP),
  872. ADS_SETTYPE_PROVIDER);
  873. if ( SUCCEEDED (hr) )
  874. {
  875. //
  876. // Open the root DSE object
  877. //
  878. hr = spPathname->AddLeafElement(const_cast <PWSTR> (CERTTMPL_ROOTDSE));
  879. if ( SUCCEEDED (hr) )
  880. {
  881. BSTR bstrFullPath = 0;
  882. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  883. if ( SUCCEEDED (hr) )
  884. {
  885. CComPtr<IADs> spRootDSEObject;
  886. VARIANT varNamingContext;
  887. hr = ADsGetObject (
  888. bstrFullPath,
  889. IID_PPV_ARG (IADs, &spRootDSEObject));
  890. if ( SUCCEEDED (hr) )
  891. {
  892. ASSERT (!!spRootDSEObject);
  893. //
  894. // Get the configuration naming context from the root DSE
  895. //
  896. hr = spRootDSEObject->Get(const_cast <PWSTR> (CERTTMPL_CONFIG_NAMING_CONTEXT),
  897. &varNamingContext);
  898. if ( SUCCEEDED (hr) )
  899. {
  900. hr = spPathname->Set(V_BSTR(&varNamingContext),
  901. ADS_SETTYPE_DN);
  902. if ( SUCCEEDED (hr) )
  903. {
  904. hr = spPathname->AddLeafElement (L"CN=Services");
  905. if ( SUCCEEDED (hr) )
  906. {
  907. hr = spPathname->AddLeafElement (L"CN=Public Key Services");
  908. if ( SUCCEEDED (hr) )
  909. {
  910. hr = spPathname->AddLeafElement (L"CN=Certificate Templates");
  911. if ( SUCCEEDED (hr) )
  912. {
  913. BSTR bstrCertTemplatePath = 0;
  914. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrCertTemplatePath);
  915. if ( SUCCEEDED (hr) )
  916. {
  917. CComPtr<IDirectoryObject> spTemplateContObj;
  918. hr = ADsGetObject (
  919. bstrCertTemplatePath,
  920. IID_PPV_ARG (IDirectoryObject, &spTemplateContObj));
  921. if ( SUCCEEDED (hr) )
  922. {
  923. hr = EnumerateTemplates (spTemplateContObj,
  924. szFriendlyName, bFound);
  925. }
  926. else
  927. {
  928. _TRACE (0, L"ADsGetObject (%s) failed: 0x%x\n", bstrCertTemplatePath, hr);
  929. }
  930. SysFreeString (bstrCertTemplatePath);
  931. }
  932. }
  933. }
  934. }
  935. }
  936. }
  937. else
  938. {
  939. _TRACE (0, L"IADs::Get (%s) failed: 0x%x\n", CERTTMPL_CONFIG_NAMING_CONTEXT, hr);
  940. }
  941. }
  942. else
  943. {
  944. _TRACE (0, L"ADsGetObject (%s) failed: 0x%x\n", bstrFullPath, hr);
  945. }
  946. }
  947. }
  948. }
  949. }
  950. else
  951. hr = E_POINTER;
  952. _TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::FindFriendlyNameInEnterpriseTemplates\n");
  953. return hr;
  954. }
  955. void CTemplateGeneralPropertyPage::OnKillfocusValidityEdit()
  956. {
  957. // NTRAID# 331178 Certtmpl: All Certificate Templates must enforce
  958. // that the certificate Renewal Period < = 75% of the Validity Period
  959. int nMaxRenewalDays = (m_nValidityDays * 3) / 4;
  960. if ( nMaxRenewalDays < m_nRenewalDays )
  961. {
  962. // change without confirmation
  963. SetRenewalPeriod (nMaxRenewalDays, true);
  964. GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
  965. }
  966. }
  967. void CTemplateGeneralPropertyPage::OnKillfocusValidityUnits()
  968. {
  969. // NTRAID# 331178 Certtmpl: All Certificate Templates must enforce
  970. // that the certificate Renewal Period < = 75% of the Validity Period
  971. int nMaxRenewalDays = (m_nValidityDays * 3) / 4;
  972. if ( nMaxRenewalDays < m_nRenewalDays )
  973. {
  974. // change without confirmation
  975. SetRenewalPeriod (nMaxRenewalDays, true);
  976. GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
  977. }
  978. }