Only allow current opers to WHOX.
[ircu2.10.12-pk.git] / ircd / m_who.c
index 6b277f1bcd41d5c2e06cfd82a5154dc84c88b238..49df47580c393399ab9e97ae91a50dced6cc19a6 100644 (file)
@@ -184,10 +184,11 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           continue;
         case 'x':
         case 'X':
-          bitsel |= WHOSELECT_EXTRA;
-          if (HasPriv(sptr, PRIV_WHOX))
-           log_write(LS_WHO, L_INFO, LOG_NOSNOTICE, "%#C WHO %s %s", sptr,
-                     (BadPtr(parv[3]) ? parv[1] : parv[3]), parv[2]);
+          if (HasPriv(sptr, PRIV_WHOX) && IsAnOper(sptr)) {
+              bitsel |= WHOSELECT_EXTRA;
+              log_write(LS_WHO, L_INFO, LOG_NOSNOTICE, "%#C WHO %s %s", sptr,
+                        (BadPtr(parv[3]) ? parv[1] : parv[3]), parv[2]);
+          }
           continue;
         case 'n':
         case 'N':
@@ -271,6 +272,10 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           case 'A':
             fields |= WHO_FIELD_ACC;
             break;
+          case 'o':
+          case 'O':
+            fields |= WHO_FIELD_OPL;
+            break;
           default:
             break;
         }
@@ -376,6 +381,8 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
         matchsel &= ~WHO_FIELD_UID;
       if ((minlen > HOSTLEN) || !(cset & NTL_IRCHN))
         matchsel &= ~WHO_FIELD_HOS;
+      if ((minlen > ACCOUNTLEN))
+        matchsel &= ~WHO_FIELD_ACC;
     }
 
     /* First of all loop through the clients in common channels */
@@ -409,7 +416,9 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
               || matchexec(cli_info(acptr), mymask, minlen))
               && ((!(matchsel & WHO_FIELD_NIP))
              || (HasHiddenHost(acptr) && !IsAnOper(sptr))
-              || !ipmask_check(&cli_ip(acptr), &imask, ibits)))
+              || !ipmask_check(&cli_ip(acptr), &imask, ibits))
+              && ((!(matchsel & WHO_FIELD_ACC))
+              || matchexec(cli_user(acptr)->account, mymask, minlen)))
             continue;
           if (!SHOW_MORE(sptr, counter))
             break;
@@ -445,7 +454,9 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
             || matchexec(cli_info(acptr), mymask, minlen))
             && ((!(matchsel & WHO_FIELD_NIP))
            || (HasHiddenHost(acptr) && !IsAnOper(sptr))
-            || !ipmask_check(&cli_ip(acptr), &imask, ibits)))
+            || !ipmask_check(&cli_ip(acptr), &imask, ibits))
+            && ((!(matchsel & WHO_FIELD_ACC))
+            || matchexec(cli_user(acptr)->account, mymask, minlen)))
           continue;
         if (!SHOW_MORE(sptr, counter))
           break;
@@ -456,11 +467,10 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   /* Make a clean mask suitable to be sent in the "end of" */
   if (mask && (p = strchr(mask, ' ')))
     *p = '\0';
-  send_reply(sptr, RPL_ENDOFWHO, BadPtr(mask) ? "*" : mask);
-
   /* Notify the user if we decided that his query was too long */
   if (counter < 0)
-    send_reply(sptr, ERR_QUERYTOOLONG, "WHO");
+    send_reply(sptr, ERR_QUERYTOOLONG, BadPtr(mask) ? "*" : mask);
+  send_reply(sptr, RPL_ENDOFWHO, BadPtr(mask) ? "*" : mask);
 
   return 0;
 }