1 add opkick command, similar to opmode command, but then for kicking
2 priv controlled by LOCAL_OPMODE and OPMODE
3 feature controlled by OPKICK (disabled by default), new p10 token OK
4 if implemented, it must not be enabled until ALL servers and services are upgraded
5 generates HACK(4) snomask notice for accountability with oper as source
6 probably needs some work (for one i simply copied the header from m_kick.c)
8 diff -r a77bd3d09dec include/client.h
9 --- a/include/client.h Tue Feb 03 18:16:21 2009 +0100
10 +++ b/include/client.h Tue Feb 03 18:40:09 2009 +0100
12 PRIV_LOCAL_JUPE, /**< oper can local JUPE */
13 PRIV_OPMODE, /**< oper can OP/CLEARMODE */
14 PRIV_LOCAL_OPMODE, /**< oper can local OP/CLEARMODE */
15 + PRIV_OPKICK, /**< oper can OPKICK */
16 + PRIV_LOCAL_OPKICK, /**< oper can local OPKICK */
17 PRIV_SET, /**< oper can SET */
18 PRIV_WHOX, /**< oper can use /who x */
19 PRIV_BADCHAN, /**< oper can BADCHAN */
20 diff -r a77bd3d09dec include/handlers.h
21 --- a/include/handlers.h Tue Feb 03 18:16:21 2009 +0100
22 +++ b/include/handlers.h Tue Feb 03 18:40:09 2009 +0100
24 extern int mo_kill(struct Client*, struct Client*, int, char*[]);
25 extern int mo_notice(struct Client*, struct Client*, int, char*[]);
26 extern int mo_oper(struct Client*, struct Client*, int, char*[]);
27 +extern int mo_opkick(struct Client*, struct Client*, int, char*[]);
28 extern int mo_opmode(struct Client*, struct Client*, int, char*[]);
29 extern int mo_ping(struct Client*, struct Client*, int, char*[]);
30 extern int mo_privmsg(struct Client*, struct Client*, int, char*[]);
32 extern int ms_nick(struct Client*, struct Client*, int, char*[]);
33 extern int ms_notice(struct Client*, struct Client*, int, char*[]);
34 extern int ms_oper(struct Client*, struct Client*, int, char*[]);
35 +extern int ms_opkick(struct Client*, struct Client*, int, char*[]);
36 extern int ms_opmode(struct Client*, struct Client*, int, char*[]);
37 extern int ms_part(struct Client*, struct Client*, int, char*[]);
38 extern int ms_ping(struct Client*, struct Client*, int, char*[]);
39 diff -r a77bd3d09dec include/ircd_features.h
40 --- a/include/ircd_features.h Tue Feb 03 18:16:21 2009 +0100
41 +++ b/include/ircd_features.h Tue Feb 03 18:40:09 2009 +0100
43 /* features that affect all operators */
44 FEAT_EXTENDED_CHECKCMD,
50 diff -r a77bd3d09dec include/msg.h
51 --- a/include/msg.h Tue Feb 03 18:16:21 2009 +0100
52 +++ b/include/msg.h Tue Feb 03 18:40:09 2009 +0100
55 #define CMD_KICK MSG_KICK, TOK_KICK
57 +#define MSG_OPKICK "OPKICK" /* OPKICK */
58 +#define TOK_OPKICK "OK"
59 +#define CMD_OPKICK MSG_OPKICK, TOK_OPKICK
61 #define MSG_USERHOST "USERHOST" /* USER -> USRH */
62 #define TOK_USERHOST "USERHOST"
63 #define CMD_USERHOST MSG_USERHOST, TOK_USERHOST
64 diff -r a77bd3d09dec ircd/Makefile.in
65 --- a/ircd/Makefile.in Tue Feb 03 18:16:21 2009 +0100
66 +++ b/ircd/Makefile.in Tue Feb 03 18:40:09 2009 +0100
76 ../include/ircd_features.h ../include/s_conf.h ../include/client.h \
77 ../include/s_debug.h ../include/s_user.h ../include/s_misc.h \
79 +m_opkick.o: m_opkick.c ../config.h ../include/channel.h \
80 + ../include/ircd_defs.h ../include/res.h ../config.h ../include/client.h \
81 + ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
82 + ../include/ircd_handler.h ../include/capab.h ../include/hash.h \
83 + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
84 + ../include/ircd_reply.h ../include/ircd_string.h \
85 + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
86 + ../include/numnicks.h ../include/send.h ../include/ircd_features.h
87 m_opmode.o: m_opmode.c ../config.h ../include/client.h \
88 ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
89 ../include/ircd_events.h ../config.h ../include/ircd_handler.h \
90 diff -r a77bd3d09dec ircd/client.c
91 --- a/ircd/client.c Tue Feb 03 18:16:21 2009 +0100
92 +++ b/ircd/client.c Tue Feb 03 18:40:09 2009 +0100
94 FlagSet(&privs_local, PRIV_LOCAL_GLINE);
95 FlagSet(&privs_local, PRIV_LOCAL_JUPE);
96 FlagSet(&privs_local, PRIV_LOCAL_OPMODE);
97 + FlagSet(&privs_local, PRIV_LOCAL_OPKICK);
98 FlagSet(&privs_local, PRIV_WHOX);
99 FlagSet(&privs_local, PRIV_DISPLAY);
100 FlagSet(&privs_local, PRIV_FORCE_LOCAL_OPMODE);
102 ClrPriv(client, PRIV_GLINE);
103 ClrPriv(client, PRIV_JUPE);
104 ClrPriv(client, PRIV_OPMODE);
105 + ClrPriv(client, PRIV_OPKICK);
106 ClrPriv(client, PRIV_BADCHAN);
110 P(SHOW_INVIS), P(SHOW_ALL_INVIS), P(UNLIMIT_QUERY), P(KILL),
111 P(LOCAL_KILL), P(REHASH), P(RESTART), P(DIE),
112 P(GLINE), P(LOCAL_GLINE), P(JUPE), P(LOCAL_JUPE),
113 - P(OPMODE), P(LOCAL_OPMODE), P(SET), P(WHOX),
114 + P(OPMODE), P(LOCAL_OPMODE), P(OPKICK), P(LOCAL_OPKICK),
116 P(BADCHAN), P(LOCAL_BADCHAN), P(SEE_CHAN), P(PROPAGATE),
117 P(DISPLAY), P(SEE_OPERS), P(WIDE_GLINE), P(LIST_CHAN),
118 P(FORCE_OPMODE), P(FORCE_LOCAL_OPMODE), P(APASS_OPMODE),
119 diff -r a77bd3d09dec ircd/ircd_features.c
120 --- a/ircd/ircd_features.c Tue Feb 03 18:16:21 2009 +0100
121 +++ b/ircd/ircd_features.c Tue Feb 03 18:40:09 2009 +0100
123 /* features that affect all operators */
124 F_B(EXTENDED_CHECKCMD, 0, 0, 0),
125 F_B(CONFIG_OPERCMDS, 0, 0, 0),
126 + F_B(OPKICK, 0, 1, 0),
127 F_B(SETHOST, 0, 0, 0),
128 F_B(SETHOST_USER, 0, 0, 0),
129 F_B(SETHOST_AUTO, 0, 0, 0),
130 diff -r a77bd3d09dec ircd/ircd_lexer.l
131 --- a/ircd/ircd_lexer.l Tue Feb 03 18:16:21 2009 +0100
132 +++ b/ircd/ircd_lexer.l Tue Feb 03 18:40:09 2009 +0100
133 @@ -132,11 +132,13 @@
134 { "local_jupe", TPRIV_LOCAL_JUPE },
135 { "local_kill", TPRIV_LOCAL_KILL },
136 { "local_opmode", TPRIV_LOCAL_OPMODE },
137 + { "local_opkick", TPRIV_LOCAL_OPKICK },
139 { "megabytes", MBYTES },
140 { "mode_lchan", TPRIV_MODE_LCHAN },
141 { "operator", OPER },
142 { "opmode", TPRIV_OPMODE },
143 + { "opkick", TPRIV_OPKICK },
144 { "password", PASS },
145 { "propagate", TPRIV_PROPAGATE },
146 { "realname", REAL },
147 diff -r a77bd3d09dec ircd/ircd_parser.y
148 --- a/ircd/ircd_parser.y Tue Feb 03 18:16:21 2009 +0100
149 +++ b/ircd/ircd_parser.y Tue Feb 03 18:40:09 2009 +0100
151 %token TPRIV_CHAN_LIMIT TPRIV_MODE_LCHAN TPRIV_DEOP_LCHAN TPRIV_WALK_LCHAN
152 %token TPRIV_LOCAL_KILL TPRIV_REHASH TPRIV_RESTART TPRIV_DIE
153 %token TPRIV_GLINE TPRIV_LOCAL_GLINE TPRIV_LOCAL_JUPE TPRIV_LOCAL_BADCHAN
154 -%token TPRIV_LOCAL_OPMODE TPRIV_OPMODE TPRIV_SET TPRIV_WHOX TPRIV_BADCHAN
155 +%token TPRIV_LOCAL_OPMODE TPRIV_OPMODE TPRIV_LOCAL_OPKICK TPRIV_OPKICK
156 +%token TPRIV_SET TPRIV_WHOX TPRIV_BADCHAN
157 %token TPRIV_SEE_CHAN TPRIV_SHOW_INVIS TPRIV_SHOW_ALL_INVIS TPRIV_PROPAGATE
158 %token TPRIV_UNLIMIT_QUERY TPRIV_DISPLAY TPRIV_SEE_OPERS TPRIV_WIDE_GLINE
159 %token TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE TPRIV_APASS_OPMODE
161 TPRIV_LOCAL_JUPE { $$ = PRIV_LOCAL_JUPE; } |
162 TPRIV_LOCAL_OPMODE { $$ = PRIV_LOCAL_OPMODE; } |
163 TPRIV_OPMODE { $$ = PRIV_OPMODE; }|
164 + TPRIV_LOCAL_OPKICK { $$ = PRIV_LOCAL_OPKICK; }|
165 + TPRIV_OPKICK { $$ = PRIV_OPKICK; }|
166 TPRIV_SET { $$ = PRIV_SET; } |
167 TPRIV_WHOX { $$ = PRIV_WHOX; } |
168 TPRIV_BADCHAN { $$ = PRIV_BADCHAN; } |
169 diff -r a77bd3d09dec ircd/m_opkick.c
170 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
171 +++ b/ircd/m_opkick.c Tue Feb 03 18:40:09 2009 +0100
174 + * IRC - Internet Relay Chat, ircd/m_opkick.c
175 + * Copyright (C) 1990 Jarkko Oikarinen and
176 + * University of Oulu, Computing Center
178 + * See file AUTHORS in IRC package for additional names of
181 + * This program is free software; you can redistribute it and/or modify
182 + * it under the terms of the GNU General Public License as published by
183 + * the Free Software Foundation; either version 1, or (at your option)
184 + * any later version.
186 + * This program is distributed in the hope that it will be useful,
187 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
188 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
189 + * GNU General Public License for more details.
191 + * You should have received a copy of the GNU General Public License
192 + * along with this program; if not, write to the Free Software
193 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
198 + * m_functions execute protocol messages on this server:
200 + * cptr is always NON-NULL, pointing to a *LOCAL* client
201 + * structure (with an open socket connected!). This
202 + * identifies the physical socket where the message
203 + * originated (or which caused the m_function to be
204 + * executed--some m_functions may call others...).
206 + * sptr is the source of the message, defined by the
207 + * prefix part of the message if present. If not
208 + * or prefix not found, then sptr==cptr.
210 + * (!IsServer(cptr)) => (cptr == sptr), because
211 + * prefixes are taken *only* from servers...
214 + * (sptr == cptr) => the message didn't
217 + * (sptr != cptr && IsServer(sptr) means
218 + * the prefix specified servername. (?)
220 + * (sptr != cptr && !IsServer(sptr) means
221 + * that message originated from a remote
222 + * user (not local).
226 + * (!IsServer(sptr)) means that, sptr can safely
227 + * taken as defining the target structure of the
228 + * message in this server.
230 + * *Always* true (if 'parse' and others are working correct):
232 + * 1) sptr->from == cptr (note: cptr->from == cptr)
234 + * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr
235 + * *cannot* be a local connection, unless it's
236 + * actually cptr!). [MyConnect(x) should probably
237 + * be defined as (x == x->from) --msa ]
239 + * parc number of variable parameter strings (if zero,
240 + * parv is allowed to be NULL)
242 + * parv a NULL terminated list of parameter pointers,
244 + * parv[0], sender (prefix string), if not present
245 + * this points to an empty string.
246 + * parv[1]...parv[parc-1]
247 + * pointers to additional parameters
248 + * parv[parc] == NULL, *always*
250 + * note: it is guaranteed that parv[0]..parv[parc-1] are all
251 + * non-NULL pointers.
255 +#include "channel.h"
259 +#include "ircd_log.h"
260 +#include "ircd_reply.h"
261 +#include "ircd_string.h"
263 +#include "numeric.h"
264 +#include "numnicks.h"
266 +#include "ircd_features.h"
268 +/* #include <assert.h> -- Now using assert in ircd_log.h */
271 + * mo_opkick - oper message handler
273 + * parv[0] = sender prefix
274 + * parv[1] = channel
275 + * parv[2] = client to kick
276 + * parv[parc-1] = kick comment
278 +int mo_opkick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
280 + struct Client *who;
281 + struct Channel *chptr;
282 + struct Membership *member = 0;
283 + struct Membership* member2;
284 + char *name, *comment;
286 + ClrFlag(sptr, FLAG_TS8);
288 + if (!feature_bool(FEAT_OPKICK))
289 + return send_reply(sptr, ERR_DISABLED, "OPKICK");
291 + if (parc < 3 || *parv[1] == '\0')
292 + return need_more_params(sptr, "OPKICK");
296 + /* simple checks */
297 + if (!(chptr = get_channel(sptr, name, CGT_NO_CREATE)))
298 + return send_reply(sptr, ERR_NOSUCHCHANNEL, name);
300 + if (!HasPriv(sptr, IsLocalChannel(chptr->chname) ? PRIV_LOCAL_OPKICK : PRIV_OPKICK))
301 + return send_reply(sptr, ERR_NOPRIVILEGES);
303 + if (!(who = find_chasing(sptr, parv[2], 0, 1)))
304 + return 0; /* find_chasing sends the reply for us */
306 + /* Don't allow the channel service to be kicked */
307 + if (IsChannelService(who) && IsService(cli_user(who)->server))
308 + return send_reply(sptr, ERR_ISREALSERVICE, cli_name(who), chptr->chname);
310 + /* check if kicked user is actually on the channel */
311 + if (!(member = find_member_link(chptr, who)) || IsZombie(member))
312 + return send_reply(sptr, ERR_USERNOTINCHANNEL, cli_name(who), chptr->chname);
314 + /* We rely on ircd_snprintf to truncate the comment */
315 + comment = EmptyString(parv[parc - 1]) ? parv[2] : parv[parc - 1];
318 + if (!IsLocalChannel(name))
319 + sendcmdto_serv_butone(sptr, CMD_OPKICK, cptr, "%H %C :%s", chptr, who, comment);
321 + /* If it's a delayed join, only send the KICK to the person doing
322 + * the kicking and the victim
324 + if (IsDelayedJoin(member)) {
326 + sendcmdto_one(feature_bool(FEAT_HIS_MODEWHO) ? &his : sptr, CMD_KICK, who, "%H %C :%s", chptr, who, comment);
327 + /* operator using OPKICK is on the channel */
328 + if ((member2 = find_member_link(chptr, sptr)) && !IsZombie(member2)) {
329 + sendcmdto_one(who, CMD_JOIN, sptr, "%H", chptr);
330 + sendcmdto_one(feature_bool(FEAT_HIS_MODEWHO) ? &his : sptr, CMD_KICK, sptr, "%H %C :%s", chptr, who, comment);
332 + CheckDelayedJoins(chptr);
334 + sendcmdto_channel_butserv_butone(feature_bool(FEAT_HIS_MODEWHO) ? &his : sptr,
335 + CMD_KICK, chptr, NULL, 0, "%H %C :%s", chptr, who, comment);
337 + /* Send HACK notice and log it */
338 + sendto_opmask_butone(0, SNO_HACK4, "HACK(4): %C KICK %H %C %s", sptr, chptr, who, comment);
339 + log_write(LS_OPERMODE, L_INFO, LOG_NOSNOTICE, "%#C OPKICK %H %C %s", sptr, chptr, who, comment);
341 + make_zombie(member, who, cptr, sptr, chptr);
347 + * ms_opkick - server message handler
349 + * parv[0] = sender prefix
350 + * parv[1] = channel
351 + * parv[2] = client to kick
352 + * parv[parc-1] = kick comment
354 +int ms_opkick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
356 + struct Client *who;
357 + struct Channel *chptr;
358 + struct Membership *member = 0;
359 + char *name, *comment;
361 + ClrFlag(sptr, FLAG_TS8);
363 + if (parc < 3 || *parv[1] == '\0')
364 + return need_more_params(sptr, "OPKICK");
367 + comment = parv[parc - 1];
369 + /* figure out who gets kicked from what */
370 + if (IsLocalChannel(name) ||
371 + !(chptr = get_channel(sptr, name, CGT_NO_CREATE)) ||
372 + !(who = findNUser(parv[2])))
375 + /* We go ahead and pass on the KICK for users not on the channel */
376 + if (!(member = find_member_link(chptr, who)) || IsZombie(member)) {
378 + make_zombie(member, who, cptr, sptr, chptr);
383 + /* Propagate kick... */
384 + sendcmdto_serv_butone(sptr, CMD_OPKICK, cptr, "%H %C :%s", chptr, who, comment);
386 + if (member) { /* and tell the channel about it */
387 + if (IsDelayedJoin(member)) {
389 + sendcmdto_one((IsServer(sptr) || feature_bool(FEAT_HIS_MODEWHO)) ? &his : sptr,
390 + CMD_KICK, who, "%H %C :%s", chptr, who, comment);
392 + sendcmdto_channel_butserv_butone((IsServer(sptr) || feature_bool(FEAT_HIS_MODEWHO)) ? &his : sptr,
393 + CMD_KICK, chptr, NULL, 0, "%H %C :%s", chptr, who, comment);
396 + /* Send HACK notice and log it */
397 + sendto_opmask_butone(0, SNO_HACK4, "HACK(4): %C KICK %H %C %s", sptr, chptr, who, comment);
398 + log_write(LS_OPERMODE, L_INFO, LOG_NOSNOTICE, "%#C OPKICK %H %C %s", sptr, chptr, who, comment);
400 + make_zombie(member, who, cptr, sptr, chptr);
404 diff -r a77bd3d09dec ircd/parse.c
405 --- a/ircd/parse.c Tue Feb 03 18:16:21 2009 +0100
406 +++ b/ircd/parse.c Tue Feb 03 18:40:09 2009 +0100
408 0, MAXPARA, MFLG_SLOW, 0, NULL,
409 { m_unregistered, m_not_oper, m_check, m_check, m_ignore }
413 + * Add the command for OPKICK.
418 + 0, MAXPARA, MFLG_SLOW, 0, NULL,
419 + /* UNREG, CLIENT, SERVER, OPER, SERVICE */
420 + { m_unregistered, m_not_oper, ms_opkick, mo_opkick, m_ignore }
423 /* This command is an alias for QUIT during the unregistered part of
424 * of the server. This is because someone jumping via a broken web