ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/core/m_kill.c
Revision: 33
Committed: Sun Oct 2 20:50:00 2005 UTC (18 years, 5 months ago) by knight
Content type: text/x-csrc
Original Path: ircd-hybrid/modules/core/m_kill.c
File size: 10652 byte(s)
Log Message:
- svn:keywords

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_kill.c: Kills a user.
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "handlers.h"
27     #include "client.h"
28     #include "hash.h" /* for find_client() */
29     #include "ircd.h"
30     #include "numeric.h"
31     #include "s_log.h"
32     #include "s_serv.h"
33     #include "s_conf.h"
34     #include "send.h"
35     #include "whowas.h"
36     #include "irc_string.h"
37     #include "sprintf_irc.h"
38     #include "msg.h"
39     #include "parse.h"
40     #include "modules.h"
41    
42    
43     static char buf[IRCD_BUFSIZE];
44    
45     static void ms_kill(struct Client *, struct Client *, int, char *[]);
46     static void mo_kill(struct Client *, struct Client *, int, char *[]);
47     static void relay_kill(struct Client *, struct Client *, struct Client *,
48     const char *, const char *);
49    
50     struct Message kill_msgtab = {
51     "KILL", 0, 0, 2, 0, MFLG_SLOW, 0,
52     {m_unregistered, m_not_oper, ms_kill, m_ignore, mo_kill, m_ignore}
53     };
54    
55     #ifndef STATIC_MODULES
56     void
57     _modinit(void)
58     {
59     mod_add_cmd(&kill_msgtab);
60     }
61    
62     void
63     _moddeinit(void)
64     {
65     mod_del_cmd(&kill_msgtab);
66     }
67    
68 knight 31 const char *_version = "$Revision$";
69 adx 30 #endif
70    
71     /* mo_kill()
72     * parv[0] = sender prefix
73     * parv[1] = kill victim
74     * parv[2] = kill path
75     */
76     static void
77     mo_kill(struct Client *client_p, struct Client *source_p,
78     int parc, char *parv[])
79     {
80     struct Client *target_p;
81     const char *inpath = client_p->name;
82     char *user;
83     char *reason;
84     char def_reason[] = "No reason";
85    
86     user = parv[1];
87     reason = parv[2]; /* Either defined or NULL (parc >= 2!!) */
88    
89     if (*user == '\0')
90     {
91     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
92     me.name, source_p->name, "KILL");
93     return;
94     }
95    
96     if (IsDigit(*user)) /* opers shouldn't be trying uids anyway ;-) */
97     return;
98    
99     if (!IsOperK(source_p) && !IsOperGlobalKill(source_p))
100     {
101     sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
102     me.name, source_p->name);
103     return;
104     }
105    
106     if (!EmptyString(reason))
107     {
108     if (strlen(reason) > (size_t)KILLLEN)
109     reason[KILLLEN] = '\0';
110     }
111     else
112     reason = def_reason;
113    
114     if ((target_p = find_client(user)) == NULL)
115     {
116     /* If the user has recently changed nick, automatically
117     * rewrite the KILL for this new nickname--this keeps
118     * servers in synch when nick change and kill collide
119     */
120     if ((target_p = get_history(user,
121     (time_t)ConfigFileEntry.kill_chase_time_limit))
122     == NULL)
123     {
124     sendto_one(source_p, form_str(ERR_NOSUCHNICK),
125     me.name, source_p->name, user);
126     return;
127     }
128    
129     sendto_one(source_p, ":%s NOTICE %s :KILL changed from %s to %s",
130     me.name, source_p->name, user, target_p->name);
131     }
132    
133     if (IsServer(target_p) || IsMe(target_p))
134     {
135     sendto_one(source_p, form_str(ERR_CANTKILLSERVER),
136     me.name, source_p->name);
137     return;
138     }
139    
140     if (!MyConnect(target_p) && (!IsOperGlobalKill(source_p)))
141     {
142     sendto_one(source_p, ":%s NOTICE %s :Nick %s isnt on your server",
143     me.name, source_p->name, target_p->name);
144     return;
145     }
146    
147     if (MyConnect(target_p))
148     sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
149     source_p->name, source_p->username, source_p->host,
150     target_p->name, reason);
151    
152     /* Do not change the format of this message. There's no point in changing messages
153     * that have been around for ever, for no reason.. */
154     sendto_realops_flags(UMODE_ALL, L_ALL,
155     "Received KILL message for %s. From %s Path: %s (%s)",
156     target_p->name, source_p->name, me.name, reason);
157    
158     ilog(L_INFO, "KILL From %s For %s Path %s (%s)",
159     source_p->name, target_p->name, me.name, reason);
160     log_oper_action(LOG_KILL_TYPE, source_p, "%s %s\n",
161     me.name, reason);
162    
163     /*
164     ** And pass on the message to other servers. Note, that if KILL
165     ** was changed, the message has to be sent to all links, also
166     ** back.
167     ** Suicide kills are NOT passed on --SRB
168     */
169     if (!MyConnect(target_p))
170     {
171     relay_kill(client_p, source_p, target_p, inpath, reason);
172     /*
173     ** Set FLAGS_KILLED. This prevents exit_one_client from sending
174     ** the unnecessary QUIT for this. (This flag should never be
175     ** set in any other place)
176     */
177     SetKilled(target_p);
178     }
179    
180     ircsprintf(buf, "Killed (%s (%s))", source_p->name, reason);
181     exit_client(target_p, source_p, buf);
182     }
183    
184     /* ms_kill()
185     * parv[0] = sender prefix
186     * parv[1] = kill victim
187     * parv[2] = kill path and reason
188     */
189     static void
190     ms_kill(struct Client *client_p, struct Client *source_p,
191     int parc, char *parv[])
192     {
193     struct Client *target_p;
194     char *user;
195     char *reason;
196     const char *path;
197     char def_reason[] = "No reason";
198    
199     if (*parv[1] == '\0')
200     {
201     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
202     me.name, source_p->name, "KILL");
203     return;
204     }
205    
206     user = parv[1];
207    
208     if (EmptyString(parv[2]))
209     {
210     reason = def_reason;
211    
212     /* hyb6 takes the nick of the killer from the path *sigh* --fl_ */
213     path = source_p->name;
214     }
215     else
216     {
217     reason = strchr(parv[2], ' ');
218    
219     if (reason != NULL)
220     *reason++ = '\0';
221     else
222     reason = def_reason;
223    
224     path = parv[2];
225     }
226    
227     if ((target_p = find_person(client_p, user)) == NULL)
228     {
229     /* If the user has recently changed nick, but only if its
230     * not an uid, automatically rewrite the KILL for this new nickname.
231     * --this keeps servers in synch when nick change and kill collide
232     */
233     if(IsDigit(*user)) /* Somehow an uid was not found in the hash ! */
234     return;
235     if((target_p = get_history(user,
236     (time_t)ConfigFileEntry.kill_chase_time_limit))
237     == NULL)
238     {
239     sendto_one(source_p, form_str(ERR_NOSUCHNICK),
240     me.name, source_p->name, user);
241     return;
242     }
243     sendto_one(source_p,":%s NOTICE %s :KILL changed from %s to %s",
244     me.name, source_p->name, user, target_p->name);
245     }
246    
247     if (IsServer(target_p) || IsMe(target_p))
248     {
249     sendto_one(source_p, form_str(ERR_CANTKILLSERVER),
250     me.name, source_p->name);
251     return;
252     }
253    
254     if (MyConnect(target_p))
255     {
256     if (IsServer(source_p))
257     {
258     /* dont send clients kills from a hidden server */
259     if ((IsHidden(source_p) || ConfigServerHide.hide_servers) && !IsOper(target_p))
260     sendto_one(target_p, ":%s KILL %s :%s",
261     me.name, target_p->name, reason);
262     else
263     sendto_one(target_p, ":%s KILL %s :%s",
264     source_p->name, target_p->name, reason);
265     }
266     else
267     sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
268     source_p->name, source_p->username, source_p->host,
269     target_p->name, reason);
270     }
271    
272     /* Be warned, this message must be From %s, or it confuses clients
273     * so dont change it to From: or the case or anything! -- fl -- db */
274     /* path must contain at least 2 !'s, or bitchx falsely declares it
275     * local --fl
276     */
277     if (IsOper(source_p)) /* send it normally */
278     {
279     sendto_realops_flags(UMODE_ALL, L_ALL,
280     "Received KILL message for %s. From %s Path: %s!%s!%s!%s %s",
281     target_p->name, source_p->name, source_p->servptr->name,
282     source_p->host, source_p->username, source_p->name, reason);
283     }
284     else
285     {
286     sendto_realops_flags(UMODE_SKILL, L_ALL,
287     "Received KILL message for %s. From %s %s",
288     target_p->name, source_p->name, reason);
289     }
290    
291     ilog(L_INFO,"KILL From %s For %s Path %s %s",
292     source_p->name, target_p->name, source_p->name, reason);
293    
294     relay_kill(client_p, source_p, target_p, path, reason);
295     SetKilled(target_p);
296    
297     /* reason comes supplied with its own ()'s */
298     if (IsServer(source_p) && (IsHidden(source_p) || ConfigServerHide.hide_servers))
299     ircsprintf(buf, "Killed (%s %s)", me.name, reason);
300     else
301     ircsprintf(buf, "Killed (%s %s)", source_p->name, reason);
302    
303     exit_client(target_p, source_p, buf);
304     }
305    
306     static void
307     relay_kill(struct Client *one, struct Client *source_p,
308     struct Client *target_p, const char *inpath, const char *reason)
309     {
310     dlink_node *ptr;
311     struct Client *client_p;
312     int introduce_killed_client;
313     const char *from, *to;
314    
315     /* LazyLinks:
316     * Check if each lazylink knows about target_p.
317     * If it does, send the kill, introducing source_p if required.
318     * If it doesn't either:
319     * a) don't send the kill (risk ghosts)
320     * b) introduce the client (and source_p, if required)
321     * [rather redundant]
322     *
323     * Use a) if IsServer(source_p), but if an oper kills someone,
324     * ensure we blow away any ghosts.
325     *
326     * -davidt
327     */
328    
329     if (IsServer(source_p))
330     introduce_killed_client = 0;
331     else
332     introduce_killed_client = 1;
333    
334     DLINK_FOREACH(ptr, serv_list.head)
335     {
336     client_p = ptr->data;
337    
338     if (client_p == NULL || client_p == one)
339     continue;
340    
341     if (!introduce_killed_client)
342     {
343     if (ServerInfo.hub && IsCapable(client_p, CAP_LL))
344     {
345     if ((client_p->localClient->serverMask &
346     target_p->lazyLinkClientExists) == 0)
347     {
348     /* target isn't known to lazy leaf, skip it */
349     continue;
350     }
351     }
352     }
353     /* force introduction of killed client but check that
354     * its not on the server we're bursting too.. */
355     else if (strcmp(target_p->servptr->name, client_p->name))
356     client_burst_if_needed(client_p, target_p);
357    
358     /* introduce source of kill */
359     client_burst_if_needed(client_p, source_p);
360    
361     /* use UID if possible */
362     from = ID_or_name(source_p, client_p);
363     to = ID_or_name(target_p, client_p);
364    
365     if (MyClient(source_p))
366     {
367     sendto_one(client_p, ":%s KILL %s :%s!%s!%s!%s (%s)",
368     from, to,
369     me.name, source_p->host, source_p->username,
370     source_p->name, reason);
371     }
372     else
373     {
374     sendto_one(client_p, ":%s KILL %s :%s %s",
375     from, to, inpath, reason);
376     }
377     }
378     }
379    

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision