X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/212380e3f42f585dc1ea927402252eb943f91f7b..2498a1b577ac3901abbff2612d3647f8aef038b7:/modules/core/m_kick.c diff --git a/modules/core/m_kick.c b/modules/core/m_kick.c index d475aaf..3029ca6 100644 --- a/modules/core/m_kick.c +++ b/modules/core/m_kick.c @@ -21,14 +21,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_kick.c 258 2005-09-21 23:57:17Z nenolod $ + * $Id: m_kick.c 3317 2007-03-28 23:17:06Z jilles $ */ #include "stdinc.h" -#include "tools.h" #include "channel.h" #include "client.h" -#include "irc_string.h" +#include "match.h" #include "ircd.h" #include "numeric.h" #include "send.h" @@ -38,6 +37,8 @@ #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 **); #define mg_kick { m_kick, 3 } @@ -49,11 +50,10 @@ struct Message kick_msgtab = { mapi_clist_av1 kick_clist[] = { &kick_msgtab, NULL }; -DECLARE_MODULE_AV1(kick, NULL, NULL, kick_clist, NULL, NULL, "$Revision: 258 $"); +DECLARE_MODULE_AV1(kick, NULL, NULL, kick_clist, NULL, NULL, "$Revision: 3317 $"); /* ** m_kick -** parv[0] = sender prefix ** parv[1] = channel ** parv[2] = client to kick ** parv[3] = kick comment @@ -68,16 +68,14 @@ 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); - comment = LOCAL_COPY((EmptyString(parv[3])) ? parv[2] : parv[3]); - if(strlen(comment) > (size_t) REASONLEN) - comment[REASONLEN] = '\0'; - *buf = '\0'; if((p = strchr(parv[1], ','))) *p = '\0'; @@ -91,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); @@ -102,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); @@ -145,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) @@ -163,6 +166,54 @@ 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_NOKICK) + { + sendto_one_numeric(source_p, ERR_NOKICK, + form_str(ERR_NOKICK), + chptr->chname); + 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; + + hookdata.client = source_p; + hookdata.chptr = chptr; + hookdata.target = who; + hookdata.approved = 1; + + call_hook(h_can_kick, &hookdata); + + if (!hookdata.approved) + return 0; + } + + comment = LOCAL_COPY((EmptyString(parv[3])) ? who->name : parv[3]); + 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 @@ -182,10 +233,13 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s KICK %s %s :%s", use_id(source_p), chptr->chname, use_id(who), comment); - sendto_server(client_p, chptr, NOCAPS, CAP_TS6, - ":%s KICK %s %s :%s", - source_p->name, chptr->chname, who->name, 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,