]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/core/m_kick.c
Fix some valgrind warnings.
[irc/rqf/shadowircd.git] / modules / core / m_kick.c
index 841485f871b912ebae3d8fe79c9598b8c4518859..3029ca6f0de72b315e50a3d84ccb37310f062f12 100644 (file)
@@ -37,6 +37,7 @@
 #include "hash.h"
 #include "packet.h"
 #include "s_serv.h"
+#include "s_conf.h"
 #include "hook.h"
 
 static int m_kick(struct Client *, struct Client *, int, const char **);
@@ -67,8 +68,10 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
        char *comment;
        const char *name;
        char *p = NULL;
+       char text[10];
        const char *user;
        static char buf[BUFSIZE];
+       int is_override = 0;
 
        if(MyClient(source_p) && !IsFloodDone(source_p))
                flood_endgrace(source_p);
@@ -86,6 +89,13 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
                return 0;
        }
 
+       user = parv[2];         /* strtoken(&p2, parv[2], ","); */
+
+       if(!(who = find_chasing(source_p, user, &chasing)))
+       {
+               return 0;
+       }
+
        if(!IsServer(source_p))
        {
                msptr = find_channel_membership(chptr, source_p);
@@ -97,17 +107,22 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
                        return 0;
                }
 
-               if(!is_chanop(msptr))
+               if(!can_kick_deop(msptr, find_channel_membership(chptr, who)))
                {
                        if(MyConnect(source_p))
                        {
-                               sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
-                                          me.name, source_p->name, name);
-                               return 0;
+                               if(IsOverride(source_p))
+                                       is_override = 1;
+                               else
+                               {
+                                       sendto_one(source_p, ":%s 482 %s %s :You do not have the proper privledges to kick this user",
+                                                       me.name, source_p->name, name);
+                                       return 0;
+                               }
                        }
 
                        /* If its a TS 0 channel, do it the old way */
-                       if(chptr->channelts == 0)
+                       else if(chptr->channelts == 0)
                        {
                                sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                                           get_id(&me, source_p), get_id(source_p, source_p), name);
@@ -140,13 +155,6 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
        if((p = strchr(parv[2], ',')))
                *p = '\0';
 
-       user = parv[2];         /* strtoken(&p2, parv[2], ","); */
-
-       if(!(who = find_chasing(source_p, user, &chasing)))
-       {
-               return 0;
-       }
-
        msptr = find_channel_membership(chptr, who);
 
        if(msptr != NULL)
@@ -166,6 +174,17 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
                        return 0;
                }
 
+               if (MyClient(source_p) && chptr->mode.mode & MODE_NOOPERKICK && IsOper(who))
+               {
+                       sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+                                       "Overriding KICK from %s on %s in %s (channel is +M)",
+                                       source_p->name, who->name, chptr->chname);
+                       sendto_one_numeric(source_p, ERR_ISCHANSERVICE,
+                                       "%s %s :Cannot kick IRC operators from that channel.",
+                                       who->name, chptr->chname);
+                       return 0;
+               }
+
                if(MyClient(source_p))
                {
                        hook_data_channel_approval hookdata;
@@ -185,6 +204,16 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
                if(strlen(comment) > (size_t) REASONLEN)
                        comment[REASONLEN] = '\0';
 
+               if(is_override)
+               {
+                       sendto_wallops_flags(UMODE_WALLOP, &me,
+                                       "%s is overriding KICK [%s] on [%s] [%s]",
+                                       get_oper_name(source_p), who->name, chptr->chname, comment);
+                       sendto_server(NULL, chptr, NOCAPS, NOCAPS,
+                                       ":%s WALLOPS :%s is overriding KICK [%s] on [%s] [%s]",
+                                       me.name, get_oper_name(source_p), who->name, chptr->chname, comment);
+               }
+
                /* jdc
                 * - In the case of a server kicking a user (i.e. CLEARCHAN),
                 *   the kick should show up as coming from the server which did
@@ -205,6 +234,12 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
                              ":%s KICK %s %s :%s",
                              use_id(source_p), chptr->chname, use_id(who), comment);
                remove_user_from_channel(msptr);
+
+               rb_snprintf(text, sizeof(text), "K%s", who->id);
+
+               /* we don't need to track NOREJOIN stuff unless it's our client being kicked */
+               if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN)
+                       channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN");
        }
        else if (MyClient(source_p))
                sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,