don't allow users to change their nick if the new nick is banned in a channel the...
authorpk910 <philipp@zoelle1.de>
Tue, 1 Nov 2011 19:25:44 +0000 (20:25 +0100)
committerpk910 <philipp@zoelle1.de>
Tue, 1 Nov 2011 19:25:44 +0000 (20:25 +0100)
include/channel.h
ircd/channel.c
ircd/s_user.c

index 50547c2922f1ae6acf834d5a68b19c37472e9648..32bea51e352f386a1c90396357599d99c8965cc0 100644 (file)
@@ -413,7 +413,7 @@ extern struct Client* find_chasing(struct Client* sptr, const char* user, int* c
 void add_invite(struct Client *cptr, struct Channel *chptr);
 int number_of_zombies(struct Channel *chptr);
 
-extern const char* find_no_nickchange_channel(struct Client* cptr);
+extern const char* find_no_nickchange_channel(struct Client* cptr, const char* new_nick);
 extern struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr);
 extern int member_can_send_to_channel(struct Membership* member, int reveal);
 extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal);
index 30b9f1de6d3864cf78b71756416c9190184b3d81..868a82f052c7d94496dff10b62c2815dafd3d239 100644 (file)
@@ -374,7 +374,7 @@ struct Membership* find_channel_member(struct Client* cptr, struct Channel* chpt
  * @param[in] banlist The list of bans to test.
  * @return Pointer to a matching ban, or NULL if none exit.
  */
-struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
+static struct Ban *find_ban_with_nick(struct Client *cptr, const char *nick, struct Ban *banlist)
 {
   char        nu[NICKLEN + USERLEN + 2];
   char        tmphost[HOSTLEN + 1];
@@ -386,7 +386,7 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
 
   /* Build nick!user and alternate host names. */
   ircd_snprintf(0, nu, sizeof(nu), "%s!%s",
-                cli_name(cptr), cli_user(cptr)->username);
+                (nick ? nick : cli_name(cptr)), cli_user(cptr)->username);
   ircd_ntoa_r(iphost, &cli_ip(cptr));
 
   /* Check for all three possible hosts:
@@ -439,6 +439,10 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
   return found;
 }
 
+struct Ban *find_ban(struct Client *cptr, struct Ban *banlist) {
+    return find_ban_with_nick(cptr, NULL, banlist);
+}
+
 /**
  * This function returns true if the user is banned on the said channel.
  * This function will check the ban cache if applicable, otherwise will
@@ -462,6 +466,13 @@ static int is_banned(struct Membership* member)
   }
 }
 
+static int is_banned_with_nick(struct Membership* member, const char *nick) {
+  if (find_ban_with_nick(member->user, nick, member->channel->banlist))
+    return 1;
+  else
+    return 0;
+}
+
 /** add a user to a channel.
  * adds a user to a channel by adding another link to the channels member
  * chain.
@@ -796,11 +807,12 @@ int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int r
  * the name of the first channel banned on.
  *
  * @param cptr         The client
+ * @param new_nick The new nick of the client
  *
  * @returns the name of the first channel banned on, or NULL if the user
  *          can change nicks.
  */
-const char* find_no_nickchange_channel(struct Client* cptr)
+const char* find_no_nickchange_channel(struct Client* cptr, const char *new_nick)
 {
   if (MyUser(cptr)) {
     struct Membership* member;
@@ -810,7 +822,7 @@ const char* find_no_nickchange_channel(struct Client* cptr)
         continue;
       if ((member->channel->mode.mode & MODE_MODERATED)
           || (member->channel->mode.mode & MODE_REGONLY && !IsAccount(cptr))
-          || is_banned(member))
+          || is_banned(member) || (new_nick && is_banned_with_nick(member, new_nick)))
         return member->channel->chname;
     }
   }
index c10eb72360d8b152f0241489e197f3346f2bbb77..942c44c96a7b291db160290f3d67164bb82f014d 100644 (file)
@@ -667,7 +667,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
     if (MyUser(sptr)) {
       const char* channel_name;
       struct Membership *member;
-      if (!force && !IsXtraOp(sptr) && (channel_name = find_no_nickchange_channel(sptr))) {
+      if (!force && !IsXtraOp(sptr) && (channel_name = find_no_nickchange_channel(sptr, nick))) {
         return send_reply(cptr, ERR_BANNICKCHANGE, channel_name);
       }
       /*