]>
Commit | Line | Data |
---|---|---|
1 | /* usercmds.c */ | |
2 | ||
3 | #include "chanserv.h" | |
4 | #include "../lib/irc_string.h" | |
5 | ||
6 | #include <stdio.h> | |
7 | #include <string.h> | |
8 | ||
9 | int csu_douserflags(void *source, int cargc, char **cargv); | |
10 | int csu_doinfo(void *source, int cargc, char **cargv); | |
11 | int csu_dowhois(void *source, int cargc, char **cargv); | |
12 | int csu_dousercomment(void *source, int cargc, char **cargv); | |
13 | int csu_dodeluser(void *source, int cargc, char **cargv); | |
14 | int csu_dolanguage(void *source, int cargc, char **cargv); | |
15 | int csu_dosuspenduser(void *source, int cargc, char **cargv); | |
16 | int csu_dounsuspenduser(void *source, int cargc, char **cargv); | |
17 | int csu_dospewdb(void *source, int cargc, char **cargv); | |
18 | int csu_dospewpass(void *source, int cargc, char **cargv); | |
19 | int csu_dospewemail(void *source, int cargc, char **cargv); | |
20 | int csu_dolistflags(void *source, int cargc, char **cargv); | |
21 | int csu_dosuspenduserlist(void *source, int cargc, char **cargv); | |
22 | ||
23 | void _init() { | |
24 | chanservaddcommand("userflags" , QCMD_AUTHED, 2, csu_douserflags ,"Shows or changes user flags."); | |
25 | chanservaddcommand("info" , QCMD_AUTHED, 2, csu_doinfo ,"Shows or changes info line."); | |
26 | chanservaddcommand("whois" , QCMD_AUTHED, 1, csu_dowhois ,"Displays information about a user."); | |
27 | chanservaddcommand("usercomment" , QCMD_OPER , 2, csu_dousercomment ,"Shows or changes staff comment for a user."); | |
28 | chanservaddcommand("deluser" , QCMD_OPER , 2, csu_dodeluser ,"Removes a user from the bot."); | |
29 | chanservaddcommand("language" , QCMD_AUTHED, 1, csu_dolanguage ,"Shows or changes your current language."); | |
30 | chanservaddcommand("suspenduser" , QCMD_OPER , 1, csu_dosuspenduser ,"Suspend/Delay GLINE/Instantly GLINE a user."); | |
31 | chanservaddcommand("unsuspenduser" , QCMD_OPER , 1, csu_dounsuspenduser ,"Unsuspend a user."); | |
32 | chanservaddcommand("spewdb" , QCMD_OPER , 1, csu_dospewdb ,"Search for a user in the database."); | |
33 | chanservaddcommand("spewpass" , QCMD_OPER , 1, csu_dospewpass ,"Search for a password in the database."); | |
34 | chanservaddcommand("spewemail" , QCMD_OPER , 1, csu_dospewemail ,"Search for an e-mail in the database."); | |
35 | chanservaddcommand("listflags" , QCMD_OPER , 1, csu_dolistflags ,"List users with the specified user flags."); | |
36 | chanservaddcommand("suspenduserlist", QCMD_HELPER, 1, csu_dosuspenduserlist,"Lists suspended/locked users."); | |
37 | } | |
38 | ||
39 | void _fini() { | |
40 | chanservremovecommand("userflags", csu_douserflags); | |
41 | chanservremovecommand("info", csu_doinfo); | |
42 | chanservremovecommand("whois", csu_dowhois); | |
43 | chanservremovecommand("usercomment", csu_dousercomment); | |
44 | chanservremovecommand("deluser", csu_dodeluser); | |
45 | chanservremovecommand("language", csu_dolanguage); | |
46 | chanservremovecommand("suspenduser", csu_dosuspenduser); | |
47 | chanservremovecommand("unsuspenduser", csu_dounsuspenduser); | |
48 | chanservremovecommand("spewdb", csu_dospewdb); | |
49 | chanservremovecommand("spewpass", csu_dospewpass); | |
50 | chanservremovecommand("spewemail", csu_dospewemail); | |
51 | chanservremovecommand("listflags", csu_dolistflags); | |
52 | chanservremovecommand("suspenduserlist", csu_dosuspenduserlist); | |
53 | } | |
54 | ||
55 | int csu_douserflags(void *source, int cargc, char **cargv) { | |
56 | nick *sender=source; | |
57 | reguser *rup=getreguserfromnick(sender), *target; | |
58 | int arg=0; | |
59 | flag_t flagmask, changemask; | |
60 | char flagbuf[30]; | |
61 | ||
62 | if (!rup) | |
63 | return CMD_ERROR; | |
64 | ||
65 | if (cargc<1) { | |
66 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "userflags"); | |
67 | return CMD_ERROR; | |
68 | } | |
69 | ||
70 | if (*cargv[0]!='+' && *cargv[0]!='-') { | |
71 | arg++; | |
72 | /* If the first char isn't a "change" character, it must specify a target */ | |
73 | ||
74 | if (!(target=findreguser(sender,cargv[0]))) | |
75 | return CMD_ERROR; | |
76 | ||
77 | if (target!=rup && !cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) { | |
78 | chanservstdmessage(sender, QM_NOACCESS, "userflags"); | |
79 | return CMD_ERROR; | |
80 | } | |
81 | } else { | |
82 | target=rup; | |
83 | } | |
84 | ||
85 | if (cargc>arg) { | |
86 | /* OK, now we have a changestring.. */ | |
87 | if (target!=rup && !cs_privcheck(QPRIV_CHANGEUSERFLAGS, sender)) { | |
88 | chanservstdmessage(sender, QM_NOACCESS, "userflags"); | |
89 | return CMD_ERROR; | |
90 | } | |
91 | ||
92 | strcpy(flagbuf,printflags(target->flags, ruflags)); | |
93 | ||
94 | changemask=QUFLAG_NOTICE | QUFLAG_INFO; | |
95 | ||
96 | if (target==rup) { | |
97 | /* If you're changing yourself, you can give up the "status" flags and add/remove notice */ | |
98 | changemask|=(target->flags & (QUFLAG_OPER | QUFLAG_DEV | QUFLAG_PROTECT | QUFLAG_HELPER | QUFLAG_ADMIN)); | |
99 | } | |
100 | ||
101 | /* Warning, policy ahead */ | |
102 | ||
103 | if (UHasOperPriv(rup)) | |
104 | changemask |= QUFLAG_GLINE | QUFLAG_DELAYEDGLINE | QUFLAG_RESTRICTED | QUFLAG_PROTECT; | |
105 | ||
106 | if (UHasAdminPriv(rup)) | |
107 | changemask |= (QUFLAG_OPER | QUFLAG_HELPER); | |
108 | ||
109 | if (UIsDev(rup)) | |
110 | changemask=QUFLAG_ALL; | |
111 | ||
112 | setflags(&target->flags, changemask, cargv[arg], ruflags, REJECT_NONE); | |
113 | ||
114 | /* More policy */ | |
115 | if (!UHasHelperPriv(target)) { | |
116 | target->flags &= ~QUFLAG_PROTECT; | |
117 | } | |
118 | ||
119 | cs_log(sender,"USERFLAGS #%s %s (%s -> %s)",target->username,cargv[arg],flagbuf,printflags(target->flags, ruflags)); | |
120 | csdb_updateuser(target); | |
121 | chanservstdmessage(sender, QM_DONE); | |
122 | } | |
123 | ||
124 | if (cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) | |
125 | flagmask=QUFLAG_ALL; | |
126 | else | |
127 | flagmask=QUFLAG_INFO | QUFLAG_NOTICE | QUFLAG_OPER | QUFLAG_HELPER | QUFLAG_DEV | QUFLAG_ADMIN; | |
128 | ||
129 | chanservstdmessage(sender, QM_CURUSERFLAGS, target->username, printflags(target->flags & flagmask, ruflags)); | |
130 | ||
131 | return CMD_OK; | |
132 | } | |
133 | ||
134 | int csu_doinfo(void *source, int cargc, char **cargv) { | |
135 | nick *sender=source; | |
136 | reguser *rup=getreguserfromnick(sender); | |
137 | chanindex *cip; | |
138 | regchan *rcp; | |
139 | regchanuser *rcup; | |
140 | char linebuf[INFOLEN+10]; | |
141 | char *newline=""; | |
142 | int doupdate=0; | |
143 | ||
144 | if (cargc==0 || *cargv[0]!='#') { | |
145 | /* Global info line */ | |
146 | if (cargc==1) { | |
147 | /* Setting to either one word or "none" */ | |
148 | if (!ircd_strcmp(cargv[0],"none")) { | |
149 | newline=""; | |
150 | doupdate=1; | |
151 | } else { | |
152 | newline=cargv[0]; | |
153 | doupdate=1; | |
154 | } | |
155 | } else if (cargc>1) { | |
156 | /* More than one word: we need to stick them back together */ | |
157 | snprintf(linebuf,INFOLEN,"%s %s",cargv[0],cargv[1]); | |
158 | newline=linebuf; | |
159 | doupdate=1; | |
160 | } | |
161 | ||
162 | if (doupdate) { | |
163 | if (rup->info) | |
164 | freesstring(rup->info); | |
165 | ||
166 | rup->info=getsstring(newline, INFOLEN); | |
167 | ||
168 | chanservstdmessage(sender, QM_DONE); | |
169 | csdb_updateuser(rup); | |
170 | } | |
171 | ||
172 | chanservstdmessage(sender, QM_GLOBALINFO, rup->info?rup->info->content:"(none)"); | |
173 | } else { | |
174 | /* Channel info line */ | |
175 | ||
176 | if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext]) || | |
177 | (CIsSuspended(rcp) && !cs_privcheck(QPRIV_SUSPENDBYPASS, sender))) { | |
178 | chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]); | |
179 | return CMD_ERROR; | |
180 | } | |
181 | ||
182 | if ((!(rcup=findreguseronchannel(rcp, rup)) || !CUHasVoicePriv(rcup))) { | |
183 | chanservstdmessage(sender, QM_NOACCESSONCHAN, cargv[0], "info"); | |
184 | return CMD_ERROR; | |
185 | } | |
186 | ||
187 | if (cargc>1) { | |
188 | if (rcup->info) | |
189 | freesstring(rcup->info); | |
190 | ||
191 | if (!ircd_strcmp(cargv[1],"none")) | |
192 | rcup->info=NULL; | |
193 | else | |
194 | rcup->info=getsstring(cargv[1],INFOLEN); | |
195 | ||
196 | csdb_updatechanuser(rcup); | |
197 | chanservstdmessage(sender, QM_DONE); | |
198 | } | |
199 | ||
200 | chanservstdmessage(sender, QM_CHANNELINFO, cip->name->content, | |
201 | rcup->info?rcup->info->content:"(none)"); | |
202 | } | |
203 | ||
204 | return CMD_OK; | |
205 | } | |
206 | ||
207 | int csu_dowhois(void *source, int cargc, char **cargv) { | |
208 | nick *sender=source; | |
209 | reguser *rup=getreguserfromnick(sender), *target; | |
210 | char buf[200]; | |
211 | char nbpos=0; | |
212 | nicklist *nlp; | |
213 | struct tm *tmp; | |
214 | regchanuser *rcup, *rcup2; | |
215 | flag_t flagmask, flags; | |
216 | int doneheader=0; | |
217 | ||
218 | if (!(rup=getreguserfromnick(sender))) | |
219 | return CMD_ERROR; | |
220 | ||
221 | if (cargc<1) { | |
222 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "whois"); | |
223 | return CMD_ERROR; | |
224 | } | |
225 | ||
226 | if (!(target=findreguser(sender, cargv[0]))) { | |
227 | nick* np; | |
228 | ||
229 | if ((np=getnickbynick(cargv[0]))) { | |
230 | activeuser* aup=getactiveuserfromnick(np); | |
231 | chanservsendmessage(sender, "%s has attempted to auth %d time%s.", np->nick, aup->authattempts, | |
232 | aup->authattempts==1?"":"s"); | |
233 | } | |
234 | return CMD_ERROR; | |
235 | } | |
236 | ||
237 | if (cargv[0][0]=='#') { | |
238 | chanservstdmessage(sender, QM_WHOISHEADER_AUTH, target->username); | |
239 | } else { | |
240 | chanservstdmessage(sender, QM_WHOISHEADER_NICK, cargv[0], target->username); | |
241 | } | |
242 | ||
243 | if (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender)) { | |
244 | chanservstdmessage(sender, QM_WHOIS_USERID, target->ID); | |
245 | } | |
246 | ||
247 | if (cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) { | |
248 | flagmask=QUFLAG_ALL; | |
249 | } else { | |
250 | if (UIsAdmin(target)) | |
251 | chanservstdmessage(sender, QM_USERISADMIN, target->username); | |
252 | else if (UIsOper(target)) | |
253 | chanservstdmessage(sender, QM_USERISOPER, target->username); | |
254 | else if (UIsHelper(target)) | |
255 | chanservstdmessage(sender, QM_USERISHELPER, target->username); | |
256 | ||
257 | if (UIsDev(target)) | |
258 | chanservstdmessage(sender, QM_USERISDEV, target->username); | |
259 | ||
260 | flagmask=0; | |
261 | } | |
262 | ||
263 | if (rup==target) | |
264 | flagmask|=(QUFLAG_OPER | QUFLAG_DEV | QUFLAG_HELPER | | |
265 | QUFLAG_ADMIN | QUFLAG_INFO | QUFLAG_NOTICE); | |
266 | ||
267 | if (flagmask & target->flags) | |
268 | chanservstdmessage(sender, QM_WHOIS_FLAGS, printflags(flagmask & target->flags, ruflags)); | |
269 | ||
270 | if (!target->nicks) { | |
271 | chanservstdmessage(sender, QM_WHOIS_USERS, "(none)"); | |
272 | } else { | |
273 | for (nlp=target->nicks; ;nlp=nlp->next) { | |
274 | if (nbpos>0 && (!nlp || nbpos+strlen(nlp->np->nick) > 60)) { | |
275 | chanservstdmessage(sender, QM_WHOIS_USERS, buf); | |
276 | nbpos=0; | |
277 | } | |
278 | ||
279 | if (!nlp) | |
280 | break; | |
281 | ||
282 | nbpos+=sprintf(buf+nbpos,"%s ",nlp->np->nick); | |
283 | } | |
284 | } | |
285 | ||
286 | if (target->created) { | |
287 | tmp=gmtime(&(target->created)); | |
288 | strftime(buf,15,"%d/%m/%y %H:%M",tmp); | |
289 | ||
290 | chanservstdmessage(sender, QM_WHOIS_CREATED, buf); | |
291 | } | |
292 | ||
293 | tmp=gmtime(&(target->lastauth)); | |
294 | strftime(buf,15,"%d/%m/%y %H:%M",tmp); | |
295 | ||
296 | chanservstdmessage(sender, QM_WHOIS_LASTAUTH, buf); | |
297 | ||
298 | if (target->lastuserhost && (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender))) { | |
299 | chanservstdmessage(sender, QM_WHOIS_USERLANG, cslanguages[target->languageid] ? | |
300 | cslanguages[target->languageid]->name->content : "(unknown)"); | |
301 | chanservstdmessage(sender, QM_WHOIS_LASTUSERHOST, target->lastuserhost->content); | |
302 | } | |
303 | ||
304 | if (target->email && (rup==target || cs_privcheck(QPRIV_VIEWEMAIL, sender))) { | |
305 | chanservstdmessage(sender, QM_WHOIS_EMAIL, target->email->content); | |
306 | ||
307 | tmp=gmtime(&(target->lastemailchange)); | |
308 | strftime(buf,15,"%d/%m/%y %H:%M",tmp); | |
309 | ||
310 | chanservstdmessage(sender, QM_WHOIS_EMAILSET, buf); | |
311 | } | |
312 | ||
313 | if (target->info) { | |
314 | chanservstdmessage(sender, QM_WHOIS_INFO, target->info->content); | |
315 | } | |
316 | ||
317 | if (target->comment && (cs_privcheck(QPRIV_VIEWCOMMENTS, sender))) { | |
318 | chanservstdmessage(sender, QM_WHOIS_COMMENT, target->comment->content); | |
319 | } | |
320 | ||
321 | for (rcup=target->knownon;rcup;rcup=rcup->nextbyuser) { | |
322 | if (!UHasHelperPriv(rup)) { | |
323 | if (!(rcup2=findreguseronchannel(rcup->chan,rup))) | |
324 | continue; | |
325 | ||
326 | if (!CUHasVoicePriv(rcup2)) | |
327 | continue; | |
328 | ||
329 | flagmask = (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOVOICE | | |
330 | QCUFLAG_AUTOOP | QCUFLAG_TOPIC | QCUFLAG_SPAMCON); | |
331 | ||
332 | if (CUHasMasterPriv(rcup2)) | |
333 | flagmask |= (QCUFLAG_DENY | QCUFLAG_QUIET | QCUFLAG_BANNED); | |
334 | } else { | |
335 | flagmask=QCUFLAG_ALL; | |
336 | } | |
337 | ||
338 | if (!(flags=rcup->flags & flagmask)) | |
339 | continue; | |
340 | ||
341 | if (!doneheader) { | |
342 | doneheader=1; | |
343 | chanservstdmessage(sender, QM_WHOIS_CHANHEADER, target->username); | |
344 | } | |
345 | ||
346 | chanservsendmessage(sender, " %-30s %s",rcup->chan->index->name->content,printflags(flags, rcuflags)); | |
347 | } | |
348 | ||
349 | chanservstdmessage(sender, QM_ENDOFLIST); | |
350 | ||
351 | return CMD_OK; | |
352 | } | |
353 | ||
354 | int csu_dodeluser(void *source, int cargc, char **cargv) { | |
355 | nick *sender=source; | |
356 | reguser *rup=getreguserfromnick(sender), *target; | |
357 | ||
358 | if (!rup) | |
359 | return CMD_ERROR; | |
360 | ||
361 | if (cargc<1) { | |
362 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "deluser"); | |
363 | return CMD_ERROR; | |
364 | } | |
365 | ||
366 | if (!(target=findreguser(sender, cargv[0]))) | |
367 | return CMD_ERROR; | |
368 | ||
369 | cs_log(sender,"DELUSER %s (%s)",target->username,cargc>1?cargv[1]:""); | |
370 | cs_removeuser(target); | |
371 | ||
372 | chanservstdmessage(sender, QM_DONE); | |
373 | ||
374 | return CMD_OK; | |
375 | } | |
376 | ||
377 | int csu_dousercomment(void *source, int cargc, char **cargv) { | |
378 | nick *sender=source; | |
379 | reguser *rup=getreguserfromnick(sender), *target; | |
380 | char buf[300]; | |
381 | int bufpos; | |
382 | ||
383 | if (!rup) | |
384 | return CMD_ERROR; | |
385 | ||
386 | if (cargc<1) { | |
387 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "usercomment"); | |
388 | return CMD_ERROR; | |
389 | } | |
390 | ||
391 | if (!(target=findreguser(sender, cargv[0]))) | |
392 | return CMD_ERROR; | |
393 | ||
394 | if (cargc>1) { | |
395 | if (!ircd_strcmp(cargv[1],"none")) { | |
396 | freesstring(target->comment); | |
397 | target->comment=NULL; | |
398 | } else { | |
399 | if (*cargv[1]=='+') { | |
400 | if (target->comment) { | |
401 | strcpy(buf,target->comment->content); | |
402 | bufpos=target->comment->length; | |
403 | buf[bufpos++]=' '; | |
404 | } else { | |
405 | bufpos=0; | |
406 | } | |
407 | strncpy(buf+bufpos, cargv[1]+1, 250-bufpos); | |
408 | } else { | |
409 | strncpy(buf, cargv[1], 250); | |
410 | } | |
411 | ||
412 | freesstring(target->comment); | |
413 | target->comment=getsstring(buf,250); | |
414 | } | |
415 | csdb_updateuser(target); | |
416 | } | |
417 | ||
418 | if (target->comment) | |
419 | chanservstdmessage(sender, QM_COMMENT, target->username, target->comment->content); | |
420 | else | |
421 | chanservstdmessage(sender, QM_NOCOMMENT, target->username); | |
422 | ||
423 | return CMD_OK; | |
424 | } | |
425 | ||
426 | int csu_dolanguage(void *source, int cargc, char **cargv) { | |
427 | nick *sender=source; | |
428 | reguser *rup=getreguserfromnick(sender); | |
429 | char buf[300]; | |
430 | int bufpos=0; | |
431 | int i; | |
432 | int len; | |
433 | ||
434 | if (!rup) | |
435 | return CMD_ERROR; | |
436 | ||
437 | if (cargc==0) { | |
438 | /* Display language */ | |
439 | i=rup->languageid; | |
440 | chanservstdmessage(sender, QM_YOURLANGUAGE, cslanguages[i] ? cslanguages[i]->name->content : "Unknown"); | |
441 | ||
442 | /* Display available lanaguages */ | |
443 | chanservstdmessage(sender, QM_LANGUAGELIST); | |
444 | ||
445 | for (i=0;i<MAXLANG;i++) { | |
446 | if (cslanguages[i]) { | |
447 | if (bufpos > 70) { | |
448 | chanservsendmessage(sender, "%s", buf); | |
449 | bufpos=0; | |
450 | } | |
451 | len=sprintf(buf+bufpos, "%.14s (%.2s)",cslanguages[i]->name->content,cslanguages[i]->code); | |
452 | memset(buf+bufpos+len,' ',20-len); | |
453 | bufpos+=20; | |
454 | buf[bufpos]='\0'; | |
455 | } | |
456 | } | |
457 | ||
458 | if (bufpos) | |
459 | chanservsendmessage(sender, "%s", buf); | |
460 | ||
461 | chanservstdmessage(sender, QM_ENDOFLIST); | |
462 | } else { | |
463 | /* Set language */ | |
464 | for (i=0;i<MAXLANG;i++) { | |
465 | if (cslanguages[i] && !ircd_strcmp(cargv[0],cslanguages[i]->code)) { | |
466 | /* Match. */ | |
467 | rup->languageid=i; | |
468 | csdb_updateuser(rup); | |
469 | ||
470 | chanservstdmessage(sender, QM_DONE); | |
471 | chanservstdmessage(sender, QM_YOURLANGUAGE, cslanguages[i]->name->content); | |
472 | break; | |
473 | } | |
474 | } | |
475 | ||
476 | if (i==MAXLANG) | |
477 | chanservstdmessage(sender, QM_UNKNOWNLANGUAGE, cargv[0]); | |
478 | } | |
479 | ||
480 | return CMD_OK; | |
481 | } | |
482 | ||
483 | int csu_dosuspenduser(void *source, int cargc, char **cargv) { | |
484 | nick *sender=source; | |
485 | reguser *rup=getreguserfromnick(sender); | |
486 | reguser *vrup; | |
487 | char* flag; | |
488 | char* victim; | |
489 | char* dur_p; | |
490 | char* reason; | |
491 | int kill=1, gline=0, email=0, password=0, hitcount=0; | |
492 | time_t expires=0; | |
493 | int duration=0; | |
494 | struct tm* tmp; | |
495 | char buf[200]=""; | |
496 | int dgwait; | |
497 | ||
498 | if (!rup) | |
499 | return CMD_ERROR; | |
500 | ||
501 | if (cargc < 1) { | |
502 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser"); | |
503 | return CMD_ERROR; | |
504 | } | |
505 | ||
506 | if (cargv[0][0] == '-') { | |
507 | flag=cargv[0]; | |
508 | if (!(victim=strchr(flag, ' '))) { | |
509 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser"); | |
510 | return CMD_ERROR; | |
511 | } | |
512 | *(victim++)='\0'; | |
513 | if (!(dur_p=strchr(victim, ' '))) { | |
514 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser"); | |
515 | return CMD_ERROR; | |
516 | } | |
517 | *(dur_p++)='\0'; | |
518 | if ((reason=strchr(dur_p, ' '))) { | |
519 | *(reason++)='\0'; | |
520 | if ((duration=durationtolong(dur_p))) { | |
521 | if ((duration < 86400) || (duration > 2592000)) { | |
522 | chanservstdmessage(sender, QM_INVALIDDURATION); | |
523 | return CMD_ERROR; | |
524 | } | |
525 | expires=time(0)+duration; | |
526 | } | |
527 | else { | |
528 | *(reason-1)=' '; | |
529 | reason=dur_p; | |
530 | expires=0; | |
531 | } | |
532 | } | |
533 | else { | |
534 | reason=dur_p; | |
535 | expires=0; | |
536 | } | |
537 | ||
538 | if (!ircd_strcmp(flag, "-nokill")) { | |
539 | kill=0; | |
540 | } | |
541 | else if (!ircd_strcmp(flag, "-gline")) { | |
542 | gline=1; | |
543 | } | |
544 | else if (!ircd_strcmp(flag, "-instantgline")) { | |
545 | gline=2; | |
546 | } | |
547 | else if (!ircd_strcmp(flag, "-email")) { | |
548 | email=1; | |
549 | } | |
550 | else if (!ircd_strcmp(flag, "-password")) { | |
551 | password=1; | |
552 | } | |
553 | else { | |
554 | chanservstdmessage(sender, QM_INVALIDCHANLEVCHANGE); | |
555 | return CMD_ERROR; | |
556 | } | |
557 | } | |
558 | else { | |
559 | victim=cargv[0]; | |
560 | if (!(dur_p=strchr(victim, ' '))) { | |
561 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser"); | |
562 | return CMD_ERROR; | |
563 | } | |
564 | *(dur_p++)='\0'; | |
565 | if ((reason=strchr(dur_p, ' '))) { | |
566 | *(reason++)='\0'; | |
567 | if ((duration=durationtolong(dur_p))) { | |
568 | if ((duration < 86400) || (duration > 2592000)) { | |
569 | chanservstdmessage(sender, QM_INVALIDDURATION); | |
570 | return CMD_ERROR; | |
571 | } | |
572 | expires=time(0)+duration; | |
573 | } | |
574 | else { | |
575 | *(reason-1)=' '; | |
576 | reason=dur_p; | |
577 | expires=0; | |
578 | } | |
579 | } | |
580 | else { | |
581 | reason=dur_p; | |
582 | expires=0; | |
583 | } | |
584 | } | |
585 | ||
586 | if (expires) { | |
587 | tmp=gmtime(&expires); | |
588 | strftime(buf,15,"%d/%m/%y %H:%M",tmp); | |
589 | } | |
590 | ||
591 | if (email) { | |
592 | int i; | |
593 | ||
594 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
595 | for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) { | |
596 | if (!ircd_strcmp(vrup->email->content, victim)) { | |
597 | if (UHasSuspension(vrup)) | |
598 | continue; | |
599 | ||
600 | if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) | |
601 | continue; | |
602 | ||
603 | hitcount++; | |
604 | vrup->flags|=QUFLAG_SUSPENDED; | |
605 | vrup->suspendby=rup->ID; | |
606 | vrup->suspendexp=expires; | |
607 | vrup->suspendreason=getsstring(reason, strlen(reason)+1); | |
608 | ||
609 | while (vrup->nicks) { | |
610 | if (!vrup->nicks->np) | |
611 | continue; | |
612 | ||
613 | chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username); | |
614 | chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL); | |
615 | } | |
616 | csdb_updateuser(vrup); | |
617 | } | |
618 | } | |
619 | } | |
620 | ||
621 | chanservwallmessage("%s (%s) bulk suspended <%s>, hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never"); | |
622 | } | |
623 | else if (password) { | |
624 | int i; | |
625 | ||
626 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
627 | for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) { | |
628 | if (!strcmp(vrup->password, victim)) { | |
629 | if (UHasSuspension(vrup)) | |
630 | continue; | |
631 | ||
632 | if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) | |
633 | continue; | |
634 | ||
635 | hitcount++; | |
636 | vrup->flags|=QUFLAG_SUSPENDED; | |
637 | vrup->suspendby=rup->ID; | |
638 | vrup->suspendexp=expires; | |
639 | vrup->suspendreason=getsstring(reason, strlen(reason)+1); | |
640 | ||
641 | while (vrup->nicks) { | |
642 | if (!vrup->nicks->np) | |
643 | continue; | |
644 | ||
645 | chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username); | |
646 | chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL); | |
647 | } | |
648 | csdb_updateuser(vrup); | |
649 | } | |
650 | } | |
651 | } | |
652 | ||
653 | chanservwallmessage("%s (%s) bulk suspended password \"%s\", hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never"); | |
654 | } | |
655 | else { | |
656 | if (!(vrup=findreguser(sender, victim))) | |
657 | return CMD_ERROR; | |
658 | ||
659 | if (!ircd_strcmp(vrup->username, rup->username)) { | |
660 | chanservsendmessage(sender, "You can't suspend yourself, silly."); | |
661 | return CMD_ERROR; | |
662 | } | |
663 | ||
664 | if (UHasSuspension(vrup)) { | |
665 | chanservstdmessage(sender, QM_USERALREADYSUSPENDED); | |
666 | return CMD_ERROR; | |
667 | } | |
668 | ||
669 | if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) { | |
670 | snprintf(buf, 199, "suspenduser on %s", vrup->username); | |
671 | chanservstdmessage(sender, QM_NOACCESS, buf); | |
672 | chanservwallmessage("%s (%s) FAILED to suspend %s", sender->nick, rup->username, vrup->username); | |
673 | return CMD_ERROR; | |
674 | } | |
675 | ||
676 | if (gline == 2) | |
677 | vrup->flags|=QUFLAG_GLINE; | |
678 | else if (gline == 1) | |
679 | vrup->flags|=QUFLAG_DELAYEDGLINE; | |
680 | else | |
681 | vrup->flags|=QUFLAG_SUSPENDED; | |
682 | vrup->suspendby=rup->ID; | |
683 | vrup->suspendexp=expires; | |
684 | vrup->suspendreason=getsstring(reason, strlen(reason)+1); | |
685 | ||
686 | chanservwallmessage("%s (%s) %s %s (expires: %s)", sender->nick, rup->username, (gline)?((gline == 2)?"instantly glined":"delayed glined"):"suspended", vrup->username, expires?buf:"never"); | |
687 | if (gline) { | |
688 | dgwait=(gline==2)?0:rand()%900; | |
689 | chanservsendmessage(sender, "Scheduling delayed GLINE for account %s in %d %s", | |
690 | vrup->username, (dgwait>60)?(dgwait/60):dgwait, (dgwait>60)?"minutes":"seconds"); | |
691 | deleteschedule(NULL, &chanservdgline, (void*)vrup); | |
692 | scheduleoneshot(time(NULL)+dgwait, &chanservdgline, (void*)vrup); | |
693 | } | |
694 | else if (kill) { | |
695 | while (vrup->nicks) { | |
696 | if (!vrup->nicks->np) | |
697 | continue; | |
698 | ||
699 | chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username); | |
700 | chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL); | |
701 | hitcount++; | |
702 | } | |
703 | } | |
704 | ||
705 | csdb_updateuser(vrup); | |
706 | } | |
707 | ||
708 | return CMD_OK; | |
709 | } | |
710 | ||
711 | int csu_dounsuspenduser(void *source, int cargc, char **cargv) { | |
712 | nick *sender=source; | |
713 | reguser *rup=getreguserfromnick(sender); | |
714 | reguser *vrup; | |
715 | char action[100]; | |
716 | ||
717 | if (!rup) | |
718 | return CMD_ERROR; | |
719 | ||
720 | if (cargc < 1) { | |
721 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspenduser"); | |
722 | return CMD_ERROR; | |
723 | } | |
724 | ||
725 | if (cargv[0][0] == '#') { | |
726 | if (!(vrup=findreguserbynick(&cargv[0][1]))) { | |
727 | chanservstdmessage(sender, QM_UNKNOWNUSER, &cargv[0][1]); | |
728 | return CMD_ERROR; | |
729 | } | |
730 | } | |
731 | else { | |
732 | nick *np; | |
733 | ||
734 | if (!(np=getnickbynick(cargv[0]))) { | |
735 | chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[0]); | |
736 | return CMD_ERROR; | |
737 | } | |
738 | ||
739 | if (!(vrup=getreguserfromnick(np)) && sender) { | |
740 | chanservstdmessage(sender, QM_USERNOTAUTHED, cargv[0]); | |
741 | return CMD_ERROR; | |
742 | } | |
743 | } | |
744 | ||
745 | if (!UHasSuspension(vrup)) { | |
746 | chanservstdmessage(sender, QM_USERNOTSUSPENDED, cargv[0]); | |
747 | return CMD_ERROR; | |
748 | } | |
749 | ||
750 | if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) { | |
751 | snprintf(action, 99, "unsuspenduser on %s", vrup->username); | |
752 | chanservstdmessage(sender, QM_NOACCESS, action); | |
753 | chanservwallmessage("%s (%s) FAILED to unsuspend %s", sender->nick, rup->username, vrup->username); | |
754 | return CMD_ERROR; | |
755 | } | |
756 | ||
757 | if (UIsDelayedGline(vrup)) { | |
758 | strcpy(action, "removed delayed gline on"); | |
759 | } | |
760 | else if (UIsGline(vrup)) { | |
761 | strcpy(action, "removed instant gline on"); | |
762 | } | |
763 | else if (UIsSuspended(vrup)) { | |
764 | strcpy(action, "unsuspended"); | |
765 | } | |
766 | else if (UIsNeedAuth(vrup)) { | |
767 | strcpy(action, "enabled"); | |
768 | } | |
769 | else { | |
770 | chanservsendmessage(sender, "Unknown suspend type encountered."); | |
771 | return CMD_ERROR; | |
772 | } | |
773 | ||
774 | vrup->flags&=(~(QUFLAG_GLINE|QUFLAG_DELAYEDGLINE|QUFLAG_SUSPENDED|QUFLAG_NEEDAUTH)); | |
775 | vrup->suspendby=0; | |
776 | vrup->suspendexp=0; | |
777 | freesstring(vrup->suspendreason); | |
778 | vrup->suspendreason=0; | |
779 | csdb_updateuser(vrup); | |
780 | ||
781 | chanservwallmessage("%s (%s) %s %s", sender->nick, rup->username, action, vrup->username); | |
782 | chanservstdmessage(sender, QM_DONE); | |
783 | return CMD_OK; | |
784 | } | |
785 | ||
786 | int csu_dospewdb(void *source, int cargc, char **cargv) { | |
787 | nick *sender=source; | |
788 | reguser *rup=getreguserfromnick(sender); | |
789 | reguser *dbrup; | |
790 | int i; | |
791 | unsigned int count=0; | |
792 | ||
793 | if (!rup) | |
794 | return CMD_ERROR; | |
795 | ||
796 | if (cargc < 1) { | |
797 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewdb"); | |
798 | return CMD_ERROR; | |
799 | } | |
800 | ||
801 | chanservstdmessage(sender, QM_SPEWHEADER); | |
802 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
803 | for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) { | |
804 | if (!match(cargv[0], dbrup->username)) { | |
805 | chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none"); | |
806 | count++; | |
807 | if (count >= 2000) { | |
808 | chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users"); | |
809 | return CMD_ERROR; | |
810 | } | |
811 | } | |
812 | } | |
813 | } | |
814 | chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s"); | |
815 | ||
816 | return CMD_OK; | |
817 | } | |
818 | ||
819 | int csu_dospewpass(void *source, int cargc, char **cargv) { | |
820 | nick *sender=source; | |
821 | reguser *rup=getreguserfromnick(sender); | |
822 | reguser *dbrup; | |
823 | int i; | |
824 | unsigned int count=0; | |
825 | ||
826 | if (!rup) | |
827 | return CMD_ERROR; | |
828 | ||
829 | if (cargc < 1) { | |
830 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewpass"); | |
831 | return CMD_ERROR; | |
832 | } | |
833 | ||
834 | chanservstdmessage(sender, QM_SPEWHEADER); | |
835 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
836 | for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) { | |
837 | if (!match(cargv[0], dbrup->password)) { | |
838 | chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none"); | |
839 | count++; | |
840 | if (count >= 2000) { | |
841 | chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users"); | |
842 | return CMD_ERROR; | |
843 | } | |
844 | } | |
845 | } | |
846 | } | |
847 | chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s"); | |
848 | ||
849 | return CMD_OK; | |
850 | } | |
851 | ||
852 | int csu_dospewemail(void *source, int cargc, char **cargv) { | |
853 | nick *sender=source; | |
854 | reguser *rup=getreguserfromnick(sender); | |
855 | reguser *dbrup; | |
856 | int i; | |
857 | unsigned int count=0; | |
858 | ||
859 | if (!rup) | |
860 | return CMD_ERROR; | |
861 | ||
862 | if (cargc < 1) { | |
863 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewemail"); | |
864 | return CMD_ERROR; | |
865 | } | |
866 | ||
867 | chanservstdmessage(sender, QM_SPEWHEADER); | |
868 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
869 | for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) { | |
870 | if (!dbrup->email) | |
871 | continue; | |
872 | if (!match(cargv[0], dbrup->email->content)) { | |
873 | chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none"); | |
874 | count++; | |
875 | if (count >= 2000) { | |
876 | chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users"); | |
877 | return CMD_ERROR; | |
878 | } | |
879 | } | |
880 | } | |
881 | } | |
882 | chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s"); | |
883 | ||
884 | return CMD_OK; | |
885 | } | |
886 | ||
887 | int csu_dolistflags(void *source, int cargc, char **cargv) { | |
888 | nick *sender=source; | |
889 | reguser *rup=getreguserfromnick(sender); | |
890 | reguser *dbrup; | |
891 | flag_t matchflags = 0; | |
892 | char *ch; | |
893 | int i, j; | |
894 | unsigned int count=0; | |
895 | ||
896 | if (!rup) | |
897 | return CMD_ERROR; | |
898 | ||
899 | if (cargc < 1) { | |
900 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "listflags"); | |
901 | return CMD_ERROR; | |
902 | } | |
903 | ||
904 | ch=cargv[0][0]=='+'?cargv[0]+1:cargv[0]; | |
905 | ||
906 | for (i=0; ch[i]; i++) { | |
907 | for (j = 0; ruflags[j].flagchar; j++) { | |
908 | if (ruflags[j].flagchar == ch[i]) { | |
909 | matchflags|=ruflags[j].flagbit; | |
910 | break; | |
911 | } | |
912 | } | |
913 | } | |
914 | ||
915 | chanservstdmessage(sender, QM_LISTFLAGSHEADER); | |
916 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
917 | for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) { | |
918 | if ((dbrup->flags & matchflags) == matchflags) { | |
919 | chanservsendmessage(sender, "%-15s %-17s %-10s %-30s %s", dbrup->username, printflags(dbrup->flags, ruflags), | |
920 | UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", | |
921 | dbrup->lastuserhost?dbrup->lastuserhost->content:"none"); | |
922 | count++; | |
923 | if (count >= 2000) { | |
924 | chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users"); | |
925 | return CMD_ERROR; | |
926 | } | |
927 | } | |
928 | } | |
929 | } | |
930 | chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s"); | |
931 | ||
932 | return CMD_OK; | |
933 | } | |
934 | ||
935 | int csu_dosuspenduserlist(void *source, int cargc, char **cargv) { | |
936 | nick *sender=source; | |
937 | reguser *rup=getreguserfromnick(sender); | |
938 | reguser *vrup; | |
939 | reguser *dbrup; | |
940 | int i; | |
941 | unsigned int count=0; | |
942 | struct tm *tmp; | |
943 | char buf[200]; | |
944 | ||
945 | if (!rup) | |
946 | return CMD_ERROR; | |
947 | ||
948 | if (cargc < 1) { | |
949 | chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduserlist"); | |
950 | return CMD_ERROR; | |
951 | } | |
952 | ||
953 | vrup=findreguserbynick(cargv[0]); | |
954 | ||
955 | chanservstdmessage(sender, QM_SUSPENDUSERLISTHEADER); | |
956 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
957 | for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) { | |
958 | if (!UHasSuspension(dbrup)) | |
959 | continue; | |
960 | ||
961 | /*if (!ircd_strcmp(dbrup->username, cargv[0]) || (dbrup->suspendby == vrup->ID)) {*/ | |
962 | if (!match(cargv[0], dbrup->username) || (vrup && (dbrup->suspendby == vrup->ID))) { | |
963 | char suspendtype[100]; | |
964 | char *bywhom=0; | |
965 | ||
966 | if ((UIsGline(dbrup) || UIsDelayedGline(dbrup)) && !UHasOperPriv(rup)) | |
967 | continue; | |
968 | ||
969 | if (UIsDelayedGline(dbrup)) | |
970 | strcpy(suspendtype, "delayed gline"); | |
971 | else if (UIsGline(dbrup)) | |
972 | strcpy(suspendtype, "instant gline"); | |
973 | else if (UIsSuspended(dbrup)) | |
974 | strcpy(suspendtype, "suspended"); | |
975 | else | |
976 | strcpy(suspendtype, "not used"); | |
977 | ||
978 | if (vrup && (dbrup->suspendby == vrup->ID)) { | |
979 | bywhom=vrup->username; | |
980 | } | |
981 | else { | |
982 | reguser* trup=findreguserbyID(dbrup->suspendby); | |
983 | if (trup) | |
984 | bywhom=trup->username; | |
985 | } | |
986 | ||
987 | if (dbrup->suspendexp) { | |
988 | tmp=gmtime(&(dbrup->suspendexp)); | |
989 | strftime(buf,15,"%d/%m/%y %H:%M",tmp); | |
990 | } | |
991 | ||
992 | count++; | |
993 | chanservsendmessage(sender, "%-15s %-13s %-15s %-15s %s", dbrup->username, suspendtype, UHasOperPriv(rup)?(bywhom?bywhom:"unknown"):"not shown", (dbrup->suspendexp)?((time(0) >= dbrup->suspendexp)?"next auth":buf):"never", dbrup->suspendreason->content); | |
994 | if (count >= 2000) { | |
995 | chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users"); | |
996 | return CMD_ERROR; | |
997 | } | |
998 | } | |
999 | } | |
1000 | } | |
1001 | chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s"); | |
1002 | ||
1003 | return CMD_OK; | |
1004 | } |