]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/usercmds.c
Initial Import
[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 nicklist *nl;
488 char* flag;
489 char* victim;
490 char* dur_p;
491 char* reason;
492 int kill=1, gline=0, email=0, password=0, hitcount=0;
493 time_t expires=0;
494 int duration=0;
495 struct tm* tmp;
496 char buf[200]="";
497 int dgwait;
498
499 if (!rup)
500 return CMD_ERROR;
501
502 if (cargc < 1) {
503 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
504 return CMD_ERROR;
505 }
506
507 if (cargv[0][0] == '-') {
508 flag=cargv[0];
509 if (!(victim=strchr(flag, ' '))) {
510 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
511 return CMD_ERROR;
512 }
513 *(victim++)='\0';
514 if (!(dur_p=strchr(victim, ' '))) {
515 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
516 return CMD_ERROR;
517 }
518 *(dur_p++)='\0';
519 if ((reason=strchr(dur_p, ' '))) {
520 *(reason++)='\0';
521 if ((duration=durationtolong(dur_p))) {
522 if ((duration < 86400) || (duration > 2592000)) {
523 chanservstdmessage(sender, QM_INVALIDDURATION);
524 return CMD_ERROR;
525 }
526 expires=time(0)+duration;
527 }
528 else {
529 *(reason-1)=' ';
530 reason=dur_p;
531 expires=0;
532 }
533 }
534 else {
535 reason=dur_p;
536 expires=0;
537 }
538
539 if (!ircd_strcmp(flag, "-nokill")) {
540 kill=0;
541 }
542 else if (!ircd_strcmp(flag, "-gline")) {
543 gline=1;
544 }
545 else if (!ircd_strcmp(flag, "-instantgline")) {
546 gline=2;
547 }
548 else if (!ircd_strcmp(flag, "-email")) {
549 email=1;
550 }
551 else if (!ircd_strcmp(flag, "-password")) {
552 password=1;
553 }
554 else {
555 chanservstdmessage(sender, QM_INVALIDCHANLEVCHANGE);
556 return CMD_ERROR;
557 }
558 }
559 else {
560 victim=cargv[0];
561 if (!(dur_p=strchr(victim, ' '))) {
562 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
563 return CMD_ERROR;
564 }
565 *(dur_p++)='\0';
566 if ((reason=strchr(dur_p, ' '))) {
567 *(reason++)='\0';
568 if ((duration=durationtolong(dur_p))) {
569 if ((duration < 86400) || (duration > 2592000)) {
570 chanservstdmessage(sender, QM_INVALIDDURATION);
571 return CMD_ERROR;
572 }
573 expires=time(0)+duration;
574 }
575 else {
576 *(reason-1)=' ';
577 reason=dur_p;
578 expires=0;
579 }
580 }
581 else {
582 reason=dur_p;
583 expires=0;
584 }
585 }
586
587 if (expires) {
588 tmp=gmtime(&expires);
589 strftime(buf,15,"%d/%m/%y %H:%M",tmp);
590 }
591
592 if (email) {
593 int i;
594
595 for (i=0;i<REGUSERHASHSIZE;i++) {
596 for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) {
597 if (!ircd_strcmp(vrup->email->content, victim)) {
598 if (UHasSuspension(vrup))
599 continue;
600
601 if (UHasOperPriv(vrup) && !UHasAdminPriv(rup))
602 continue;
603
604 hitcount++;
605 vrup->flags|=QUFLAG_SUSPENDED;
606 vrup->suspendby=rup->ID;
607 vrup->suspendexp=expires;
608 vrup->suspendreason=getsstring(reason, strlen(reason)+1);
609
610 while (vrup->nicks) {
611 if (!vrup->nicks->np)
612 continue;
613
614 chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
615 chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
616 }
617 csdb_updateuser(vrup);
618 }
619 }
620 }
621
622 chanservwallmessage("%s (%s) bulk suspended <%s>, hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never");
623 }
624 else if (password) {
625 int i;
626
627 for (i=0;i<REGUSERHASHSIZE;i++) {
628 for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) {
629 if (!strcmp(vrup->password, victim)) {
630 if (UHasSuspension(vrup))
631 continue;
632
633 if (UHasOperPriv(vrup) && !UHasAdminPriv(rup))
634 continue;
635
636 hitcount++;
637 vrup->flags|=QUFLAG_SUSPENDED;
638 vrup->suspendby=rup->ID;
639 vrup->suspendexp=expires;
640 vrup->suspendreason=getsstring(reason, strlen(reason)+1);
641
642 while (vrup->nicks) {
643 if (!vrup->nicks->np)
644 continue;
645
646 chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
647 chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
648 }
649 csdb_updateuser(vrup);
650 }
651 }
652 }
653
654 chanservwallmessage("%s (%s) bulk suspended password \"%s\", hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never");
655 }
656 else {
657 if (!(vrup=findreguser(sender, victim)))
658 return CMD_ERROR;
659
660 if (!ircd_strcmp(vrup->username, rup->username)) {
661 chanservsendmessage(sender, "You can't suspend yourself, silly.");
662 return CMD_ERROR;
663 }
664
665 if (UHasSuspension(vrup)) {
666 chanservstdmessage(sender, QM_USERALREADYSUSPENDED);
667 return CMD_ERROR;
668 }
669
670 if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) {
671 snprintf(buf, 199, "suspenduser on %s", vrup->username);
672 chanservstdmessage(sender, QM_NOACCESS, buf);
673 chanservwallmessage("%s (%s) FAILED to suspend %s", sender->nick, rup->username, vrup->username);
674 return CMD_ERROR;
675 }
676
677 if (gline == 2)
678 vrup->flags|=QUFLAG_GLINE;
679 else if (gline == 1)
680 vrup->flags|=QUFLAG_DELAYEDGLINE;
681 else
682 vrup->flags|=QUFLAG_SUSPENDED;
683 vrup->suspendby=rup->ID;
684 vrup->suspendexp=expires;
685 vrup->suspendreason=getsstring(reason, strlen(reason)+1);
686
687 chanservwallmessage("%s (%s) %s %s (expires: %s)", sender->nick, rup->username, (gline)?((gline == 2)?"instantly glined":"delayed glined"):"suspended", vrup->username, expires?buf:"never");
688 if (gline) {
689 dgwait=(gline==2)?0:rand()%900;
690 chanservsendmessage(sender, "Scheduling delayed GLINE for account %s in %d %s",
691 vrup->username, (dgwait>60)?(dgwait/60):dgwait, (dgwait>60)?"minutes":"seconds");
692 deleteschedule(NULL, &chanservdgline, (void*)vrup);
693 scheduleoneshot(time(NULL)+dgwait, &chanservdgline, (void*)vrup);
694 }
695 else if (kill) {
696 while (vrup->nicks) {
697 if (!vrup->nicks->np)
698 continue;
699
700 chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
701 chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
702 hitcount++;
703 }
704 }
705
706 csdb_updateuser(vrup);
707 }
708
709 return CMD_OK;
710 }
711
712 int csu_dounsuspenduser(void *source, int cargc, char **cargv) {
713 nick *sender=source;
714 reguser *rup=getreguserfromnick(sender);
715 reguser *vrup;
716 char action[100];
717
718 if (!rup)
719 return CMD_ERROR;
720
721 if (cargc < 1) {
722 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspenduser");
723 return CMD_ERROR;
724 }
725
726 if (cargv[0][0] == '#') {
727 if (!(vrup=findreguserbynick(&cargv[0][1]))) {
728 chanservstdmessage(sender, QM_UNKNOWNUSER, &cargv[0][1]);
729 return CMD_ERROR;
730 }
731 }
732 else {
733 nick *np;
734
735 if (!(np=getnickbynick(cargv[0]))) {
736 chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[0]);
737 return CMD_ERROR;
738 }
739
740 if (!(vrup=getreguserfromnick(np)) && sender) {
741 chanservstdmessage(sender, QM_USERNOTAUTHED, cargv[0]);
742 return CMD_ERROR;
743 }
744 }
745
746 if (!UHasSuspension(vrup)) {
747 chanservstdmessage(sender, QM_USERNOTSUSPENDED, cargv[0]);
748 return CMD_ERROR;
749 }
750
751 if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) {
752 snprintf(action, 99, "unsuspenduser on %s", vrup->username);
753 chanservstdmessage(sender, QM_NOACCESS, action);
754 chanservwallmessage("%s (%s) FAILED to unsuspend %s", sender->nick, rup->username, vrup->username);
755 return CMD_ERROR;
756 }
757
758 if (UIsDelayedGline(vrup)) {
759 strcpy(action, "removed delayed gline on");
760 }
761 else if (UIsGline(vrup)) {
762 strcpy(action, "removed instant gline on");
763 }
764 else if (UIsSuspended(vrup)) {
765 strcpy(action, "unsuspended");
766 }
767 else if (UIsNeedAuth(vrup)) {
768 strcpy(action, "enabled");
769 }
770 else {
771 chanservsendmessage(sender, "Unknown suspend type encountered.");
772 return CMD_ERROR;
773 }
774
775 vrup->flags&=(~(QUFLAG_GLINE|QUFLAG_DELAYEDGLINE|QUFLAG_SUSPENDED|QUFLAG_NEEDAUTH));
776 vrup->suspendby=0;
777 vrup->suspendexp=0;
778 freesstring(vrup->suspendreason);
779 vrup->suspendreason=0;
780 csdb_updateuser(vrup);
781
782 chanservwallmessage("%s (%s) %s %s", sender->nick, rup->username, action, vrup->username);
783 chanservstdmessage(sender, QM_DONE);
784 return CMD_OK;
785 }
786
787 int csu_dospewdb(void *source, int cargc, char **cargv) {
788 nick *sender=source;
789 reguser *rup=getreguserfromnick(sender);
790 reguser *dbrup;
791 int i;
792 unsigned int count=0;
793
794 if (!rup)
795 return CMD_ERROR;
796
797 if (cargc < 1) {
798 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewdb");
799 return CMD_ERROR;
800 }
801
802 chanservstdmessage(sender, QM_SPEWHEADER);
803 for (i=0;i<REGUSERHASHSIZE;i++) {
804 for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
805 if (!match(cargv[0], dbrup->username)) {
806 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");
807 count++;
808 if (count >= 2000) {
809 chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
810 return CMD_ERROR;
811 }
812 }
813 }
814 }
815 chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
816
817 return CMD_OK;
818 }
819
820 int csu_dospewpass(void *source, int cargc, char **cargv) {
821 nick *sender=source;
822 reguser *rup=getreguserfromnick(sender);
823 reguser *dbrup;
824 int i;
825 unsigned int count=0;
826
827 if (!rup)
828 return CMD_ERROR;
829
830 if (cargc < 1) {
831 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewpass");
832 return CMD_ERROR;
833 }
834
835 chanservstdmessage(sender, QM_SPEWHEADER);
836 for (i=0;i<REGUSERHASHSIZE;i++) {
837 for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
838 if (!match(cargv[0], dbrup->password)) {
839 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");
840 count++;
841 if (count >= 2000) {
842 chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
843 return CMD_ERROR;
844 }
845 }
846 }
847 }
848 chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
849
850 return CMD_OK;
851 }
852
853 int csu_dospewemail(void *source, int cargc, char **cargv) {
854 nick *sender=source;
855 reguser *rup=getreguserfromnick(sender);
856 reguser *dbrup;
857 int i;
858 unsigned int count=0;
859
860 if (!rup)
861 return CMD_ERROR;
862
863 if (cargc < 1) {
864 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewemail");
865 return CMD_ERROR;
866 }
867
868 chanservstdmessage(sender, QM_SPEWHEADER);
869 for (i=0;i<REGUSERHASHSIZE;i++) {
870 for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
871 if (!dbrup->email)
872 continue;
873 if (!match(cargv[0], dbrup->email->content)) {
874 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");
875 count++;
876 if (count >= 2000) {
877 chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
878 return CMD_ERROR;
879 }
880 }
881 }
882 }
883 chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
884
885 return CMD_OK;
886 }
887
888 int csu_dolistflags(void *source, int cargc, char **cargv) {
889 nick *sender=source;
890 reguser *rup=getreguserfromnick(sender);
891 reguser *dbrup;
892 flag_t matchflags = 0;
893 char *ch;
894 int i, j;
895 unsigned int count=0;
896 int level=0;
897
898 if (!rup)
899 return CMD_ERROR;
900
901 if (cargc < 1) {
902 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "listflags");
903 return CMD_ERROR;
904 }
905
906 ch=cargv[0][0]=='+'?cargv[0]+1:cargv[0];
907
908 for (i=0; ch[i]; i++) {
909 for (j = 0; ruflags[j].flagchar; j++) {
910 if (ruflags[j].flagchar == ch[i]) {
911 matchflags|=ruflags[j].flagbit;
912 break;
913 }
914 }
915 }
916
917 chanservstdmessage(sender, QM_LISTFLAGSHEADER);
918 for (i=0;i<REGUSERHASHSIZE;i++) {
919 for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
920 if ((dbrup->flags & matchflags) == matchflags) {
921 chanservsendmessage(sender, "%-15s %-17s %-10s %-30s %s", dbrup->username, printflags(dbrup->flags, ruflags),
922 UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set",
923 dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
924 count++;
925 if (count >= 2000) {
926 chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
927 return CMD_ERROR;
928 }
929 }
930 }
931 }
932 chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
933
934 return CMD_OK;
935 }
936
937 int csu_dosuspenduserlist(void *source, int cargc, char **cargv) {
938 nick *sender=source;
939 reguser *rup=getreguserfromnick(sender);
940 reguser *vrup;
941 reguser *dbrup;
942 int i;
943 unsigned int count=0;
944 struct tm *tmp;
945 char buf[200];
946
947 if (!rup)
948 return CMD_ERROR;
949
950 if (cargc < 1) {
951 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduserlist");
952 return CMD_ERROR;
953 }
954
955 vrup=findreguserbynick(cargv[0]);
956
957 chanservstdmessage(sender, QM_SUSPENDUSERLISTHEADER);
958 for (i=0;i<REGUSERHASHSIZE;i++) {
959 for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
960 if (!UHasSuspension(dbrup))
961 continue;
962
963 /*if (!ircd_strcmp(dbrup->username, cargv[0]) || (dbrup->suspendby == vrup->ID)) {*/
964 if (!match(cargv[0], dbrup->username) || (vrup && (dbrup->suspendby == vrup->ID))) {
965 char suspendtype[100];
966 char *bywhom=0;
967
968 if ((UIsGline(dbrup) || UIsDelayedGline(dbrup)) && !UHasOperPriv(rup))
969 continue;
970
971 if (UIsDelayedGline(dbrup))
972 strcpy(suspendtype, "delayed gline");
973 else if (UIsGline(dbrup))
974 strcpy(suspendtype, "instant gline");
975 else if (UIsSuspended(dbrup))
976 strcpy(suspendtype, "suspended");
977 else
978 strcpy(suspendtype, "not used");
979
980 if (vrup && (dbrup->suspendby == vrup->ID)) {
981 bywhom=vrup->username;
982 }
983 else {
984 reguser* trup=findreguserbyID(dbrup->suspendby);
985 if (trup)
986 bywhom=trup->username;
987 }
988
989 if (dbrup->suspendexp) {
990 tmp=gmtime(&(dbrup->suspendexp));
991 strftime(buf,15,"%d/%m/%y %H:%M",tmp);
992 }
993
994 count++;
995 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);
996 if (count >= 2000) {
997 chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
998 return CMD_ERROR;
999 }
1000 }
1001 }
1002 }
1003 chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
1004
1005 return CMD_OK;
1006 }