]> jfr.im git - irc/quakenet/newserv.git/blame - trusts/db.c
Merge.
[irc/quakenet/newserv.git] / 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 12int trustsdbloaded;
2b6e02e2 13
be2823bc 14void createtrusttables(int migration);
4be1aaf2 15void trusts_flush(void);
83bccee3 16void trusts_freeall(void);
2b6e02e2 17
be2823bc
CP
18void createtrusttables(int migration) {
19 char *groups, *hosts;
20
21 if(migration) {
22 groups = "migration_groups";
23 hosts = "migration_hosts";
24 } else {
25 groups = "groups";
26 hosts = "hosts";
27 }
28
29 trustsdb->createtable(trustsdb, NULL, NULL,
4be1aaf2 30 "CREATE TABLE ? (id INT PRIMARY KEY, name VARCHAR(?), trustedfor INT, mode INT, maxperident INT, maxusage INT, expires INT, lastseen INT, lastmaxuserreset INT, createdby VARCHAR(?), contact VARCHAR(?), comment VARCHAR(?))",
be2823bc
CP
31 "Tdddd", groups, TRUSTNAMELEN, NICKLEN, CONTACTLEN, COMMENTLEN
32 );
9bf9e8a1
CP
33
34 /* I'd like multiple keys here but that's not gonna happen on a cross-database platform :( */
35 trustsdb->createtable(trustsdb, NULL, NULL, "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, host VARCHAR(?), maxusage INT, lastseen INT)", "Td", hosts, TRUSTHOSTLEN);
4be1aaf2
CP
36}
37
38static void flushdatabase(void *arg) {
39 trusts_flush();
be2823bc
CP
40}
41
7938a2c3
CP
42static void triggerdbloaded(void *arg) {
43 triggerhook(HOOK_TRUSTS_DB_LOADED, NULL);
44}
45
4be1aaf2 46static void loadcomplete(void) {
bf5b66e5
CP
47 /* error has already been shown */
48 if(loaderror)
49 return;
2b6e02e2 50
b76fd8e6 51 th_linktree();
bf5b66e5 52 trustsdbloaded = 1;
4be1aaf2
CP
53 flushschedule = schedulerecurring(time(NULL) + 300, 0, 300, flushdatabase, NULL);
54
7938a2c3 55 scheduleoneshot(time(NULL), triggerdbloaded, NULL);
be2823bc
CP
56}
57
be2823bc
CP
58static void loadhosts_data(const DBAPIResult *result, void *tag) {
59 if(!result) {
60 loaderror = 1;
61 return;
62 }
63
64 if(!result->success) {
65 Error("trusts", ERR_ERROR, "Error loading hosts table.");
66 loaderror = 1;
67
68 result->clear(result);
69 return;
70 }
71
9bf9e8a1 72 if(result->fields != 5) {
be2823bc
CP
73 Error("trusts", ERR_ERROR, "Wrong number of fields in hosts table.");
74 loaderror = 1;
75
76 result->clear(result);
77 return;
78 }
79
80 while(result->next(result)) {
9bf9e8a1 81 unsigned int groupid, id;
5ada3782 82 char *host;
4be1aaf2 83 unsigned int maxusage, lastseen;
be2823bc
CP
84 trustgroup *tg;
85
9bf9e8a1
CP
86 id = strtoul(result->get(result, 0), NULL, 10);
87 if(id > thmaxid)
88 thmaxid = id;
89
90 groupid = strtoul(result->get(result, 1), NULL, 10);
be2823bc
CP
91
92 tg = tg_getbyid(groupid);
93 if(!tg) {
94 Error("trusts", ERR_WARNING, "Orphaned trust group host: %d", groupid);
95 continue;
96 }
97
9bf9e8a1
CP
98 /* NOTE: 2 is at the bottom */
99 maxusage = strtoul(result->get(result, 3), NULL, 10);
100 lastseen = (time_t)strtoul(result->get(result, 4), NULL, 10);
101 host = result->get(result, 2);
be2823bc 102
9bf9e8a1 103 if(!th_add(tg, id, host, maxusage, lastseen))
5ada3782 104 Error("trusts", ERR_WARNING, "Error adding host to trust %d: %s", groupid, host);
be2823bc
CP
105 }
106
107 result->clear(result);
108
bf5b66e5 109 loadcomplete();
be2823bc
CP
110}
111
112static void loadhosts_fini(const DBAPIResult *result, void *tag) {
9bf9e8a1 113 Error("trusts", ERR_INFO, "Finished loading hosts, maximum id: %d", thmaxid);
be2823bc
CP
114}
115
116static void loadgroups_data(const DBAPIResult *result, void *tag) {
117 if(!result) {
118 loaderror = 1;
119 return;
120 }
121
122 if(!result->success) {
123 Error("trusts", ERR_ERROR, "Error loading group table.");
124 loaderror = 1;
125
126 result->clear(result);
127 return;
128 }
129
130 if(result->fields != 12) {
131 Error("trusts", ERR_ERROR, "Wrong number of fields in groups table.");
132 loaderror = 1;
133
134 result->clear(result);
135 return;
136 }
137
138 while(result->next(result)) {
139 unsigned int id;
5ada3782 140 sstring *name, *createdby, *contact, *comment;
4be1aaf2 141 unsigned int trustedfor, mode, maxperident, maxusage;
5ada3782 142 time_t expires, lastseen, lastmaxuserreset;
be2823bc
CP
143
144 id = strtoul(result->get(result, 0), NULL, 10);
145 if(id > tgmaxid)
146 tgmaxid = id;
147
5ada3782
CP
148 name = getsstring(result->get(result, 1), TRUSTNAMELEN);
149 trustedfor = strtoul(result->get(result, 2), NULL, 10);
150 mode = atoi(result->get(result, 3));
151 maxperident = strtoul(result->get(result, 4), NULL, 10);
4be1aaf2 152 maxusage = strtoul(result->get(result, 5), NULL, 10);
5ada3782
CP
153 expires = (time_t)strtoul(result->get(result, 6), NULL, 10);
154 lastseen = (time_t)strtoul(result->get(result, 7), NULL, 10);
155 lastmaxuserreset = (time_t)strtoul(result->get(result, 8), NULL, 10);
156 createdby = getsstring(result->get(result, 9), NICKLEN);
157 contact = getsstring(result->get(result, 10), CONTACTLEN);
158 comment = getsstring(result->get(result, 11), COMMENTLEN);
159
160 if(name && createdby && contact && comment) {
4be1aaf2 161 if(!tg_add(id, name->content, trustedfor, mode, maxperident, maxusage, expires, lastseen, lastmaxuserreset, createdby->content, contact->content, comment->content))
5ada3782
CP
162 Error("trusts", ERR_WARNING, "Error adding trustgroup %d: %s", id, name->content);
163 } else {
164 Error("trusts", ERR_ERROR, "Error allocating sstring in group loader, id: %d", id);
165 }
be2823bc 166
5ada3782
CP
167 freesstring(name);
168 freesstring(createdby);
169 freesstring(contact);
170 freesstring(comment);
be2823bc
CP
171 }
172
173 result->clear(result);
174}
175
176static void loadgroups_fini(const DBAPIResult *result, void *tag) {
177 Error("trusts", ERR_INFO, "Finished loading groups, maximum id: %d.", tgmaxid);
2b6e02e2
CP
178}
179
bf5b66e5 180int trusts_loaddb(void) {
bf5b66e5 181 if(!trustsdb) {
83bccee3
CP
182 trustsdb = dbapi2open(NULL, "trusts");
183 if(!trustsdb) {
184 Error("trusts", ERR_WARNING, "Unable to connect to db -- not loaded.");
185 return 0;
186 }
bf5b66e5
CP
187 }
188
189 createtrusttables(0);
2b6e02e2 190
be2823bc 191 loaderror = 0;
2b6e02e2 192
be2823bc
CP
193 trustsdb->loadtable(trustsdb, NULL, loadgroups_data, loadgroups_fini, NULL, "groups");
194 trustsdb->loadtable(trustsdb, NULL, loadhosts_data, loadhosts_fini, NULL, "hosts");
bf5b66e5
CP
195
196 return 1;
2b6e02e2
CP
197}
198
83bccee3 199void trusts_closedb(int closeconnection) {
2b6e02e2
CP
200 if(!trustsdb)
201 return;
202
83bccee3
CP
203 if(flushschedule) {
204 deleteschedule(flushschedule, flushdatabase, NULL);
205 flushschedule = NULL;
206
207 flushdatabase(NULL);
208 }
4be1aaf2 209
bf5b66e5 210 trusts_freeall();
83bccee3 211
bf5b66e5 212 trustsdbloaded = 0;
9bf9e8a1 213 thmaxid = tgmaxid = 0;
bf5b66e5 214
83bccee3
CP
215 if(closeconnection) {
216 trustsdb->close(trustsdb);
217 trustsdb = NULL;
218 }
219
220 triggerhook(HOOK_TRUSTS_DB_CLOSED, NULL);
2b6e02e2 221}
4be1aaf2
CP
222
223void th_dbupdatecounts(trusthost *th) {
1b5bf791 224 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuu", "hosts", th->lastseen, th->maxusage, th->id);
4be1aaf2
CP
225}
226
227void tg_dbupdatecounts(trustgroup *tg) {
1b5bf791 228 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuu", "groups", tg->lastseen, tg->maxusage, tg->id);
4be1aaf2 229}
d2c08930
CP
230
231trusthost *th_new(trustgroup *tg, char *host) {
9097ab05
CP
232 trusthost *th, *superset, *subset;
233 u_int32_t ip, mask;
234
235 /* ugh */
236 if(!trusts_str2cidr(host, &ip, &mask))
237 return NULL;
238
239 th_getsuperandsubsets(ip, mask, &superset, &subset);
240
241 th = th_add(tg, thmaxid + 1, host, 0, 0);
d2c08930
CP
242 if(!th)
243 return NULL;
244
245 thmaxid++;
246
247 trustsdb->squery(trustsdb,
248 "INSERT INTO ? (id, groupid, host, maxusage, lastseen) VALUES (?, ?, ?, ?, ?)",
249 "Tuusut", "hosts", th->id, tg->id, trusts_cidr2str(th->ip, th->mask), th->maxusage, th->lastseen
250 );
251
9097ab05 252 th_adjusthosts(th, subset, superset);
d2c08930 253
b76fd8e6 254 th_linktree();
d2c08930
CP
255 return th;
256}
257
258trustgroup *tg_new(char *name, unsigned int trustedfor, int mode, unsigned int maxperident, time_t expires, char *createdby, char *contact, char *comment) {
259 trustgroup *tg = tg_add(tgmaxid + 1, name, trustedfor, mode, maxperident, 0, expires, 0, 0, createdby, contact, comment);
260 if(!tg)
261 return NULL;
262
263 tgmaxid++;
264
265 trustsdb->squery(trustsdb,
266 "INSERT INTO ? (id, name, trustedfor, mode, maxperident, maxusage, expires, lastseen, lastmaxuserreset, createdby, contact, comment) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
267 "Tusuuuutttsss", "groups", tg->id, tg->name->content, tg->trustedfor, tg->mode, tg->maxperident, tg->maxusage, tg->expires, tg->lastseen, tg->lastmaxuserreset, tg->createdby->content, tg->contact->content, tg->comment->content
268 );
269
270 return tg;
271}