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