Author: Kev <klmitch@mit.edu>
[ircu2.10.12-pk.git] / ircd / s_user.c
index ea7b01fa3596d9ca273b651a5600b4d653add9c2..bd732904fff7565fc1519cb32e8f5e71b2fe864b 100644 (file)
@@ -32,7 +32,9 @@
 #include "ircd.h"
 #include "ircd_alloc.h"
 #include "ircd_chattr.h"
+#include "ircd_features.h"
 #include "ircd_log.h"
+#include "ircd_policy.h"
 #include "ircd_reply.h"
 #include "ircd_string.h"
 #include "list.h"
@@ -129,50 +131,6 @@ void user_count_memory(size_t* count_out, size_t* bytes_out)
   *bytes_out = userCount * sizeof(struct User);
 }
 
-/*
- * user_set_away - set user away state
- * returns 1 if client is away or changed away message, 0 if 
- * client is removing away status.
- * NOTE: this function may modify user and message, so they
- * must be mutable.
- */
-int user_set_away(struct User* user, char* message)
-{
-  char* away;
-  assert(0 != user);
-
-  away = user->away;
-
-  if (EmptyString(message)) {
-    /*
-     * Marking as not away
-     */
-    if (away) {
-      MyFree(away);
-      user->away = 0;
-    }
-  }
-  else {
-    /*
-     * Marking as away
-     */
-    unsigned int len = strlen(message);
-
-    if (len > TOPICLEN) {
-      message[TOPICLEN] = '\0';
-      len = TOPICLEN;
-    }
-    if (away)
-      away = (char*) MyRealloc(away, len + 1);
-    else
-      away = (char*) MyMalloc(len + 1);
-    assert(0 != away);
-
-    user->away = away;
-    strcpy(away, message);
-  }
-  return (user->away != 0);
-}
 
 /*
  * next_client
@@ -405,8 +363,8 @@ int register_user(struct Client *cptr, struct Client *sptr,
         {
           last_too_many1 = CurrentTime;
           sendto_opmask_butone(0, SNO_TOOMANY, "Too many connections in "
-                               "class for %s.",
-                               get_client_name(sptr, HIDE_IP));
+                               "class %i for %s.", get_client_class(sptr),
+                               get_client_name(sptr, SHOW_IP));
         }
         ++ServerStats->is_ref;
         IPcheck_connect_fail(cli_ip(sptr));
@@ -419,7 +377,7 @@ int register_user(struct Client *cptr, struct Client *sptr,
           last_too_many2 = CurrentTime;
           sendto_opmask_butone(0, SNO_TOOMANY, "Too many connections from "
                                "same IP for %s.",
-                               get_client_name(sptr, HIDE_IP));
+                               get_client_name(sptr, SHOW_IP));
         }
         ++ServerStats->is_ref;
         return exit_client(cptr, sptr, &me,
@@ -696,6 +654,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
         }
       }
     }
+    client_set_privs(new_client); /* set privs on user */
     /*
      * Set new nick name.
      */
