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