]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/store/postgresql/postgresql_store_admins.cpp
Use std::lock_guard instead of STG_LOCKER.
[stg.git] / projects / stargazer / plugins / store / postgresql / postgresql_store_admins.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
19  */
20
21 /*
22  *  Administrators manipulation methods
23  *
24  *  $Revision: 1.3 $
25  *  $Date: 2010/11/08 10:10:24 $
26  *
27  */
28
29 #include "postgresql_store.h"
30
31 #include "stg/common.h"
32 #include "stg/admin_conf.h"
33 #include "stg/blowfish.h"
34
35 #include <string>
36 #include <vector>
37 #include <sstream>
38
39 #include <libpq-fe.h>
40
41 #define adm_enc_passwd "cjeifY8m3"
42
43 //-----------------------------------------------------------------------------
44 int POSTGRESQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
45 {
46 std::lock_guard lock(m_mutex);
47
48 if (PQstatus(connection) != CONNECTION_OK)
49     {
50     printfd(__FILE__, "POSTGRESQL_STORE::GetAdminsList(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
51     if (Reset())
52         {
53         strError = "Connection lost";
54         printfd(__FILE__, "POSTGRESQL_STORE::GetAdminsList(): '%s'\n", strError.c_str());
55         return -1;
56         }
57     }
58
59 PGresult * result;
60
61 if (StartTransaction())
62     {
63     printfd(__FILE__, "POSTGRESQL_STORE::GetAdminsList(): 'Failed to start transaction'\n");
64     return -1;
65     }
66
67 result = PQexec(connection, "SELECT login FROM tb_admins WHERE login <> '@stargazer'");
68
69 if (PQresultStatus(result) != PGRES_TUPLES_OK)
70     {
71     strError = PQresultErrorMessage(result);
72     PQclear(result);
73     printfd(__FILE__, "POSTGRESQL_STORE::GetAdminsList(): '%s'\n", strError.c_str());
74     if (RollbackTransaction())
75         {
76         printfd(__FILE__, "POSTGRESQL_STORE::GetAdminsList(): 'Failed to rollback transaction'\n");
77         }
78     return -1;
79     }
80
81 int tuples = PQntuples(result);
82
83 for (int i = 0; i < tuples; ++i)
84     {
85     adminsList->push_back(PQgetvalue(result, i, 0));
86     }
87
88 PQclear(result);
89
90 if (CommitTransaction())
91     {
92     printfd(__FILE__, "POSTGRESQL_STORE::GetAdminsList(): 'Failed to commit transaction'\n");
93     return -1;
94     }
95
96 return 0;
97 }
98
99 //-----------------------------------------------------------------------------
100 int POSTGRESQL_STORE::SaveAdmin(const STG::AdminConf & ac) const
101 {
102 std::lock_guard lock(m_mutex);
103
104 if (PQstatus(connection) != CONNECTION_OK)
105     {
106     printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
107     if (Reset())
108         {
109         strError = "Connection lost";
110         printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): '%s'\n", strError.c_str());
111         return -1;
112         }
113     }
114
115 PGresult * result;
116
117 if (StartTransaction())
118     {
119     printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Failed to start transaction'\n");
120     return -1;
121     }
122
123 char encodedPass[2 * ADM_PASSWD_LEN + 2];
124 char cryptedPass[ADM_PASSWD_LEN + 1];
125 char adminPass[ADM_PASSWD_LEN + 1];
126 BLOWFISH_CTX ctx;
127
128 memset(cryptedPass, 0, ADM_PASSWD_LEN + 1);
129 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
130 InitContext(adm_enc_passwd, sizeof(adm_enc_passwd), &ctx);
131
132 for (int i = 0; i < ADM_PASSWD_LEN / 8; i++)
133     EncryptBlock(cryptedPass + 8 * i, adminPass + 8 * i, &ctx);
134
135 cryptedPass[ADM_PASSWD_LEN] = 0;
136 Encode12(encodedPass, cryptedPass, ADM_PASSWD_LEN);
137
138 std::string pass = encodedPass;
139 std::string login = ac.login;
140
141 if (EscapeString(pass))
142     {
143     printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Failed to escape password'\n");
144     if (RollbackTransaction())
145         {
146         printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Failed to rollback transaction'\n");
147         }
148     return -1;
149     }
150
151 if (EscapeString(login))
152     {
153     printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Failed to escape login'\n");
154     if (RollbackTransaction())
155         {
156         printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Failed to rollback transaction'\n");
157         }
158     return -1;
159     }
160
161 std::stringstream query;
162 query << "UPDATE tb_admins SET "
163           << "passwd = '" << pass << "', "
164           << "chg_conf = " << ac.priv.userConf << ", "
165           << "chg_password = " << ac.priv.userPasswd << ", "
166           << "chg_stat = " << ac.priv.userStat << ", "
167           << "chg_cash = " << ac.priv.userCash << ", "
168           << "usr_add_del = " << ac.priv.userAddDel << ", "
169           << "chg_tariff = " << ac.priv.tariffChg << ", "
170           << "chg_admin = " << ac.priv.adminChg << " "
171       << "WHERE login = '" << login << "'";
172
173 result = PQexec(connection, query.str().c_str());
174
175 if (PQresultStatus(result) != PGRES_COMMAND_OK)
176     {
177     strError = PQresultErrorMessage(result);
178     PQclear(result);
179     printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): '%s'\n", strError.c_str());
180     if (RollbackTransaction())
181         {
182         printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Failed to rollback transaction'\n");
183         }
184     return -1;
185     }
186
187 PQclear(result);
188
189 if (CommitTransaction())
190     {
191     printfd(__FILE__, "POSTGRESQL_STORE::SaveAdmin(): 'Failed to commit transaction'\n");
192     return -1;
193     }
194
195 return 0;
196 }
197
198 //-----------------------------------------------------------------------------
199 int POSTGRESQL_STORE::RestoreAdmin(STG::AdminConf * ac, const std::string & login) const
200 {
201 std::lock_guard lock(m_mutex);
202
203 if (PQstatus(connection) != CONNECTION_OK)
204     {
205     printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
206     if (Reset())
207         {
208         strError = "Connection lost";
209         printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): '%s'\n", strError.c_str());
210         return -1;
211         }
212     }
213
214 PGresult * result;
215
216 if (StartTransaction())
217     {
218     printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Failed to start transaction'\n");
219     return -1;
220     }
221
222 char cryptedPass[ADM_PASSWD_LEN + 1];
223 char adminPass[ADM_PASSWD_LEN + 1];
224 BLOWFISH_CTX ctx;
225
226 std::string elogin = login;
227
228 if (EscapeString(elogin))
229     {
230     printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Failed to escape login'\n");
231     if (RollbackTransaction())
232         {
233         printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Failed to rollback transaction'\n");
234         }
235     return -1;
236     }
237
238 std::ostringstream query;
239 query << "SELECT login, passwd, \
240                  chg_conf, chg_password, chg_stat, \
241                  chg_cash, usr_add_del, chg_tariff, \
242                  chg_admin, chg_service, chg_corporation \
243           FROM tb_admins \
244           WHERE login = '" << elogin << "'";
245
246 result = PQexec(connection, query.str().c_str());
247
248 if (PQresultStatus(result) != PGRES_TUPLES_OK)
249     {
250     strError = PQresultErrorMessage(result);
251     printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): '%s'\n", strError.c_str());
252     PQclear(result);
253     if (RollbackTransaction())
254         {
255         printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Failed to rollback transaction'\n");
256         }
257     return -1;
258     }
259
260 int tuples = PQntuples(result);
261
262 if (tuples != 1)
263     {
264     strError = "Failed to fetch admin's data";
265     printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
266     PQclear(result);
267     if (RollbackTransaction())
268         {
269         printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Failed to rollback transaction'\n");
270         }
271     return -1;
272     }
273
274 ac->login = PQgetvalue(result, 0, 0);
275 ac->password = PQgetvalue(result, 0, 1);
276
277 std::stringstream tuple;
278 tuple << PQgetvalue(result, 0, 2) << " "
279       << PQgetvalue(result, 0, 3) << " "
280       << PQgetvalue(result, 0, 4) << " "
281       << PQgetvalue(result, 0, 5) << " "
282       << PQgetvalue(result, 0, 6) << " "
283       << PQgetvalue(result, 0, 7) << " "
284       << PQgetvalue(result, 0, 8) << " "
285       << PQgetvalue(result, 0, 9) << " "
286       << PQgetvalue(result, 0, 10);
287
288 PQclear(result);
289
290 tuple >> ac->priv.userConf
291       >> ac->priv.userPasswd
292       >> ac->priv.userStat
293       >> ac->priv.userCash
294       >> ac->priv.userAddDel
295       >> ac->priv.tariffChg
296       >> ac->priv.adminChg;
297
298 if (CommitTransaction())
299     {
300     printfd(__FILE__, "POSTGRESQL_STORE::RestoreAdmin(): 'Failed to commit transacion'\n");
301     return -1;
302     }
303
304 if (ac->password == "")
305     {
306     return 0;
307     }
308
309 Decode21(cryptedPass, ac->password.c_str());
310 InitContext(adm_enc_passwd, sizeof(adm_enc_passwd), &ctx);
311 for (int i = 0; i < ADM_PASSWD_LEN / 8; i++)
312     {
313     DecryptBlock(adminPass + 8 * i, cryptedPass + 8 * i, &ctx);
314     }
315 ac->password = adminPass;
316
317 return 0;
318 }
319 //-----------------------------------------------------------------------------
320 int POSTGRESQL_STORE::AddAdmin(const std::string & login) const
321 {
322 std::lock_guard lock(m_mutex);
323
324 if (PQstatus(connection) != CONNECTION_OK)
325     {
326     printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
327     if (Reset())
328         {
329         strError = "Connection lost";
330         printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): '%s'\n", strError.c_str());
331         return -1;
332         }
333     }
334
335 PGresult * result;
336
337 if (StartTransaction())
338     {
339     printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): 'Failed to start transaction'\n");
340     return -1;
341     }
342
343 std::string elogin = login;
344
345 if (EscapeString(elogin))
346     {
347     printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): 'Failed to escape login'\n");
348     if (RollbackTransaction())
349         {
350         printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): 'Failed to rollback transaction'\n");
351         }
352     return -1;
353     }
354
355 std::ostringstream query;
356 query << "INSERT INTO tb_admins \
357               (login, passwd, \
358               chg_conf, chg_password, chg_stat, \
359               chg_cash, usr_add_del, chg_tariff, \
360               chg_admin, chg_service, chg_corporation) \
361           VALUES "
362           << "('" << elogin << "', \
363               '', 0, 0, 0, 0, 0, 0, 0, 0, 0)";
364
365 result = PQexec(connection, query.str().c_str());
366
367 if (PQresultStatus(result) != PGRES_COMMAND_OK)
368     {
369     strError = PQresultErrorMessage(result);
370     PQclear(result);
371     printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): '%s'\n", strError.c_str());
372     if (RollbackTransaction())
373         {
374         printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): 'Failed to rollback transaction'\n");
375         }
376     return -1;
377     }
378
379 PQclear(result);
380
381 if (CommitTransaction())
382     {
383     printfd(__FILE__, "POSTGRESQL_STORE::AddAdmin(): 'Failed to commit transaction'\n");
384     return -1;
385     }
386
387 return 0;
388 }
389 //-----------------------------------------------------------------------------
390 int POSTGRESQL_STORE::DelAdmin(const std::string & login) const
391 {
392 std::lock_guard lock(m_mutex);
393
394 if (PQstatus(connection) != CONNECTION_OK)
395     {
396     printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
397     if (Reset())
398         {
399         strError = "Connection lost";
400         printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): '%s'\n", strError.c_str());
401         return -1;
402         }
403     }
404
405 PGresult * result;
406
407 if (StartTransaction())
408     {
409     printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): 'Failed to start transaction'\n");
410     return -1;
411     }
412
413 std::string elogin = login;
414
415 if (EscapeString(elogin))
416     {
417     printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): 'Failed to escape login'\n");
418     if (RollbackTransaction())
419         {
420         printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): 'Failed to rollback transaction'\n");
421         }
422     return -1;
423     }
424
425 std::ostringstream query;
426 query << "DELETE FROM tb_admins WHERE login = '" << elogin << "'";
427
428 result = PQexec(connection, query.str().c_str());
429
430 if (PQresultStatus(result) != PGRES_COMMAND_OK)
431     {
432     strError = PQresultErrorMessage(result);
433     PQclear(result);
434     printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): '%s'\n", strError.c_str());
435     if (RollbackTransaction())
436         {
437         printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): 'Failed to rollback transaction'\n");
438         }
439     return -1;
440     }
441
442 PQclear(result);
443
444 if (CommitTransaction())
445     {
446     printfd(__FILE__, "POSTGRESQL_STORE::DelAdmin(): 'Failed to commit transaction'\n");
447     return -1;
448     }
449
450 return 0;
451 }
452 //-----------------------------------------------------------------------------
453