@@ -1000,12 +959,13 @@ int whisper(struct Client* source, const char* nick, const char* channel,
 /*
  * added Sat Jul 25 07:30:42 EST 1992
  */
-void send_umode_out(struct Client *cptr, struct Client *sptr, int old)
+void send_umode_out(struct Client *cptr, struct Client *sptr, int old,
+                   int prop)
 {
   int i;
   struct Client *acptr;
 
-  send_umode(NULL, sptr, old, SEND_UMODES);
+  send_umode(NULL, sptr, old, SEND_UMODES & ~(prop ? 0 : FLAGS_OPER));
 
   for (i = HighestFd; i >= 0; i--) {
     if ((acptr = LocalClientArray[i]) && IsServer(acptr) &&
@@ -1069,6 +1029,7 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
   unsigned int tmpmask = 0;
   int snomask_given = 0;
   char buf[BUFSIZE];
+  int prop = 0;
 
   what = MODE_ADD;
 
@@ -1141,9 +1102,9 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
           tmpmask = (what == MODE_ADD) ?
               (IsAnOper(sptr) ? SNO_OPERDEFAULT : SNO_DEFAULT) : 0;
         if (tmpmask)
-          cli_flags(sptr) |= FLAGS_SERVNOTICE;
+         SetServNotice(sptr);
         else
-          cli_flags(sptr) &= ~FLAGS_SERVNOTICE;
+         ClearServNotice(sptr);
         break;
       case 'w':
         if (what == MODE_ADD)
@@ -1217,36 +1178,53 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
      */
     if (!(setflags & FLAGS_CHSERV))
       ClearChannelService(sptr);
-#ifdef WALLOPS_OPER_ONLY
     /*
      * only send wallops to opers
      */
-    if (!IsAnOper(sptr) && !(setflags & FLAGS_WALLOP))
+    if (feature_bool(FEAT_WALLOPS_OPER_ONLY) && !IsAnOper(sptr) &&
+       !(setflags & FLAGS_WALLOP))
       ClearWallops(sptr);
+#ifdef SERVNOTICE_OPER_ONLY
+    if (MyConnect(sptr) && !IsAnOper(sptr) && !(setflags & FLAGS_SERVNOTICE)) {
+      ClearServNotice(sptr);
+      set_snomask(sptr, 0, SNO_SET);
+    }
+#endif
+#ifdef DEBUG_OPER_ONLY
+    if (!IsAnOper(sptr) && !(setflags & FLAGS_DEBUG))
+      ClearDebug(sptr);
 #endif
   }
   if (MyConnect(sptr)) {
     if ((setflags & (FLAGS_OPER | FLAGS_LOCOP)) && !IsAnOper(sptr))
       det_confs_butmask(sptr, CONF_CLIENT & ~CONF_OPS);
 
-    if (tmpmask != cli_snomask(sptr))
-      set_snomask(sptr, tmpmask, SNO_SET);
-    if (cli_snomask(sptr) && snomask_given)
-      send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
+    if (SendServNotice(sptr)) {
+      if (tmpmask != cli_snomask(sptr))
+       set_snomask(sptr, tmpmask, SNO_SET);
+      if (cli_snomask(sptr) && snomask_given)
+       send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
+    }
   }
   /*
    * Compare new flags with old flags and send string which
    * will cause servers to update correctly.
    */
-  if ((setflags & FLAGS_OPER) && !IsOper(sptr))
-    --UserStats.opers;
-  if (!(setflags & FLAGS_OPER) && IsOper(sptr))
+  if (!(setflags & FLAGS_OPER) && IsOper(sptr)) { /* user now oper */
     ++UserStats.opers;
+    client_set_privs(sptr); /* may set propagate privilege */
+  }
+  if (HasPriv(sptr, PRIV_PROPAGATE)) /* remember propagate privilege setting */
+    prop = 1;
+  if ((setflags & FLAGS_OPER) && !IsOper(sptr)) { /* user no longer oper */
+    --UserStats.opers;
+    client_set_privs(sptr); /* will clear propagate privilege */
+  }
   if ((setflags & FLAGS_INVISIBLE) && !IsInvisible(sptr))
     --UserStats.inv_clients;
   if (!(setflags & FLAGS_INVISIBLE) && IsInvisible(sptr))
     ++UserStats.inv_clients;
-  send_umode_out(cptr, sptr, setflags);
+  send_umode_out(cptr, sptr, setflags, prop);
 
   return 0;
 }
@@ -1261,7 +1239,11 @@ char *umode_str(struct Client *cptr)
   int   i;
   int   c_flags;
 
-  c_flags = cli_flags(cptr) & SEND_UMODES;        /* cleaning up the original code */
+  c_flags = cli_flags(cptr) & SEND_UMODES; /* cleaning up the original code */
+  if (HasPriv(cptr, PRIV_PROPAGATE))
+    c_flags |= FLAGS_OPER;
+  else
+    c_flags &= ~FLAGS_OPER;
 
   for (i = 0; i < USERMODELIST_SIZE; ++i) {
     if ( (c_flags & userModeList[i].flag))
@@ -1519,7 +1501,8 @@ int add_silence(struct Client* sptr, const char* mask)
     if (MyUser(sptr))
     {
       len += strlen(lp->value.cp);
-      if ((len > MAXSILELENGTH) || (++cnt >= MAXSILES))
+      if ((len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXSILES))) ||
+         (++cnt >= feature_int(FEAT_MAXSILES)))
       {
         send_reply(sptr, ERR_SILELISTFULL, mask);
         return -1;