diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index d774e576..0f25a190 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -251,16 +251,20 @@ Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Rea } /* Channel_Part */ -/* Kick user from Channel */ +/** + * Kick user from Channel + */ GLOBAL void -Channel_Kick( CLIENT *Client, CLIENT *Origin, const char *Name, const char *Reason ) +Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name, + const char *Reason ) { CHANNEL *chan; - assert( Client != NULL ); - assert( Origin != NULL ); - assert( Name != NULL ); - assert( Reason != NULL ); + assert(Peer != NULL); + assert(Target != NULL); + assert(Origin != NULL); + assert(Name != NULL); + assert(Reason != NULL); /* Check that channel exists */ chan = Channel_Search( Name ); @@ -270,29 +274,32 @@ Channel_Kick( CLIENT *Client, CLIENT *Origin, const char *Name, const char *Reas return; } - /* Check that user is on the specified channel */ - if( ! Channel_IsMemberOf( chan, Origin )) - { - IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Name ); - return; - } + if (Client_Type(Peer) != CLIENT_SERVER && + Client_Type(Origin) != CLIENT_SERVICE) { + /* Check that user is on the specified channel */ + if (!Channel_IsMemberOf(chan, Origin)) { + IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, + Client_ID(Origin), Name); + return; + } - /* Check if user has operator status */ - if( ! strchr( Channel_UserModes( chan, Origin ), 'o' )) - { - IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Name); - return; + /* Check if user has operator status */ + if (!strchr(Channel_UserModes(chan, Origin), 'o')) { + IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, + Client_ID(Origin), Name); + return; + } } /* Check that the client to be kicked is on the specified channel */ - if( ! Channel_IsMemberOf( chan, Client )) - { - IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( Client ), Name ); + if (!Channel_IsMemberOf(chan, Target)) { + IRC_WriteStrClient(Origin, ERR_USERNOTINCHANNEL_MSG, + Client_ID(Origin), Client_ID(Target), Name ); return; } /* Kick Client from channel */ - Remove_Client( REMOVE_KICK, chan, Client, Origin, Reason, true); + Remove_Client( REMOVE_KICK, chan, Target, Origin, Reason, true); } /* Channel_Kick */ diff --git a/src/ngircd/channel.h b/src/ngircd/channel.h index a562645c..792f2692 100644 --- a/src/ngircd/channel.h +++ b/src/ngircd/channel.h @@ -66,7 +66,8 @@ GLOBAL bool Channel_Part PARAMS(( CLIENT *Client, CLIENT *Origin, const char *Na GLOBAL void Channel_Quit PARAMS(( CLIENT *Client, char *Reason )); -GLOBAL void Channel_Kick PARAMS(( CLIENT *Client, CLIENT *Origin, const char *Name, const char *Reason )); +GLOBAL void Channel_Kick PARAMS((CLIENT *Peer, CLIENT *Target, CLIENT *Origin, + const char *Name, const char *Reason)); GLOBAL unsigned long Channel_Count PARAMS(( void )); GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan )); diff --git a/src/ngircd/irc-op.c b/src/ngircd/irc-op.c index f1ebc792..6cd01049 100644 --- a/src/ngircd/irc-op.c +++ b/src/ngircd/irc-op.c @@ -34,14 +34,15 @@ static bool -try_kick(CLIENT* from, const char *nick, const char *channel, const char *reason) +try_kick(CLIENT *peer, CLIENT* from, const char *nick, const char *channel, + const char *reason) { CLIENT *target = Client_Search(nick); if (!target) return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG, Client_ID(from), nick); - Channel_Kick(target, from, channel, reason); + Channel_Kick(peer, target, from, channel, reason); return true; } @@ -93,7 +94,8 @@ IRC_KICK(CLIENT *Client, REQUEST *Req) currentChannel = Req->argv[0]; if (channelCount == 1) { while (nickCount > 0) { - if (!try_kick(from, currentNick, currentChannel, reason)) + if (!try_kick(Client, from, currentNick, + currentChannel, reason)) return false; while (*currentNick) @@ -104,7 +106,8 @@ IRC_KICK(CLIENT *Client, REQUEST *Req) } } else if (channelCount == nickCount) { while (nickCount > 0) { - if (!try_kick(from, currentNick, currentChannel, reason)) + if (!try_kick(Client, from, currentNick, + currentChannel, reason)) return false; while (*currentNick)