]> jfr.im git - irc/quakenet/newserv.git/commitdiff
CHANSERV: require reasons for getpassword, setemail, setpassword, unsuspendchan,...
authorChris Porter <redacted>
Sun, 15 Feb 2009 20:15:45 +0000 (20:15 +0000)
committerChris Porter <redacted>
Sun, 15 Feb 2009 20:15:45 +0000 (20:15 +0000)
Emit reasons everywhere, and log everything too.

12 files changed:
chanserv/authcmds/getpassword.c
chanserv/authcmds/setemail.c
chanserv/authcmds/setpassword.c
chanserv/chancmds/suspendchan.c
chanserv/chancmds/unsuspendchan.c
chanserv/chanserv.h
chanserv/chanserv_messages.h
chanserv/chanservuser.c
chanserv/usercmds/deluser.c
chanserv/usercmds/spewpassword.c
chanserv/usercmds/suspenduser.c
chanserv/usercmds/unsuspenduser.c

index 26e07bb7d7684ef9dbb38b5712b2329b3d66217a..03af6700693a98155971551ebcb43f535190bb4b 100644 (file)
@@ -8,7 +8,7 @@
  * CMDDESC: Gets a users password
  * CMDFUNC: csa_dogetpw
  * CMDPROTO: int csa_dogetpw(void *source, int cargc, char **cargv);
- * CMDHELP: Usage: @UCOMMAND@ <username>
+ * CMDHELP: Usage: @UCOMMAND@ <username> <reason>
  * CMDHELP: Fetches the password for the specified username.
  */
 
