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.

1184 lines
38 KiB

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