1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // frmHbaConfig.cpp - Backend access configuration tool
9 //
10 //////////////////////////////////////////////////////////////////////////
11
12
13 #include "pgAdmin3.h"
14
15 #ifdef __WXMSW__
16 #include <io.h>
17 #include <fcntl.h>
18 #endif
19
20 #include <wx/imaglist.h>
21
22 #include "ctl/ctlMenuToolbar.h"
23 #include "frm/frmHbaConfig.h"
24 #include "dlg/dlgHbaConfig.h"
25 #include "frm/frmMain.h"
26 #include "utils/utffile.h"
27 #include "schema/pgServer.h"
28 #include "frm/menu.h"
29 #include "utils/pgfeatures.h"
30
31 #define CTL_CFGVIEW 345
32
33 #include <wx/arrimpl.cpp>
34 WX_DEFINE_OBJARRAY(pgHbaConfigLineArray);
35
36
BEGIN_EVENT_TABLE(frmHbaConfig,frmConfig)37 BEGIN_EVENT_TABLE(frmHbaConfig, frmConfig)
38 EVT_MENU(MNU_UNDO, frmHbaConfig::OnUndo)
39 EVT_MENU(MNU_DELETE, frmHbaConfig::OnDelete)
40 EVT_MENU(MNU_CONTENTS, frmHbaConfig::OnContents)
41 EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmHbaConfig::OnEditSetting)
42 EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmHbaConfig::OnSelectSetting)
43 END_EVENT_TABLE()
44
45 #define BACE_TITLE _("Backend Access Configuration Editor")
46
47
48 frmHbaConfig::frmHbaConfig(frmMain *parent, pgServer *server)
49 : frmConfig(parent, BACE_TITLE, 0)
50 {
51 wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Configuration Editor");
52 if (server)
53 conn = server->CreateConn(wxEmptyString, 0, applicationname);
54 Init();
55
56 if (conn)
57 {
58 serverFileName = conn->ExecuteScalar(wxT("SHOW hba_file"));
59 if (serverFileName == wxT("unset") || serverFileName.IsEmpty())
60 serverFileName = wxT("pg_hba.conf");
61
62 wxString txt;
63 txt.Printf(_(" - %s on %s (%s:%d)"),
64 serverFileName.c_str(), server->GetDescription().c_str(),
65 server->GetName().c_str(), server->GetPort());
66 SetTitle(BACE_TITLE + txt);
67
68 wxString str;
69 str = conn->ExecuteScalar(wxT("SELECT pg_file_read('") + serverFileName + wxT("', 0, ")
70 wxT("pg_file_length('") + serverFileName + wxT("'))"));
71
72 DisplayFile(str);
73
74 statusBar->SetStatusText(wxString::Format(_(" Configuration read from %s"), conn->GetHost().c_str()));
75 }
76 }
77
78
frmHbaConfig(const wxString & title,const wxString & configFile)79 frmHbaConfig::frmHbaConfig(const wxString &title, const wxString &configFile)
80 : frmConfig(title + wxT(" - ") + _("Backend Access Configuration Editor"), configFile)
81 {
82
83 Init();
84
85 OpenLastFile();
86 }
87
88
~frmHbaConfig()89 frmHbaConfig::~frmHbaConfig()
90 {
91 }
92
93
Init()94 void frmHbaConfig::Init()
95 {
96 appearanceFactory->SetIcons(this);
97
98 InitFrame(wxT("frmHbaConfig"));
99 RestorePosition(150, 150, 650, 300, 300, 200);
100
101
102 listEdit = new ctlListView(this, CTL_CFGVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER);
103 listEdit->SetImageList(configImageList, wxIMAGE_LIST_SMALL);
104
105 listEdit->AddColumn(_("Type"), 40);
106 listEdit->AddColumn(_("Database"), 80);
107 listEdit->AddColumn(_("User"), 80);
108 listEdit->AddColumn(_("IP-Address"), 100);
109 listEdit->AddColumn(_("Method"), 40);
110 listEdit->AddColumn(_("Option"), 100);
111
112 helpMenu->Enable(MNU_HINT, false);
113 toolBar->EnableTool(MNU_HINT, false);
114
115 editMenu->Enable(MNU_DELETE, false);
116 toolBar->EnableTool(MNU_DELETE, false);
117 }
118
119
OnSelectSetting(wxListEvent & event)120 void frmHbaConfig::OnSelectSetting(wxListEvent &event)
121 {
122 // Enable delete because an item has been selected
123 if (event.GetIndex() != listEdit->GetItemCount() - 1)
124 {
125 editMenu->Enable(MNU_DELETE, true);
126 toolBar->EnableTool(MNU_DELETE, true);
127 }
128 else
129 {
130 editMenu->Enable(MNU_DELETE, false);
131 toolBar->EnableTool(MNU_DELETE, false);
132 }
133
134 // Disable undo because we don't want to undo the wrong line.
135 editMenu->Enable(MNU_UNDO, false);
136 toolBar->EnableTool(MNU_UNDO, false);
137 }
138
139
DisplayFile(const wxString & str)140 void frmHbaConfig::DisplayFile(const wxString &str)
141 {
142 lines.Empty();
143
144 filetype = wxTextFileType_Unix;
145 wxStringTokenizer strtok;
146
147 if (str.Find('\r') >= 0)
148 {
149 if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n")))
150 filetype = wxTextFileType_Dos;
151 else
152 filetype = wxTextFileType_Mac;
153
154 strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY);
155 }
156 else
157 strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY);
158
159 while (strtok.HasMoreTokens())
160 {
161 pgHbaConfigLine *line = new pgHbaConfigLine(strtok.GetNextToken());
162 lines.Add(line);
163 }
164
165 listEdit->DeleteAllItems();
166
167 size_t i = lines.GetCount();
168
169 // make sure the last line is empty
170
171 for (i = 0 ; i < lines.GetCount() ; i++)
172 {
173 pgHbaConfigLine &line = lines.Item(i);
174 const wxChar *connTypeStr = line.GetConnectType();
175 if ((line.isValid || (!line.isValid && !line.isComment)) && !line.GetText().IsEmpty())
176 {
177 int imgIndex = 0;
178 if (!line.isComment)
179 imgIndex = 1;
180 long pos = listEdit->AppendItem(imgIndex, connTypeStr, line.database, line.user);
181 listEdit->SetItem(pos, 3, line.ipaddress);
182 listEdit->SetItem(pos, 4, line.GetMethod());
183 listEdit->SetItem(pos, 5, line.option);
184
185 line.item = pos;
186 }
187 }
188 if (!i || !lines.Item(i - 1).text.IsEmpty())
189 {
190 pgHbaConfigLine *line = new pgHbaConfigLine();
191 lines.Add(line);
192 line->item = listEdit->AppendItem(0, wxString(wxEmptyString));
193 }
194 }
195
196
WriteFile(pgConn * conn)197 void frmHbaConfig::WriteFile(pgConn *conn)
198 {
199 wxString str;
200 size_t i;
201 for (i = 0 ; i < lines.GetCount() - 1 ; i++)
202 str.Append(lines.Item(i).GetText() + wxT("\n"));
203
204 if (DoWriteFile(str, conn))
205 {
206 changed = false;
207 fileMenu->Enable(MNU_SAVE, false);
208 editMenu->Enable(MNU_UNDO, false);
209 toolBar->EnableTool(MNU_SAVE, false);
210 toolBar->EnableTool(MNU_UNDO, false);
211
212 // make intermediate change current
213 for (i = 0 ; i < lines.GetCount() ; i++)
214 lines.Item(i).Init(lines.Item(i).GetText());
215 }
216 }
217
218
GetHintString()219 wxString frmHbaConfig::GetHintString()
220 {
221 wxString hint;
222 return hint;
223 }
224
225
GetHelpPage() const226 wxString frmHbaConfig::GetHelpPage() const
227 {
228 wxString page = wxT("client-authentication");
229 return page;
230 }
231
232
OnContents(wxCommandEvent & event)233 void frmHbaConfig::OnContents(wxCommandEvent &event)
234 {
235 DisplayHelp(wxT("index"), HELP_PGADMIN);
236 }
237
238
OnUndo(wxCommandEvent & ev)239 void frmHbaConfig::OnUndo(wxCommandEvent &ev)
240 {
241 int pos = listEdit->GetSelection();
242 if (pos >= 0)
243 {
244 size_t i;
245 for (i = 0 ; i < lines.GetCount() ; i++)
246 {
247 pgHbaConfigLine &line = lines.Item(i);
248
249 if (line.item == pos)
250 {
251 line.Init(line.text);
252 UpdateDisplay(line);
253 break;
254 }
255 }
256 }
257 }
258
OnDelete(wxCommandEvent & event)259 void frmHbaConfig::OnDelete(wxCommandEvent &event)
260 {
261 bool found = false;
262 int pos = listEdit->GetSelection();
263 if (pos >= 0)
264 {
265 listEdit->DeleteCurrentItem();
266 size_t i;
267 for (i = 0; i < lines.GetCount(); i++)
268 {
269 if (lines.Item(i).item == pos)
270 {
271 lines.RemoveAt(i);
272 changed = true;
273 fileMenu->Enable(MNU_SAVE, true);
274 editMenu->Enable(MNU_UNDO, false);
275 editMenu->Enable(MNU_DELETE, false);
276 toolBar->EnableTool(MNU_SAVE, true);
277 toolBar->EnableTool(MNU_UNDO, false);
278 toolBar->EnableTool(MNU_DELETE, false);
279 found = true;
280 break;
281 }
282 }
283 if (found)
284 {
285 /* Renumber all positions */
286 for (i = 0; i < lines.GetCount(); i++)
287 {
288 if (lines.Item(i).item > pos)
289 lines.Item(i).item--;
290 }
291 }
292 }
293 }
294
295
UpdateDisplay(pgHbaConfigLine & line)296 void frmHbaConfig::UpdateDisplay(pgHbaConfigLine &line)
297 {
298 long pos = line.item;
299 listEdit->SetItemImage(pos, (line.isComment ? 0 : 1));
300 listEdit->SetItem(pos, 0, line.GetConnectType());
301 listEdit->SetItem(pos, 1, line.database);
302 listEdit->SetItem(pos, 2, line.user);
303 listEdit->SetItem(pos, 3, line.ipaddress);
304 listEdit->SetItem(pos, 4, line.GetMethod());
305 listEdit->SetItem(pos, 5, line.option);
306 }
307
308
OnEditSetting(wxListEvent & event)309 void frmHbaConfig::OnEditSetting(wxListEvent &event)
310 {
311 long pos = event.GetIndex();
312 if (pos < 0)
313 return;
314
315 size_t i;
316
317 for (i = 0 ; i < lines.GetCount() ; i++)
318 {
319 if (lines.Item(i).item == pos)
320 {
321 pgHbaConfigLine &line = lines.Item(i);
322 bool isLastLine = (i == lines.GetCount() - 1 && line.isComment && !line.GetConnectType());
323
324 dlgHbaConfig dlg(this, &line, conn);
325 if (dlg.Go() == wxID_OK)
326 {
327 UpdateDisplay(line);
328
329 if (isLastLine)
330 {
331 long pos = listEdit->AppendItem(0, wxString(wxEmptyString));
332 pgHbaConfigLine *line = new pgHbaConfigLine();
333 line->item = pos;
334 lines.Add(line);
335 }
336 changed = true;
337 fileMenu->Enable(MNU_SAVE, true);
338 editMenu->Enable(MNU_UNDO, true);
339 toolBar->EnableTool(MNU_SAVE, true);
340 toolBar->EnableTool(MNU_UNDO, true);
341 }
342 break;
343 }
344 }
345 }
346
347
hbaConfigFactory(menuFactoryList * list,wxMenu * mnu,ctlMenuToolbar * toolbar)348 hbaConfigFactory::hbaConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list)
349 {
350 mnu->Append(id, wxT("pg_hba.conf"), _("Edit server access configuration file."));
351 }
352
353
StartDialog(frmMain * form,pgObject * obj)354 wxWindow *hbaConfigFactory::StartDialog(frmMain *form, pgObject *obj)
355 {
356 pgServer *server = obj->GetServer();
357 if (server)
358 {
359 frmHbaConfig *frm = new frmHbaConfig(form, server);
360 frm->Go();
361 return frm;
362 }
363 return 0;
364 }
365
366
CheckEnable(pgObject * obj)367 bool hbaConfigFactory::CheckEnable(pgObject *obj)
368 {
369 if (obj)
370 {
371 pgServer *server = obj->GetServer();
372 if (server)
373 {
374 pgConn *conn = server->GetConnection();
375 return conn && server->GetSuperUser() && conn->HasFeature(FEATURE_FILEREAD);
376 }
377 }
378 return false;
379 }
380
381
hbaConfigFileFactory(menuFactoryList * list,wxMenu * mnu,ctlMenuToolbar * toolbar)382 hbaConfigFileFactory::hbaConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list)
383 {
384 mnu->Append(id, _("Open pg_hba.conf..."), _("Open configuration editor with pg_hba.conf."));
385 }
386
387
StartDialog(frmMain * form,pgObject * obj)388 wxWindow *hbaConfigFileFactory::StartDialog(frmMain *form, pgObject *obj)
389 {
390 frmConfig *dlg = new frmHbaConfig(form);
391 dlg->Go();
392 dlg->DoOpen();
393 return dlg;
394 }
395