]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/usercmds.c
Add jupe support
[irc/quakenet/newserv.git] / chanserv / usercmds.c
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 }