]> jfr.im git - irc/quakenet/newserv.git/blob - trusts/trusts_commands.c
Add trustadd and trustgroupadd.
[irc/quakenet/newserv.git] / trusts / trusts_commands.c
1 #include <stdio.h>
2 #include "../control/control.h"
3 #include "../lib/irc_string.h"
4 #include "trusts.h"
5
6 int trusts_migration_start(TrustDBMigrationCallback, void *);
7 void trusts_migration_stop(void);
8 static void registercommands(int, void *);
9 static void deregistercommands(int, void *);
10
11 static void migrate_status(int errcode, void *tag) {
12 long sender = (long)tag;
13 nick *np = getnickbynumeric(sender);
14
15 if(!np)
16 return;
17
18 if(!errcode || errcode == MIGRATION_LASTERROR) {
19 if(!errcode) {
20 controlreply(np, "Migration complete.");
21 controlreply(np, "Attempting to reload database. . .");
22 } else {
23 controlreply(np, "An error occured after the database was unloaded, attempting reload. . .");
24 }
25 if(trusts_loaddb()) {
26 controlreply(np, "Database reloaded successfully.");
27 } else {
28 controlreply(np, "An error occured, please reload the module manually.");
29 }
30 } else {
31 controlreply(np, "Error %d occured during migration, commands reregistered.", errcode);
32 registercommands(0, NULL);
33 }
34 }
35
36 static int trusts_cmdmigrate(void *source, int cargc, char **cargv) {
37 nick *sender = source;
38 int ret;
39
40 /* iffy but temporary */
41 ret = trusts_migration_start(migrate_status, (void *)(sender->numeric));
42 if(!ret) {
43 controlreply(sender, "Migration started, commands deregistered.");
44 deregistercommands(0, NULL);
45 } else {
46 controlreply(sender, "Error %d starting migration.", ret);
47 }
48
49 return CMD_OK;
50 }
51
52 static int trusts_cmdtrustlist(void *source, int cargc, char **cargv) {
53 nick *sender = source;
54 trustgroup *tg;
55 trusthost *th;
56 time_t t;
57
58 if(cargc < 1)
59 return CMD_USAGE;
60
61 tg = tg_strtotg(cargv[0]);
62 if(!tg) {
63 controlreply(sender, "Couldn't find a trustgroup with that id.");
64 return CMD_ERROR;
65 }
66
67 t = time(NULL);
68
69 controlreply(sender, "Name: : %s", tg->name->content);
70 controlreply(sender, "Trusted for : %d", tg->trustedfor);
71 controlreply(sender, "Currently using : %d", tg->count);
72 controlreply(sender, "Clients per user : %d (%senforcing ident)", tg->maxperident, tg->mode?"":"not ");
73 controlreply(sender, "Contact: : %s", tg->contact->content);
74 controlreply(sender, "Expires in : %s", (tg->expires>t)?longtoduration(tg->expires - t, 2):"(in the past)");
75 controlreply(sender, "Last changed by : %s", tg->createdby->content);
76 controlreply(sender, "Comment: : %s", tg->comment->content);
77 controlreply(sender, "ID: : %u", tg->id);
78 controlreply(sender, "Last used : %s", (tg->count>0)?"(now)":trusts_timetostr(tg->lastseen));
79 controlreply(sender, "Max usage : %d", tg->maxusage);
80 controlreply(sender, "Last max reset : %s", tg->lastmaxuserreset?trusts_timetostr(tg->lastmaxuserreset):"(never)");
81
82 controlreply(sender, "Host Current Max Last seen");
83
84 for(th=tg->hosts;th;th=th->next)
85 controlreply(sender, " %-20s %-10d %-10d %s", trusts_cidr2str(th->ip, th->mask), th->count, th->maxusage, (th->count>0)?"(now)":trusts_timetostr(th->lastseen));
86
87 controlreply(sender, "End of list.");
88
89 return CMD_OK;
90 }
91
92 static int trusts_cmdtrustadd(void *source, int cargc, char **cargv) {
93 trustgroup *tg;
94 nick *sender = source;
95 char *host;
96 uint32_t ip, mask;
97 trusthost *th;
98
99 if(cargc < 2)
100 return CMD_USAGE;
101
102 tg = tg_strtotg(cargv[0]);
103 if(!tg) {
104 controlreply(sender, "Couldn't look up trustgroup.");
105 return CMD_ERROR;
106 }
107
108 host = cargv[1];
109 if(!trusts_str2cidr(host, &ip, &mask)) {
110 controlreply(sender, "Invalid host.");
111 return CMD_ERROR;
112 }
113
114 th = th_getbyhost(ip);
115 if(th) {
116 if(mask == th->mask) {
117 controlreply(sender, "This host already exists with the same mask.");
118 return CMD_ERROR;
119 }
120 if(mask > th->mask) {
121 /* this mask is a closer fit */
122
123 controlreply(sender, "Warning: this host will override another (%s), as it has smaller prefix (group: %s).", trusts_cidr2str(th->ip, th->mask), th->group->name->content);
124 controlreply(sender, "Adding anyway...");
125 }
126 } else {
127 th = th_getsupersetbyhost(ip, mask);
128 if(th) {
129 controlreply(sender, "Warning: this host is already covered by a smaller prefix (%s), which will remain part of that group: %s", trusts_cidr2str(th->ip, th->mask), th->group->name->content);
130 controlreply(sender, "Adding anyway...");
131 }
132 }
133
134 th = th_new(tg, host);
135 if(!th) {
136 controlreply(sender, "An error occured adding the host to the group.");
137 return CMD_ERROR;
138 }
139
140 controlreply(sender, "Host added.");
141 /* TODO: controlwall */
142
143 return CMD_OK;
144 }
145
146 static int trusts_cmdtrustgroupadd(void *source, int cargc, char **cargv) {
147 nick *sender = source;
148 char *name, *contact, *comment, createdby[ACCOUNTLEN + 2];
149 unsigned int howmany, maxperident, enforceident;
150 time_t howlong;
151 trustgroup *tg;
152
153 if(cargc < 6)
154 return CMD_USAGE;
155
156 name = cargv[0];
157 howmany = strtoul(cargv[1], NULL, 10);
158 if(!howmany || (howmany > 50000)) {
159 controlreply(sender, "Bad value maximum number of clients.");
160 return CMD_ERROR;
161 }
162
163 howlong = durationtolong(cargv[2]);
164 if((howlong <= 0) || (howlong > 365 * 86400 * 20)) {
165 controlreply(sender, "Invalid duration supplied.");
166 return CMD_ERROR;
167 }
168
169 maxperident = strtoul(cargv[3], NULL, 10);
170 if(!howmany || (maxperident > 1000)) {
171 controlreply(sender, "Bad value for max per ident.");
172 return CMD_ERROR;
173 }
174
175 if(cargv[4][0] != '1' && cargv[4][0] != '0') {
176 controlreply(sender, "Bad value for enforce ident (use 0 or 1).");
177 return CMD_ERROR;
178 }
179 enforceident = cargv[4][0] == '1';
180
181 contact = cargv[5];
182
183 if(cargc < 7) {
184 comment = "(no comment)";
185 } else {
186 comment = cargv[6];
187 }
188
189 /* don't allow #id or id forms */
190 if((name[0] == '#') || strtoul(name, NULL, 10)) {
191 controlreply(sender, "Invalid trustgroup name.");
192 return CMD_ERROR;
193 }
194
195 tg = tg_strtotg(name);
196 if(tg) {
197 controlreply(sender, "A group with that name already exists");
198 return CMD_ERROR;
199 }
200
201 snprintf(createdby, sizeof(createdby), "#%s", sender->authname);
202
203 tg = tg_new(name, howmany, enforceident, maxperident, howlong + time(NULL), createdby, contact, comment);
204 if(!tg) {
205 controlreply(sender, "An error occured adding the trustgroup.");
206 return CMD_ERROR;
207 }
208
209 controlreply(sender, "Group added.");
210 /* TODO: controlwall */
211
212 return CMD_OK;
213 }
214
215 static int commandsregistered;
216
217 static void registercommands(int hooknum, void *arg) {
218 if(commandsregistered)
219 return;
220 commandsregistered = 1;
221
222 registercontrolhelpcmd("trustmigrate", NO_DEVELOPER, 0, trusts_cmdmigrate, "Usage: trustmigrate\nCopies trust data from O and reloads the database.");
223 registercontrolhelpcmd("trustlist", NO_OPER, 1, trusts_cmdtrustlist, "Usage: trustlist <#id|name|id>\nShows trust data for the specified trust group.");
224 registercontrolhelpcmd("trustgroupadd", NO_OPER, 6, trusts_cmdtrustgroupadd, "Usage: trustgroupadd <name> <howmany> <howlong> <maxperident> <enforceident> <contact> ?comment?");
225 registercontrolhelpcmd("trustadd", NO_OPER, 2, trusts_cmdtrustadd, "Usage: trustadd <#id|name|id> <host>");
226 }
227
228 static void deregistercommands(int hooknum, void *arg) {
229 if(!commandsregistered)
230 return;
231 commandsregistered = 0;
232
233 deregistercontrolcmd("trustmigrate", trusts_cmdmigrate);
234 deregistercontrolcmd("trustlist", trusts_cmdtrustlist);
235 deregistercontrolcmd("trustgroupadd", trusts_cmdtrustgroupadd);
236 deregistercontrolcmd("trustadd", trusts_cmdtrustadd);
237 }
238
239 void _init(void) {
240 registerhook(HOOK_TRUSTS_DB_LOADED, registercommands);
241 registerhook(HOOK_TRUSTS_DB_CLOSED, deregistercommands);
242
243 if(trustsdbloaded)
244 registercommands(0, NULL);
245 }
246
247 void _fini(void) {
248 deregisterhook(HOOK_TRUSTS_DB_LOADED, registercommands);
249 deregisterhook(HOOK_TRUSTS_DB_CLOSED, deregistercommands);
250
251 trusts_migration_stop();
252
253 deregistercommands(0, NULL);
254 }