]> jfr.im git - irc/quakenet/newserv.git/blame - trusts/trusts_db.c
Fix argument count for trustgroupadd.
[irc/quakenet/newserv.git] / trusts / trusts_db.c
CommitLineData
2b6e02e2
CP
1#include "../dbapi2/dbapi2.h"
2#include "../core/error.h"
be2823bc 3#include "../core/hooks.h"
4be1aaf2 4#include "../core/schedule.h"
2b6e02e2
CP
5#include "trusts.h"
6
7DBAPIConn *trustsdb;
9bf9e8a1 8static int tgmaxid, thmaxid;
be2823bc 9static int loaderror;
4be1aaf2
CP
10static void *flushschedule;
11
be2823bc 12void createtrusttables(int migration);
b9c52ee0 13void trusts_flush(void (*)(trusthost *), void (*)(trustgroup *));
83bccee3 14void trusts_freeall(void);
b9c52ee0
CP
15static void th_dbupdatecounts(trusthost *th);
16static void tg_dbupdatecounts(trustgroup *tg);
2b6e02e2 17
35449aa5 18void createtrusttables(int mode) {
be2823bc
CP
19 char *groups, *hosts;
20
35449aa5 21 if(mode == TABLES_MIGRATION) {
be2823bc
CP
22 groups = "migration_groups";
23 hosts = "migration_hosts";
35449aa5
CP
24 } else if(mode == TABLES_REPLICATION) {
25 groups = "replication_groups";
26 hosts = "replication_hosts";
be2823bc
CP
27 } else {
28 groups = "groups";
29 hosts = "hosts";
30 }
31
32 trustsdb->createtable(trustsdb, NULL, NULL,
1f685425
CP
33 "CREATE TABLE ? (id INT PRIMARY KEY, name VARCHAR(?), trustedfor INT, mode INT, maxperident INT, maxusage INT, expires INT, lastseen INT, lastmaxusereset INT, createdby VARCHAR(?), contact VARCHAR(?), comment VARCHAR(?))",
34 "Tdddd", groups, TRUSTNAMELEN, CREATEDBYLEN, CONTACTLEN, COMMENTLEN
be2823bc 35 );
9bf9e8a1
CP
36
37 /* I'd like multiple keys here but that's not gonna happen on a cross-database platform :( */
38 trustsdb->createtable(trustsdb, NULL, NULL, "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, host VARCHAR(?), maxusage INT, lastseen INT)", "Td", hosts, TRUSTHOSTLEN);
4be1aaf2
CP
39}
40
41static void flushdatabase(void *arg) {
b9c52ee0 42 trusts_flush(th_dbupdatecounts, tg_dbupdatecounts);
be2823bc
CP
43}
44
7938a2c3
CP
45static void triggerdbloaded(void *arg) {
46 triggerhook(HOOK_TRUSTS_DB_LOADED, NULL);
47}
48
4be1aaf2 49static void loadcomplete(void) {
bf5b66e5
CP
50 /* error has already been shown */
51 if(loaderror)
52 return;
2b6e02e2 53
b76fd8e6 54 th_linktree();
bf5b66e5 55 trustsdbloaded = 1;
4be1aaf2
CP
56 flushschedule = schedulerecurring(time(NULL) + 300, 0, 300, flushdatabase, NULL);
57
7938a2c3 58 scheduleoneshot(time(NULL), triggerdbloaded, NULL);
be2823bc
CP
59}
60
be2823bc
CP
61static void loadhosts_data(const DBAPIResult *result, void *tag) {
62 if(!result) {
63 loaderror = 1;
64 return;
65 }
66
67 if(!result->success) {
68 Error("trusts", ERR_ERROR, "Error loading hosts table.");
69 loaderror = 1;
70
71 result->clear(result);
72 return;
73 }
74
9bf9e8a1 75 if(result->fields != 5) {
be2823bc
CP
76 Error("trusts", ERR_ERROR, "Wrong number of fields in hosts table.");
77 loaderror = 1;
78
79 result->clear(result);
80 return;
81 }
82
83 while(result->next(result)) {
82a316e7
CP
84 unsigned int groupid;
85 trusthost th;
5ada3782 86 char *host;
be2823bc 87
82a316e7
CP
88 th.id = strtoul(result->get(result, 0), NULL, 10);
89 if(th.id > thmaxid)
90 thmaxid = th.id;
9bf9e8a1
CP
91
92 groupid = strtoul(result->get(result, 1), NULL, 10);
be2823bc 93
82a316e7
CP
94 th.group = tg_getbyid(groupid);
95 if(!th.group) {
be2823bc
CP
96 Error("trusts", ERR_WARNING, "Orphaned trust group host: %d", groupid);
97 continue;
98 }
99
9bf9e8a1 100 host = result->get(result, 2);
82a316e7
CP
101 if(!trusts_str2cidr(host, &th.ip, &th.mask)) {
102 Error("trusts", ERR_WARNING, "Error parsing cidr for host: %s", host);
103 continue;
104 }
105
106 th.maxusage = strtoul(result->get(result, 3), NULL, 10);
107 th.lastseen = (time_t)strtoul(result->get(result, 4), NULL, 10);
be2823bc 108
82a316e7 109 if(!th_add(&th))
5ada3782 110 Error("trusts", ERR_WARNING, "Error adding host to trust %d: %s", groupid, host);
be2823bc
CP
111 }
112
113 result->clear(result);
114
bf5b66e5 115 loadcomplete();
be2823bc
CP
116}
117
118static void loadhosts_fini(const DBAPIResult *result, void *tag) {
9bf9e8a1 119 Error("trusts", ERR_INFO, "Finished loading hosts, maximum id: %d", thmaxid);
be2823bc
CP
120}
121
122static void loadgroups_data(const DBAPIResult *result, void *tag) {
123 if(!result) {
124 loaderror = 1;
125 return;
126 }
127
128 if(!result->success) {
129 Error("trusts", ERR_ERROR, "Error loading group table.");
130 loaderror = 1;
131
132 result->clear(result);
133 return;
134 }
135
136 if(result->fields != 12) {
137 Error("trusts", ERR_ERROR, "Wrong number of fields in groups table.");
138 loaderror = 1;
139
140 result->clear(result);
141 return;
142 }
143
144 while(result->next(result)) {
82a316e7
CP
145 trustgroup tg;
146
147 tg.id = strtoul(result->get(result, 0), NULL, 10);
148 if(tg.id > tgmaxid)
149 tgmaxid = tg.id;
150
151 tg.name = getsstring(rtrim(result->get(result, 1)), TRUSTNAMELEN);
152 tg.trustedfor = strtoul(result->get(result, 2), NULL, 10);
153 tg.mode = atoi(result->get(result, 3));
154 tg.maxperident = strtoul(result->get(result, 4), NULL, 10);
155 tg.maxusage = strtoul(result->get(result, 5), NULL, 10);
156 tg.expires = (time_t)strtoul(result->get(result, 6), NULL, 10);
157 tg.lastseen = (time_t)strtoul(result->get(result, 7), NULL, 10);
1f685425
CP
158 tg.lastmaxusereset = (time_t)strtoul(result->get(result, 8), NULL, 10);
159 tg.createdby = getsstring(rtrim(result->get(result, 9)), CREATEDBYLEN);
82a316e7
CP
160 tg.contact = getsstring(rtrim(result->get(result, 10)), CONTACTLEN);
161 tg.comment = getsstring(rtrim(result->get(result, 11)), COMMENTLEN);
162
163 if(tg.name && tg.createdby && tg.contact && tg.comment) {
164 if(!tg_add(&tg))
165 Error("trusts", ERR_WARNING, "Error adding trustgroup %d: %s", tg.id, tg.name->content);
5ada3782 166 } else {
82a316e7 167 Error("trusts", ERR_ERROR, "Error allocating sstring in group loader, id: %d", tg.id);
5ada3782 168 }
be2823bc 169
82a316e7
CP
170 freesstring(tg.name);
171 freesstring(tg.createdby);
172 freesstring(tg.contact);
173 freesstring(tg.comment);
be2823bc
CP
174 }
175
176 result->clear(result);
177}
178
179static void loadgroups_fini(const DBAPIResult *result, void *tag) {
180 Error("trusts", ERR_INFO, "Finished loading groups, maximum id: %d.", tgmaxid);
2b6e02e2
CP
181}
182
82a316e7 183static int trusts_connectdb(void) {
bf5b66e5 184 if(!trustsdb) {
83bccee3
CP
185 trustsdb = dbapi2open(NULL, "trusts");
186 if(!trustsdb) {
187 Error("trusts", ERR_WARNING, "Unable to connect to db -- not loaded.");
188 return 0;
189 }
bf5b66e5
CP
190 }
191
35449aa5 192 createtrusttables(TABLES_REGULAR);
2b6e02e2 193
82a316e7
CP
194 return 1;
195}
196
197int trusts_loaddb(void) {
198 if(!trusts_connectdb())
199 return 0;
200
be2823bc 201 loaderror = 0;
2b6e02e2 202
be2823bc
CP
203 trustsdb->loadtable(trustsdb, NULL, loadgroups_data, loadgroups_fini, NULL, "groups");
204 trustsdb->loadtable(trustsdb, NULL, loadhosts_data, loadhosts_fini, NULL, "hosts");
bf5b66e5
CP
205
206 return 1;
2b6e02e2
CP
207}
208
83bccee3 209void trusts_closedb(int closeconnection) {
2b6e02e2
CP
210 if(!trustsdb)
211 return;
212
83bccee3
CP
213 if(flushschedule) {
214 deleteschedule(flushschedule, flushdatabase, NULL);
215 flushschedule = NULL;
216
217 flushdatabase(NULL);
218 }
4be1aaf2 219
bf5b66e5 220 trusts_freeall();
83bccee3 221
bf5b66e5 222 trustsdbloaded = 0;
9bf9e8a1 223 thmaxid = tgmaxid = 0;
bf5b66e5 224
83bccee3
CP
225 if(closeconnection) {
226 trustsdb->close(trustsdb);
227 trustsdb = NULL;
228 }
229
230 triggerhook(HOOK_TRUSTS_DB_CLOSED, NULL);
2b6e02e2 231}
4be1aaf2 232
b9c52ee0 233static void th_dbupdatecounts(trusthost *th) {
1b5bf791 234 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuu", "hosts", th->lastseen, th->maxusage, th->id);
4be1aaf2
CP
235}
236
b9c52ee0 237static void tg_dbupdatecounts(trustgroup *tg) {
1b5bf791 238 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuu", "groups", tg->lastseen, tg->maxusage, tg->id);
4be1aaf2 239}
d2c08930 240
82a316e7 241trusthost *th_copy(trusthost *ith) {
9097ab05 242 trusthost *th, *superset, *subset;
9097ab05 243
82a316e7
CP
244 th = th_add(ith);
245 if(!th)
9097ab05
CP
246 return NULL;
247
82a316e7 248 trustsdb_insertth("hosts", th, th->group->id);
9097ab05 249
82a316e7
CP
250 th_getsuperandsubsets(ith->ip, ith->mask, &superset, &subset);
251 th_adjusthosts(th, subset, superset);
252 th_linktree();
253
254 return th;
255}
256
257trusthost *th_new(trustgroup *tg, char *host) {
258 trusthost *th, nth;
259
260 if(!trusts_str2cidr(host, &nth.ip, &nth.mask))
261 return NULL;
262
263 nth.group = tg;
264 nth.id = thmaxid + 1;
265 nth.lastseen = 0;
266 nth.maxusage = 0;
267
268 th = th_copy(&nth);
d2c08930
CP
269 if(!th)
270 return NULL;
271
272 thmaxid++;
273
82a316e7
CP
274 return th;
275}
d2c08930 276
82a316e7
CP
277trustgroup *tg_copy(trustgroup *itg) {
278 trustgroup *tg = tg_add(itg);
279 if(!tg)
280 return NULL;
d2c08930 281
82a316e7
CP
282 trustsdb_inserttg("groups", tg);
283 return tg;
d2c08930
CP
284}
285
82a316e7
CP
286trustgroup *tg_new(trustgroup *itg) {
287 trustgroup *tg;
288
289 itg->id = tgmaxid + 1;
290 itg->maxusage = 0;
291 itg->lastseen = 0;
1f685425 292 itg->lastmaxusereset = 0;
82a316e7
CP
293
294 tg = tg_copy(itg);
d2c08930
CP
295 if(!tg)
296 return NULL;
297
298 tgmaxid++;
299
82a316e7
CP
300 return tg;
301}
302
303void trustsdb_insertth(char *table, trusthost *th, unsigned int groupid) {
d2c08930 304 trustsdb->squery(trustsdb,
82a316e7
CP
305 "INSERT INTO ? (id, groupid, host, maxusage, lastseen) VALUES (?, ?, ?, ?, ?)",
306 "Tuusut", table, th->id, groupid, trusts_cidr2str(th->ip, th->mask), th->maxusage, th->lastseen
d2c08930 307 );
82a316e7 308}
d2c08930 309
82a316e7
CP
310void trustsdb_inserttg(char *table, trustgroup *tg) {
311 trustsdb->squery(trustsdb,
1f685425
CP
312 "INSERT INTO ? (id, name, trustedfor, mode, maxperident, maxusage, expires, lastseen, lastmaxusereset, createdby, contact, comment) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
313 "Tusuuuutttsss", table, tg->id, tg->name->content, tg->trustedfor, tg->mode, tg->maxperident, tg->maxusage, tg->expires, tg->lastseen, tg->lastmaxusereset, tg->createdby->content, tg->contact->content, tg->comment->content
82a316e7 314 );
d2c08930 315}
b9c52ee0 316
2ab0a1e7
CP
317void tg_update(trustgroup *tg) {
318 trustsdb->squery(trustsdb,
1f685425
CP
319 "UPDATE ? SET name = ?, trustedfor = ?, maxperident = ?, maxusage = ?, expires = ?, lastseen = ?, lastmaxusereset = ?, createdby = ?, contact = ?, comment = ? WHERE id = ?",
320 "Tsuuuutttsssu", "groups", tg->name->content, tg->trustedfor, tg->mode, tg->maxperident, tg->maxusage, tg->expires, tg->lastseen, tg->lastmaxusereset, tg->createdby->content, tg->contact->content, tg->comment->content, tg->id
2ab0a1e7
CP
321 );
322}
323
06deaa30
GB
324void trustsdb_deletetg(char *table, trustgroup *tg) {
325 trustsdb->squery(trustsdb,
326 "DELETE FROM ? WHERE id = ?",
327 "Tu", "groups", tg->id);
328}
329
2ab0a1e7 330void tg_delete(trustgroup *tg) {
06deaa30
GB
331 trustgroup **pnext;
332
333 for(pnext=&tglist;*pnext;pnext=&((*pnext)->next)) {
334 if(*pnext == tg) {
335 *pnext = tg->next;
336 break;
337 }
338 }
339
340 trustsdb_deletetg("groups", tg);
341 tg_free(tg, 1);
342}
343
344void trustsdb_deleteth(char *table, trusthost *th) {
345 trustsdb->squery(trustsdb,
346 "DELETE FROM ? WHERE id = ?",
347 "Tu", "hosts", th->id);
2ab0a1e7
CP
348}
349
350void th_delete(trusthost *th) {
06deaa30
GB
351 trusthost **pnext;
352 nick *np;
353
354 for(pnext=&(th->group->hosts);*pnext;pnext=&((*pnext)->next)) {
355 if(*pnext == th) {
356 *pnext = th->next;
357 break;
358 }
359 }
360
361 for(np=th->users;np;np=nextbytrust(np))
362 settrusthost(np, NULL);
363
364 th->group->count -= th->count;
365
366 trustsdb_deleteth("hosts", th);
367 th_free(th);
368
369 th_linktree();
2ab0a1e7
CP
370}
371
b9c52ee0 372void _init(void) {
82a316e7 373 trusts_connectdb();
b9c52ee0
CP
374}
375
376void _fini(void) {
377 trusts_closedb(1);
378}