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.

634 lines
12 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. accessdl.cpp
  5. Abstract:
  6. Access Dialog
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "comprop.h"
  18. #include "sitesecu.h"
  19. #include "accessdl.h"
  20. #include "dnsnamed.h"
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char BASED_CODE THIS_FILE[] = __FILE__;
  24. #endif // _DEBUG
  25. CIPAccessDlg::CIPAccessDlg(
  26. IN BOOL fDenyAccessMode,
  27. IN OUT CIPAccessDescriptor *& pAccess,
  28. IN CObListPlus * poblAccessList OPTIONAL,
  29. IN CWnd * pParent OPTIONAL,
  30. IN BOOL fAllowDomains
  31. )
  32. /*++
  33. Routine Description:
  34. Constructor for the access descriptor editor dialog. If constructed
  35. with a NULL access descriptor pointer, the access descriptor will
  36. be allocated, otherwise the dialog will edit the existing one in
  37. place.
  38. Arguments:
  39. BOOL fDenyAccessMode : If TRUE, we're denying access, if FALSE,
  40. we're granting access.
  41. CIPAccessDescriptor *& pAccess : Object being edited, or NULL to allocate
  42. a new access descriptor
  43. CObListPlus * poblAccessList : List of already existing entries to check
  44. for duplicates, or NULL
  45. CWnd * pParent, : Pointer to parent window or NULL
  46. BOOL fAllowDomains : If TRUE, domain names are valid, otherwise
  47. they will not be available
  48. Return Value:
  49. N/A
  50. --*/
  51. : CDialog(CIPAccessDlg::IDD, pParent),
  52. m_pAccess(pAccess),
  53. m_poblAccessList(poblAccessList),
  54. m_fNew(pAccess == NULL),
  55. m_fDenyAccessMode(fDenyAccessMode),
  56. m_fAllowDomains(fAllowDomains)
  57. {
  58. #if 0 // Keep Class Wizard happy
  59. //{{AFX_DATA_INIT(CIPAccessDlg)
  60. m_nStyle = RADIO_SINGLE;
  61. //}}AFX_DATA_INIT
  62. #endif // 0
  63. if (m_pAccess == NULL)
  64. {
  65. //
  66. // Allocate new one
  67. //
  68. m_pAccess = new CIPAccessDescriptor;
  69. if (m_pAccess)
  70. {
  71. m_pAccess->GrantAccess(!m_fDenyAccessMode);
  72. }
  73. }
  74. if (m_pAccess == NULL)
  75. {
  76. TRACEEOLID("Invalid access object -- possible memory failure");
  77. return;
  78. }
  79. if (m_pAccess->IsDomainName())
  80. {
  81. m_nStyle = RADIO_DOMAIN;
  82. }
  83. else
  84. {
  85. m_nStyle = m_pAccess->IsSingle() ? RADIO_SINGLE : RADIO_MULTIPLE;
  86. }
  87. //
  88. // We can only look at granted items when
  89. // deny by default is on and vice versa
  90. //
  91. ASSERT(m_pAccess->HasAccess() == !m_fDenyAccessMode);
  92. //
  93. // Load static strings
  94. //
  95. VERIFY(m_strIPAddress.LoadString(IDS_PROMPT_IP_ADDRESS));
  96. VERIFY(m_strNetworkID.LoadString(IDS_PROMPT_NETWORK_ID));
  97. VERIFY(m_strDomainName.LoadString(IDS_PROMPT_DOMAIN));
  98. }
  99. void
  100. CIPAccessDlg::DoDataExchange(
  101. IN CDataExchange * pDX
  102. )
  103. /*++
  104. Routine Description:
  105. Initialise/Store control data
  106. Arguments:
  107. CDataExchange * pDX - DDX/DDV control structure
  108. Return Value:
  109. None
  110. --*/
  111. {
  112. CDialog::DoDataExchange(pDX);
  113. //{{AFX_DATA_MAP(CIPAccessDlg)
  114. DDX_Control(pDX, IDOK, m_button_OK);
  115. DDX_Control(pDX, IDC_EDIT_DOMAIN, m_edit_Domain);
  116. DDX_Control(pDX, IDC_STATIC_IP_ADDRESS, m_static_IpAddress);
  117. DDX_Control(pDX, IDC_STATIC_SUBNET_MASK, m_static_SubnetMask);
  118. DDX_Control(pDX, IDC_BUTTON_DNS, m_button_DNS);
  119. DDX_Radio(pDX, IDC_RADIO_SINGLE, m_nStyle);
  120. //}}AFX_DATA_MAP
  121. DDX_Control(pDX, IDC_RADIO_DOMAIN, m_radio_Domain);
  122. DDX_Control(pDX, IDC_IPA_IPADDRESS, m_ipa_IPAddress);
  123. DDX_Control(pDX, IDC_IPA_SUBNET_MASK, m_ipa_SubnetMask);
  124. }
  125. //
  126. // Message Map
  127. //
  128. BEGIN_MESSAGE_MAP(CIPAccessDlg, CDialog)
  129. //{{AFX_MSG_MAP(CIPAccessDlg)
  130. ON_BN_CLICKED(IDC_RADIO_MULTIPLE, OnRadioMultiple)
  131. ON_BN_CLICKED(IDC_RADIO_SINGLE, OnRadioSingle)
  132. ON_BN_CLICKED(IDC_RADIO_DOMAIN, OnRadioDomain)
  133. ON_BN_CLICKED(IDC_BUTTON_DNS, OnButtonDns)
  134. //}}AFX_MSG_MAP
  135. ON_EN_CHANGE(IDC_IPA_IPADDRESS, OnItemChanged)
  136. ON_EN_CHANGE(IDC_IPA_SUBNET_MASK, OnItemChanged)
  137. ON_EN_CHANGE(IDC_EDIT_DOMAIN, OnItemChanged)
  138. END_MESSAGE_MAP()
  139. void
  140. CIPAccessDlg::SetControlStates(
  141. IN int nStyle
  142. )
  143. /*++
  144. Routine Description:
  145. Show/hide controls depending on the type of access descriptor we're
  146. editing.
  147. Arguments:
  148. int nStyle : Radio button style
  149. Return Value:
  150. None
  151. --*/
  152. {
  153. m_nStyle = nStyle;
  154. ActivateControl(m_ipa_IPAddress, m_nStyle != RADIO_DOMAIN);
  155. ActivateControl(m_static_SubnetMask, m_nStyle == RADIO_MULTIPLE);
  156. ActivateControl(m_ipa_SubnetMask, m_nStyle == RADIO_MULTIPLE);
  157. ActivateControl(m_button_DNS, m_nStyle == RADIO_SINGLE);
  158. ActivateControl(m_edit_Domain, m_nStyle == RADIO_DOMAIN);
  159. //
  160. // Change the prompt over the editbox/ip address box to explain
  161. // what's supposed to be edited.
  162. //
  163. switch(m_nStyle)
  164. {
  165. case RADIO_SINGLE:
  166. m_static_IpAddress.SetWindowText(m_strIPAddress);
  167. break;
  168. case RADIO_MULTIPLE:
  169. m_static_IpAddress.SetWindowText(m_strNetworkID);
  170. break;
  171. case RADIO_DOMAIN:
  172. ASSERT(m_fAllowDomains);
  173. m_static_IpAddress.SetWindowText(m_strDomainName);
  174. break;
  175. }
  176. }
  177. //
  178. // Message Handlers
  179. //
  180. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  181. BOOL
  182. CIPAccessDlg::OnInitDialog()
  183. /*++
  184. Routine Description:
  185. WM_INITDIALOG handler. Initialize the dialog.
  186. Arguments:
  187. None.
  188. Return Value:
  189. TRUE if no focus is to be set automatically, FALSE if the focus
  190. is already set.
  191. --*/
  192. {
  193. CDialog::OnInitDialog();
  194. ASSERT(m_pAccess != NULL);
  195. if (m_pAccess == NULL)
  196. {
  197. TRACEEOLID("access descriptor is NULL -- aborting dialog");
  198. CError::MessageBox(ERROR_NOT_ENOUGH_MEMORY);
  199. EndDialog(IDCANCEL);
  200. return FALSE;
  201. }
  202. //
  203. // Domain selection not always available
  204. //
  205. ASSERT(!(!m_fAllowDomains && m_pAccess->IsDomainName()));
  206. ActivateControl(m_radio_Domain, m_fAllowDomains);
  207. //
  208. // Use an appropriate title for the dialog depending on
  209. // whether we're editing a 'grant' item or a 'deny' item
  210. //
  211. CString strTitle;
  212. VERIFY(strTitle.LoadString(m_fDenyAccessMode
  213. ? IDS_DENY
  214. : IDS_GRANT));
  215. SetWindowText(strTitle);
  216. //
  217. // Set fields to be edited
  218. //
  219. if (m_pAccess->IsDomainName())
  220. {
  221. m_edit_Domain.SetWindowText(m_pAccess->QueryDomainName());
  222. }
  223. else
  224. {
  225. DWORD dwIP = m_pAccess->QueryIPAddress();
  226. if (dwIP != 0L)
  227. {
  228. m_ipa_IPAddress.SetAddress(m_pAccess->QueryIPAddress());
  229. }
  230. if (!m_pAccess->IsSingle())
  231. {
  232. m_ipa_SubnetMask.SetAddress(m_pAccess->QuerySubnetMask());
  233. }
  234. }
  235. //
  236. // Configure the dialog appropriately
  237. //
  238. SetControlStates(m_nStyle);
  239. //
  240. // No changes made yet
  241. //
  242. m_button_OK.EnableWindow(FALSE);
  243. return TRUE;
  244. }
  245. void
  246. CIPAccessDlg::OnRadioSingle()
  247. /*++
  248. Routine Description:
  249. 'Single' radio button has been pressed. Change dialog style
  250. appropriately.
  251. Arguments:
  252. None
  253. Return Value:
  254. None
  255. --*/
  256. {
  257. SetControlStates(RADIO_SINGLE);
  258. OnItemChanged();
  259. }
  260. void
  261. CIPAccessDlg::OnRadioMultiple()
  262. /*++
  263. Routine Description:
  264. 'Multiple' radio button has been pressed. Change dialog style
  265. appropriately.
  266. Arguments:
  267. None
  268. Return Value:
  269. None
  270. --*/
  271. {
  272. SetControlStates(RADIO_MULTIPLE);
  273. OnItemChanged();
  274. }
  275. void
  276. CIPAccessDlg::OnRadioDomain()
  277. /*++
  278. Routine Description:
  279. 'Domain' radio button has been pressed. Change dialog style
  280. appropriately. If this the first time domain has been pressed,
  281. put up a warning about the performance implications of using
  282. domain filtering.
  283. Arguments:
  284. None
  285. Return Value:
  286. None
  287. --*/
  288. {
  289. ASSERT(m_fAllowDomains);
  290. static BOOL fShownWarning = FALSE;
  291. if (!fShownWarning)
  292. {
  293. fShownWarning = TRUE;
  294. ::AfxMessageBox(IDS_DOMAIN_PERF);
  295. }
  296. SetControlStates(RADIO_DOMAIN);
  297. OnItemChanged();
  298. }
  299. void
  300. CIPAccessDlg::OnItemChanged()
  301. /*++
  302. Routine Description:
  303. Control data has changed. Check to see if sufficient data have been
  304. entered given the type of access descriptor being edited, and enable
  305. or disable the OK button based on that result.
  306. Arguments:
  307. None
  308. Return Value:
  309. None
  310. --*/
  311. {
  312. DWORD dwIP;
  313. DWORD dwMask;
  314. BOOL fOK = FALSE;
  315. CString strDomain;
  316. switch(m_nStyle)
  317. {
  318. case RADIO_DOMAIN:
  319. m_edit_Domain.GetWindowText(strDomain);
  320. fOK = !strDomain.IsEmpty();
  321. break;
  322. case RADIO_SINGLE:
  323. m_ipa_IPAddress.GetAddress(&dwIP);
  324. fOK = (dwIP != 0L);
  325. break;
  326. case RADIO_MULTIPLE:
  327. m_ipa_IPAddress.GetAddress(&dwIP);
  328. m_ipa_SubnetMask.GetAddress(&dwMask);
  329. fOK = (dwIP != 0L && dwMask != 0L);
  330. break;
  331. }
  332. m_button_OK.EnableWindow(fOK);
  333. }
  334. void
  335. CIPAccessDlg::OnButtonDns()
  336. /*++
  337. Routine Description:
  338. 'DNS' Button was pressed. Bring up the DNS name resolver dialog
  339. which will set the value in the associated IP address control.
  340. Arguments:
  341. None
  342. Return Value:
  343. None
  344. --*/
  345. {
  346. //
  347. // Ask for a DNS name to resolve to an IP address. The ip address
  348. // control is passed along to the dns name dialog which will manage
  349. // the ip addresses in it automatically.
  350. //
  351. CDnsNameDlg dlg(&m_ipa_IPAddress);
  352. dlg.DoModal();
  353. }
  354. void
  355. CIPAccessDlg::OnCancel()
  356. /*++
  357. Routine Description:
  358. IDCANCEL handler. If we had allocated the access descriptor, throw it
  359. away now.
  360. Arguments:
  361. None
  362. Return Value:
  363. None
  364. --*/
  365. {
  366. if (m_fNew && m_pAccess != NULL)
  367. {
  368. delete m_pAccess;
  369. m_pAccess = NULL;
  370. }
  371. CDialog::OnCancel();
  372. }
  373. void
  374. CIPAccessDlg::OnOK()
  375. /*++
  376. Routine Description:
  377. Handler for IDOK. Save control data to the access descriptor object
  378. being edited. If we have a list of access descriptors, check for
  379. duplicates.
  380. Arguments:
  381. None
  382. Return Value:
  383. None
  384. --*/
  385. {
  386. //
  387. // Must have been allocated by now.
  388. //
  389. ASSERT(m_pAccess != NULL);
  390. UpdateData(TRUE);
  391. if (m_nStyle == RADIO_DOMAIN)
  392. {
  393. CString strDomain;
  394. m_edit_Domain.GetWindowText(strDomain);
  395. //
  396. // Ensure that wildcards are used only in the first char
  397. // of the name, or not at all.
  398. //
  399. int nWildCard;
  400. if ((nWildCard = strDomain.ReverseFind(_T('*'))) != -1)
  401. {
  402. if (nWildCard != 0
  403. || strDomain.GetLength() < 3
  404. || strDomain[1] != _T('.'))
  405. {
  406. //
  407. // Don't dismiss
  408. //
  409. m_edit_Domain.SetFocus();
  410. m_edit_Domain.SetSel(0,-1);
  411. ::AfxMessageBox(IDS_INVALID_DOMAIN_NAME);
  412. return;
  413. }
  414. }
  415. m_pAccess->SetValues(!m_fDenyAccessMode, strDomain);
  416. }
  417. else
  418. {
  419. DWORD dwIP;
  420. m_ipa_IPAddress.GetAddress(&dwIP);
  421. //
  422. // Filter out bogus ip addresses
  423. //
  424. if (dwIP == 0L || dwIP == (DWORD)-1L)
  425. {
  426. //
  427. // Don't dismiss the dialog
  428. //
  429. m_ipa_IPAddress.SetFocus(0);
  430. ::AfxMessageBox(IDS_IP_INVALID);
  431. return;
  432. }
  433. if (m_nStyle == RADIO_SINGLE)
  434. {
  435. m_pAccess->SetValues(!m_fDenyAccessMode, dwIP);
  436. }
  437. else // Multiple
  438. {
  439. DWORD dwMask;
  440. m_ipa_SubnetMask.GetAddress(&dwMask);
  441. m_pAccess->SetValues(!m_fDenyAccessMode, dwIP, dwMask);
  442. }
  443. }
  444. //
  445. // Check for duplicates in the list
  446. //
  447. if (m_poblAccessList)
  448. {
  449. if (m_pAccess->DuplicateInList(*m_poblAccessList))
  450. {
  451. //
  452. // Found duplicate; don't dismiss the dialog
  453. //
  454. ::AfxMessageBox(IDS_DUPLICATE_ENTRY);
  455. return;
  456. }
  457. }
  458. //
  459. // Everything ok -- dismiss the dialog.
  460. //
  461. CDialog::OnOK();
  462. }