@@ -22,8 +22,9 @@ int csa_dogetpw(void *source, int cargc, char **cargv) {
   reguser *rup;
   nick *sender=source;
   reguser *srup=getreguserfromnick(sender);
+  char *reason;
 
-  if (cargc<1) {
+  if (cargc<2) {
     chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "getpassword");
     return CMD_ERROR;
   }
@@ -31,15 +32,19 @@ int csa_dogetpw(void *source, int cargc, char **cargv) {
   if (!(rup=findreguser(sender, cargv[0])))
     return CMD_ERROR;
 
+  reason = cargv[1];
+  if(!checkreason(sender, reason))
+    return CMD_ERROR;
+
   if(UHasStaffPriv(rup)) {
-    cs_log(sender,"GETPASSWORD FAILED username %s",rup->username);
-    chanservwallmessage("%s (%s) just FAILED using GETPASSWORD on %s", sender->nick, srup->username, rup->username);
+    cs_log(sender,"GETPASSWORD FAILED username %s (reason: %s)",rup->username, reason);
+    chanservwallmessage("%s (%s) just FAILED using GETPASSWORD on %s (reason: %s)", sender->nick, srup->username, rup->username, reason);
     chanservsendmessage(sender, "Sorry, that user is privileged.");
     return CMD_ERROR;
   }
 
-  cs_log(sender,"GETPASSWORD OK username %s",rup->username);
-  chanservwallmessage("%s (%s) just used GETPASSWORD on %s", sender->nick, srup->username, rup->username);
+  cs_log(sender,"GETPASSWORD OK username %s (reason: %s)",rup->username, reason);
+  chanservwallmessage("%s (%s) just used GETPASSWORD on %s (reason: %s)", sender->nick, srup->username, rup->username, reason);
 
   chanservsendmessage(sender, "Password is currently: %s",rup->password);
   return CMD_OK;
index b76ed1354cecc804fe2b6327ab2a63dff9de591c..35dde83a93be2b7046654a412db427e8d2b262cf 100644 (file)
@@ -3,11 +3,11 @@
  *
  * CMDNAME: setemail
  * CMDLEVEL: QCMD_OPER
- * CMDARGS: 2
+ * CMDARGS: 3
  * CMDDESC: Set the email address.
  * CMDFUNC: csa_dosetmail
  * CMDPROTO: int csa_dosetmail(void *source, int cargc, char **cargv);
- * CMDHELP: Usage: setemail <username> <email address>
+ * CMDHELP: Usage: setemail <username> <email address> <reason for modification>
  * CMDHELP: Sets the email address for the specified username.
  */
 
@@ -22,8 +22,9 @@ int csa_dosetmail(void *source, int cargc, char **cargv) {
   reguser *rup, *vrup = getreguserfromnick(sender);
   char *dupemail;
   char *local;
+  char *reason;
 
-  if (cargc<2) {
+  if (cargc<3) {
     chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setemail");
     return CMD_ERROR;
   }
@@ -39,9 +40,13 @@ int csa_dosetmail(void *source, int cargc, char **cargv) {
   if (csa_checkeboy(sender, cargv[1]))
     return CMD_ERROR;
 
+  reason = cargv[2];
+  if(!checkreason(sender, reason))
+    return CMD_ERROR;
+
   if(UHasStaffPriv(rup)) {
-    cs_log(sender,"SETEMAIL FAILED username %s",rup->username);
-    chanservwallmessage("%s (%s) just FAILED using SETEMAIL on %s: %s", sender->nick, vrup->username, rup->username, cargv[1]);
+    cs_log(sender,"SETEMAIL FAILED username %s (reason: %s)",rup->username, reason);
+    chanservwallmessage("%s (%s) just FAILED using SETEMAIL on %s: %s (reason: %s)", sender->nick, vrup->username, rup->username, cargv[1], reason);
     chanservsendmessage(sender, "Sorry, that user is privileged.");
     return CMD_ERROR;
   }
@@ -68,8 +73,8 @@ int csa_dosetmail(void *source, int cargc, char **cargv) {
   free(dupemail);
 
   chanservstdmessage(sender, QM_EMAILCHANGED, cargv[1]);
-  cs_log(sender,"SETEMAIL OK username %s <%s>",rup->username,rup->email->content);
-  chanservwallmessage("%s (%s) just used SETEMAIL on %s: %s", sender->nick, vrup->username, rup->username, rup->email->content);
+  cs_log(sender,"SETEMAIL OK username %s <%s> (reason: %s)",rup->username,rup->email->content, reason);
+  chanservwallmessage("%s (%s) just used SETEMAIL on %s: %s (reason: %s)", sender->nick, vrup->username, rup->username, rup->email->content, reason);
 
   csdb_updateuser(rup);
 
index 0eaa01357642cac44ff0607af9fca58ed32daa35..7ab4d97297f0c4b809fa96bf242d0eab60cf600d 100644 (file)
@@ -4,11 +4,11 @@
  * CMDNAME: setpassword
  * CMDALIASES: setpass
  * CMDLEVEL: QCMD_OPER
- * CMDARGS: 2
+ * CMDARGS: 3
  * CMDDESC: Set a new password.
  * CMDFUNC: csa_dosetpw
  * CMDPROTO: int csa_dosetpw(void *source, int cargc, char **cargv);
- * CMDHELP: Usage: @UCOMMAND@ <username> <password>
+ * CMDHELP: Usage: @UCOMMAND@ <username> <password> <reason for use>
  * CMDHELP: Sets the password for the specified username.
  */
 
@@ -21,8 +21,9 @@
 int csa_dosetpw(void *source, int cargc, char **cargv) {
   nick *sender=source;
   reguser *rup, *vrup=getreguserfromnick(sender);
+  char *reason;
 
-  if (cargc<2) {
+  if (cargc<3) {
     chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setpassword");
     return CMD_ERROR;
   }
@@ -30,15 +31,19 @@ int csa_dosetpw(void *source, int cargc, char **cargv) {
   if (!(rup=findreguser(sender, cargv[0])))
     return CMD_ERROR;
 
+  reason = cargv[2];
+  if(!checkreason(sender, reason))
+    return CMD_ERROR;
+
   if(UHasStaffPriv(rup)) {
-    cs_log(sender,"GETPASSWORD FAILED username %s",rup->username);
-    chanservwallmessage("%s (%s) just FAILED using SETPASSWORD on %s", sender->nick, vrup->username, rup->username);
+    cs_log(sender,"GETPASSWORD FAILED username %s (reason: %s)",rup->username, reason);
+    chanservwallmessage("%s (%s) just FAILED using SETPASSWORD on %s (reason: %s)", sender->nick, vrup->username, rup->username, reason);
     chanservsendmessage(sender, "Sorry, that user is privileged.");
     return CMD_ERROR;
   }
 
-  cs_log(sender,"SETPASSWORD OK username %s",rup->username);
-  chanservwallmessage("%s (%s) just used SETPASSWORD on %s", sender->nick, vrup->username, rup->username);
+  cs_log(sender,"SETPASSWORD OK username %s (reason: %s)",rup->username, reason);
+  chanservwallmessage("%s (%s) just used SETPASSWORD on %s (reason: %s)", sender->nick, vrup->username, rup->username, reason);
 
   if(rup->lastemail) {
     freesstring(rup->lastemail);
index a20c08c5f3005324da42078dc565a18e0961e279..8a68c90495980735e5209fc9dd19a175286a7a3a 100644 (file)
@@ -36,6 +36,9 @@ int csc_dosuspendchan(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
+  if(!checkreason(sender, cargv[1]))
+    return CMD_ERROR;
+
   if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
     chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
     return CMD_ERROR;
@@ -50,6 +53,9 @@ int csc_dosuspendchan(void *source, int cargc, char **cargv) {
   rcp->suspendreason = getsstring(cargv[1], 250);
   rcp->suspendby = rup->ID;
   rcp->suspendtime = time(NULL);
+
+  chanservwallmessage("%s (%s) used SUSPENDCHAN on %s (reason: %s)", sender->nick, rup->username, cip->name->content, rcp->suspendreason->content);
+
   cs_log(sender,"SUSPENDCHAN %s (%s)",cip->name->content,rcp->suspendreason->content);
   if(cip->channel)
     chanservjoinchan(cip->channel);
index 34f4c0b869a4922b156dec95b4e00a68451d177b..73a0dd93cade8e6a986c78eb710c8cfb3b994f37 100644 (file)
@@ -3,11 +3,11 @@
  *
  * CMDNAME: unsuspendchan
  * CMDLEVEL: QCMD_OPER
- * CMDARGS: 1
+ * CMDARGS: 2
  * CMDDESC: Unsuspends a channel from the bot.
  * CMDFUNC: csc_dounsuspendchan
  * CMDPROTO: int csc_dounsuspendchan(void *source, int cargc, char **cargv);
- * CMDHELP: Usage: unsuspendchan <channel>
+ * CMDHELP: Usage: unsuspendchan <channel> <reason>
  * CMDHELP: Unsuspends specified channel.
  */
 
@@ -27,15 +27,22 @@ int csc_dounsuspendchan(void *source, int cargc, char **cargv) {
   reguser *rup=getreguserfromnick(sender);
   chanindex *cip;
   regchan *rcp;
+  reguser *suspendedby;
+  char *csuspendedby, *csuspendedreason;
+  char *unsuspendreason;
 
   if (!rup)
     return CMD_ERROR;
 
-  if (cargc<1) {
+  if (cargc<2) {
     chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspendchan");
     return CMD_ERROR;
   }
 
+  unsuspendreason = cargv[1];
+  if(!checkreason(sender, unsuspendreason))
+    return CMD_ERROR;
+
   if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
     chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
     return CMD_ERROR;
@@ -48,7 +55,14 @@ int csc_dounsuspendchan(void *source, int cargc, char **cargv) {
   }
 
   CClearSuspended(rcp);
-  cs_log(sender,"UNSUSPENDCHAN %s (%s)",cip->name->content,rcp->suspendreason?rcp->suspendreason->content:"(no reason)");
+
+  suspendedby = findreguserbyID(rcp->suspendby);
+  csuspendedby = suspendedby?suspendedby->username:"(unknown)";
+  csuspendedreason = rcp->suspendreason?rcp->suspendreason->content:"(no reason)";
+
+  chanservwallmessage("%s (%s) used UNSUSPENDCHAN on %s (suspended by: %s, suspension reason: %s), unsuspension reason: %s", sender->nick, rup->username, cip->name->content, csuspendedby, csuspendedreason, unsuspendreason);
+  cs_log(sender,"UNSUSPENDCHAN %s (suspended by: %s, suspension reason: %s), unsuspension reason: %s", cip->name->content, csuspendedby, csuspendedreason, unsuspendreason);
+
   freesstring(rcp->suspendreason);
   rcp->suspendreason = NULL;
   rcp->suspendby = 0;
index 924ce473db8d0fd5fa15624a339b30404066a3e7..413cca4bb225138ad50affc7d425090d0d36306c 100644 (file)
@@ -90,6 +90,9 @@
 #define ENTROPYSOURCE "/dev/urandom"
 #define ENTROPYLEN    8
 
+/* Minimum acceptable reason length for stuff like deluser */
+#define MIN_REASONLEN 20
+
 #include "chanserv_messages.h"
 
 #define CSMIN(a, b) ((a)<(b)?(a):(b))
@@ -828,6 +831,7 @@ flag_t cs_sanitisechanlev(flag_t flags);
 typedef int (*UnbanFN)(void *arg, struct chanban *ban);
 int cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans, int abortonfailure);
 void cs_logchanop(regchan *rcp, char *nick, reguser *rup);
+int checkreason(nick *np, char *reason);
 
 /* chanservstdcmds.c */
 int cs_doshowcommands(void *source, int cargc, char **cargv);
index 3fe68824a3f96205e14506d5434eaa84bade9d0f..96ec1d631a612913e506adb77cae1f9ba7b32f1b 100644 (file)
@@ -225,6 +225,7 @@ BeginMessages() {
   msg(QM_CONFIGURATIONERROR, "Configuration error, contact an IRC Operator.", ""),
   msg(QM_INVALIDHMAC, "The supplied login credentials are not valid (bad HMAC).", ""),
   msg(QM_PASSEMAILCHANGED, "Auth failed: account password has been changed since you logged in.", ""),
+  msg(QM_REASONREQUIRED, "Supply a decent reason.", ""),
 } 
 EndMessages()
 #endif
index b4ed4fa5d1c40a289174e8422f5e54e0d5699e9e..57e94bfc633f73df63d9897ebde2b01fce04db63 100644 (file)
@@ -1390,3 +1390,12 @@ void cs_logchanop(regchan *rcp, char *nick, reguser *rup) {
   rcp->chanopaccts[rcp->chanoppos]=rup->ID;
   rcp->chanoppos=(rcp->chanoppos+1)%CHANOPHISTORY;
 }
+
+int checkreason(nick *np, char *reason) {
+  if((strlen(reason) < MIN_REASONLEN) || !strchr(reason, ' ')) {
+    chanservstdmessage(np, QM_REASONREQUIRED);
+    return 0;
+  }
+
+  return 1;
+}
index 9da47ae377a6caaa517d246f8f67ab60e5f2ad97..735f701fd1d571455bd600752239872e562bc2b8 100644 (file)
@@ -20,6 +20,7 @@
 int csu_dodeluser(void *source, int cargc, char **cargv) {
   nick *sender=source;
   reguser *rup=getreguserfromnick(sender), *target;
+  char *reason;
 
   if (!rup)
     return CMD_ERROR;
@@ -29,18 +30,22 @@ int csu_dodeluser(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
+  reason = cargv[1];
+  if(!checkreason(sender, reason))
+    return CMD_ERROR;
+
   if (!(target=findreguser(sender, cargv[0])))
     return CMD_ERROR;
   
   if(UHasStaffPriv(target)) {
-    cs_log(sender,"DELUSER FAILED username %s (%s)",target->username,cargc>1?cargv[1]:"");
-    chanservwallmessage("%s (%s) just FAILED using DELUSER on %s (%s)", sender->nick, rup->username, target->username, cargv[1]);
+    cs_log(sender,"DELUSER FAILED username %s (reason: %s)",target->username,reason);
+    chanservwallmessage("%s (%s) just FAILED using DELUSER on %s (reason: %s)", sender->nick, rup->username, target->username, reason);
     chanservsendmessage(sender, "Sorry, that user is privileged.");
     return CMD_ERROR;
   }
 
-  cs_log(sender,"DELUSER OK username %s (%s)",target->username,cargv[1]);
-  chanservwallmessage("%s (%s) just used DELUSER on %s (%s)", sender->nick, rup->username, target->username, cargv[1]);
+  cs_log(sender,"DELUSER OK username %s (reason: %s)",target->username,reason);
+  chanservwallmessage("%s (%s) just used DELUSER on %s (reason: %s)", sender->nick, rup->username, target->username, reason);
 
   cs_removeuser(target);
 
index 7119c0c5ba61e20b107bd756156af5081922c04c..571636f53335476c227941b19892a3b6027af189 100644 (file)
@@ -3,11 +3,11 @@
  *
  * CMDNAME: spewpassword
  * CMDLEVEL: QCMD_OPER
- * CMDARGS: 1
+ * CMDARGS: 2
  * CMDDESC: Search for a password in the database.
  * CMDFUNC: csu_dospewpass
  * CMDPROTO: int csu_dospewpass(void *source, int cargc, char **cargv);
- * CMDHELP: Usage: spewpassword <pattern>
+ * CMDHELP: Usage: spewpassword <pattern> <reason>
  * CMDHELP: Displays all users with a password that matches the specified pattern.
  */
 
@@ -22,17 +22,22 @@ int csu_dospewpass(void *source, int cargc, char **cargv) {
   reguser *dbrup;
   int i;
   unsigned int count=0;
-  
+  char *reason;
+
   if (!rup)
     return CMD_ERROR;
   
-  if (cargc < 1) {
+  if (cargc < 2) {
     chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewpass");
     return CMD_ERROR;
   }
 
-  cs_log(sender, "SPEWPASS %s", cargv[0]);
-  chanservwallmessage("%s (%s) using SPEWPASS (see log for password)", sender->nick, rup->username);
+  reason = cargv[1];
+  if(!checkreason(sender, reason))
+    return CMD_ERROR;
+
+  cs_log(sender, "SPEWPASS %s (reason: %s)", cargv[0], reason);
+  chanservwallmessage("%s (%s) using SPEWPASS (see log for password), reason: %s", sender->nick, rup->username, reason);
   
   chanservstdmessage(sender, QM_SPEWHEADER);
   for (i=0;i<REGUSERHASHSIZE;i++) {
index 054d2e7357c338de3eb3521ec9c3bb9e86129796..0d2b32abffe017146b3e9f2543f1c264c92e056b 100644 (file)
@@ -95,7 +95,7 @@ int csu_dosuspenduser(void *source, int cargc, char **cargv) {
       reason=dur_p;
       expires=0;
     }
-    
+
     if (!ircd_strcmp(flag, "-nokill")) {
       kill=0;
     }
@@ -144,6 +144,9 @@ int csu_dosuspenduser(void *source, int cargc, char **cargv) {
     }
   }
   
+  if(!checkreason(sender, reason))
+    return CMD_ERROR;
+    
   if (expires)
     q9strftime(expiresbuf,sizeof(expiresbuf),expires);
   
@@ -172,7 +175,8 @@ int csu_dosuspenduser(void *source, int cargc, char **cargv) {
       }
     }
     
-    chanservwallmessage("%s (%s) bulk suspended <%s>, hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?expiresbuf:"never");
+    chanservwallmessage("%s (%s) bulk suspended <%s>, hit %d account/s (expires: %s), reason: %s", sender->nick, rup->username, victim, hitcount, expires?expiresbuf:"never", reason);
+    cs_log(sender, "SUSPENDUSER (bulk by email: %s, hit: %d) expires: %s, reason: %s", victim, hitcount, expires?expiresbuf:"never", reason);
   }
   else if (password) {
     int i;
@@ -199,7 +203,8 @@ int csu_dosuspenduser(void *source, int cargc, char **cargv) {
       }
     }
     
-    chanservwallmessage("%s (%s) bulk suspended password \"%s\", hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?expiresbuf:"never");
+    chanservwallmessage("%s (%s) bulk suspended password \"%s\", hit %d account/s (expires: %s), reason: %s", sender->nick, rup->username, victim, hitcount, expires?expiresbuf:"never", reason);
+    cs_log(sender, "SUSPENDUSER (bulk by password: %s, hit: %d) expires: %s, reason: %s", victim, hitcount, expires?expiresbuf:"never", reason);
   }
   else {
     if (!(vrup=findreguser(sender, victim)))
@@ -217,9 +222,9 @@ int csu_dosuspenduser(void *source, int cargc, char **cargv) {
     
     if (UHasStaffPriv(vrup)) {
       char buf[200];
-      snprintf(buf, sizeof(buf), "suspenduser on %s", vrup->username);
+      snprintf(buf, sizeof(buf), "suspenduser on %s (reason: %s)", vrup->username, reason);
       chanservstdmessage(sender, QM_NOACCESS, buf);
-      chanservwallmessage("%s (%s) FAILED to suspend %s", sender->nick, rup->username, vrup->username);
+      chanservwallmessage("%s (%s) FAILED to suspend %s (reason: %s)", sender->nick, rup->username, vrup->username, reason);
       return CMD_ERROR;
     }
     
@@ -234,7 +239,9 @@ int csu_dosuspenduser(void *source, int cargc, char **cargv) {
     vrup->suspendtime=time(NULL);
     vrup->suspendreason=getsstring(reason, strlen(reason)+1);
     
-    chanservwallmessage("%s (%s) %s %s (expires: %s)", sender->nick, rup->username, (gline)?((gline == 2)?"instantly glined":"delayed glined"):"suspended", vrup->username, expires?expiresbuf:"never");
+    chanservwallmessage("%s (%s) %s %s (expires: %s), reason: %s", sender->nick, rup->username, (gline)?((gline == 2)?"instantly glined":"delayed glined"):"suspended", vrup->username, expires?expiresbuf:"never", reason);
+    cs_log(sender, "SUSPENDUSER %s %s (expires: %s), reason: %s", (gline)?((gline == 2)?"instantly glined":"delayed glined"):"suspended", vrup->username, expires?expiresbuf:"never", reason);
+
     if (gline) {
       dgwait=(gline==2)?0:rand()%900;
       chanservsendmessage(sender, "Scheduling delayed GLINE for account %s in %d %s", 
index 846fc346cc9c01e47ea81e6c288448956077398d..f29b0ef67e72f86e89becac86bd7f7a74894bade 100644 (file)
@@ -3,11 +3,11 @@
  *
  * CMDNAME: unsuspenduser
  * CMDLEVEL: QCMD_OPER
- * CMDARGS: 1
+ * CMDARGS: 2
  * CMDDESC: Unsuspend a user.
  * CMDFUNC: csu_dounsuspenduser
  * CMDPROTO: int csu_dounsuspenduser(void *source, int cargc, char **cargv);
- * CMDHELP: Usage: unsuspenduser <username>
+ * CMDHELP: Usage: unsuspenduser <username> <reason>
  * CMDHELP: Unsuspends the specified user.
  */
 
 int csu_dounsuspenduser(void *source, int cargc, char **cargv) {
   nick *sender=source;
   reguser *rup=getreguserfromnick(sender);
-  reguser *vrup;
+  reguser *vrup, *suspendedby;
   char action[100];
+  char *csuspendedby, *csuspendreason;
+  char *unsuspendreason;
   
   if (!rup)
     return CMD_ERROR;
   
-  if (cargc < 1) {
+  if (cargc < 2) {
     chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspenduser");
     return CMD_ERROR;
   }
-  
+
+  unsuspendreason = cargv[1];
+  if(!checkreason(sender, unsuspendreason))
+    return CMD_ERROR;
+
   if (cargv[0][0] == '#') {
     if (!(vrup=findreguserbynick(&cargv[0][1]))) {
       chanservstdmessage(sender, QM_UNKNOWNUSER, &cargv[0][1]);
@@ -75,7 +81,14 @@ int csu_dounsuspenduser(void *source, int cargc, char **cargv) {
     chanservsendmessage(sender, "Unknown suspend type encountered.");
     return CMD_ERROR;
   }
-  
+
+  suspendedby = findreguserbyID(vrup->suspendby);
+  csuspendedby = suspendedby?suspendedby->username:"(unknown)";
+  csuspendreason = vrup->suspendreason?vrup->suspendreason->content:"(no reason)";
+
+  chanservwallmessage("%s (%s) %s %s (suspended by: %s, suspension reason: %s), unsuspension reason: %s", sender->nick, rup->username, action, vrup->username, csuspendedby, csuspendreason, unsuspendreason);
+  cs_log(sender,"UNSUSPENDUSER %s %s (suspended by: %s, suspension reason: %s), unsuspension reason: %s", action, vrup->username, csuspendedby, csuspendreason, unsuspendreason);
+
   vrup->flags&=(~(QUFLAG_GLINE|QUFLAG_DELAYEDGLINE|QUFLAG_SUSPENDED));
   vrup->suspendby=0;
   vrup->suspendexp=0;
@@ -83,7 +96,6 @@ int csu_dounsuspenduser(void *source, int cargc, char **cargv) {
   vrup->suspendreason=0;
   csdb_updateuser(vrup);
   
-  chanservwallmessage("%s (%s) %s %s", sender->nick, rup->username, action, vrup->username);
   chanservstdmessage(sender, QM_DONE);
   return CMD_OK;
 }