keep in sync with OGN upstream (SVN-325)
[ircu2.10.12-pk.git] / ircd / m_kick.c
index c6595d4c639cff4e5c898df25e7bde0707b30416..447329a90bf94a11b68a86d87df0be2b550856cf 100644 (file)
@@ -124,7 +124,7 @@ int m_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
     return send_reply(sptr, ERR_NOSUCHCHANNEL, name);
 
   if (!(member2 = find_member_link(chptr, sptr)) || IsZombie(member2)
-      || (!IsChanOp(member2) && !(IsNetServ(sptr) && IsSecurityServ(sptr) && IsChannelService(sptr))))
+      || (!IsChanOpOrHalfOp(member2) && !(IsNetServ(sptr) && IsSecurityServ(sptr) && IsChannelService(sptr))))
     return send_reply(sptr, ERR_CHANOPRIVSNEEDED, name);
 
   if (!(who = find_chasing(sptr, parv[2], 0)))
@@ -141,6 +141,10 @@ int m_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   /* check if kicked user is actually on the channel */
   if (!(member = find_member_link(chptr, who)) || IsZombie(member) || (IsInvisibleJoin(member) && IsDelayedJoin(member)))
     return send_reply(sptr, ERR_USERNOTINCHANNEL, cli_name(who), chptr->chname);
+    
+  /* Don't allow oped users to be kicked by halfops */
+  if (IsChanOp(member) && !IsChanOp(member2) && who != sptr)
+    return send_reply(sptr, ERR_CHANOPRIVSNEEDED, name);
 
   /* Don't allow to kick member with a higher op-level,
    * or members with the same op-level unless both are MAXOPLEVEL.
@@ -167,9 +171,13 @@ int m_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
     sendcmdto_one(who, CMD_JOIN, sptr, "%H", chptr);
     sendcmdto_one(sptr, CMD_KICK, sptr, "%H %C :%s", chptr, who, comment);
     CheckDelayedJoins(chptr);
+  } else if((member->channel->mode.mode & MODE_AUDITORIUM) && !IsVoicedOrOpped(member)) {
+    /* send the kick to ops only. */
+    if (MyUser(who))
+      sendcmdto_one(sptr, CMD_KICK, who, "%H %C :%s", chptr, who, comment);
+    sendcmdto_channel_butserv_butone(sptr, CMD_KICK, chptr, NULL, SKIP_NONOPS, "%H %C :%s", chptr, who, comment);
   } else
-    sendcmdto_channel_butserv_butone(sptr, CMD_KICK, chptr, NULL, 0, "%H %C :%s", chptr, who,
-                                     comment);
+    sendcmdto_channel_butserv_butone(sptr, CMD_KICK, chptr, NULL, 0, "%H %C :%s", chptr, who, comment);
 
   make_zombie(member, who, cptr, sptr, chptr);
 
@@ -207,7 +215,7 @@ int ms_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 
   /* We go ahead and pass on the KICK for users not on the channel */
   member = find_member_link(chptr, who);
-  if((IsInvisibleJoin(member) && IsDelayedJoin(member))) 
+  if(member && (IsInvisibleJoin(member) && IsDelayedJoin(member))) 
     return 0;
   if (member && IsZombie(member))
   {
@@ -269,6 +277,11 @@ int ms_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
         if (MyUser(who))
           sendcmdto_one(IsServer(sptr) ? &his : sptr, CMD_KICK,
                         who, "%H %C :%s", chptr, who, comment);
+      }  else if((member->channel->mode.mode & MODE_AUDITORIUM) && !IsVoicedOrOpped(member)) {
+        /* send the kick to ops only. */
+        if (MyUser(who))
+          sendcmdto_one(IsServer(sptr) ? &his : sptr, CMD_KICK, who, "%H %C :%s", chptr, who, comment);
+        sendcmdto_channel_butserv_butone(IsServer(sptr) ? &his : sptr, CMD_KICK, chptr, NULL, SKIP_NONOPS, "%H %C :%s", chptr, who, comment);
       } else {
         sendcmdto_channel_butserv_butone(IsServer(sptr) ? &his : sptr, CMD_KICK,
                                          chptr, NULL, 0, "%H %C :%s", chptr, who,