ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/modules/m_kline.c
Revision: 1156
Committed: Tue Aug 9 20:29:20 2011 UTC (14 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 16130 byte(s)
Log Message:
- create ircd-hybrid-8 "branch"

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_kline.c: Bans 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 michael 1011 #include "list.h"
27 adx 30 #include "channel.h"
28     #include "client.h"
29     #include "common.h"
30     #include "irc_string.h"
31     #include "sprintf_irc.h"
32     #include "ircd.h"
33     #include "hostmask.h"
34     #include "numeric.h"
35     #include "fdlist.h"
36     #include "s_bsd.h"
37     #include "s_conf.h"
38     #include "s_log.h"
39     #include "s_misc.h"
40     #include "send.h"
41     #include "hash.h"
42     #include "handlers.h"
43     #include "s_serv.h"
44     #include "msg.h"
45     #include "s_gline.h"
46     #include "parse.h"
47     #include "modules.h"
48    
49 michael 611
50 adx 30 static void me_kline(struct Client *, struct Client *, int, char **);
51     static void mo_kline(struct Client *, struct Client *, int, char **);
52     static void ms_kline(struct Client *, struct Client *, int, char **);
53     static void me_unkline(struct Client *, struct Client *, int, char **);
54     static void mo_unkline(struct Client *, struct Client *, int, char **);
55     static void ms_unkline(struct Client *, struct Client *, int, char **);
56    
57 michael 1058 static int already_placed_kline(struct Client *, const char *, const char *, int);
58     static void apply_kline(struct Client *, struct ConfItem *, const char *, time_t);
59     static void apply_tkline(struct Client *, struct ConfItem *, int);
60    
61     static char buffer[IRCD_BUFSIZE];
62 adx 30 static int remove_tkline_match(const char *, const char *);
63    
64     struct Message kline_msgtab = {
65     "KLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
66     {m_unregistered, m_not_oper, ms_kline, me_kline, mo_kline, m_ignore}
67     };
68    
69     struct Message unkline_msgtab = {
70     "UNKLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
71     {m_unregistered, m_not_oper, ms_unkline, me_unkline, mo_unkline, m_ignore}
72     };
73    
74     void
75     _modinit(void)
76     {
77     mod_add_cmd(&kline_msgtab);
78     mod_add_cmd(&unkline_msgtab);
79     add_capability("KLN", CAP_KLN, 1);
80     add_capability("UNKLN", CAP_UNKLN, 1);
81     }
82    
83     void
84     _moddeinit(void)
85     {
86     mod_del_cmd(&kline_msgtab);
87     mod_del_cmd(&unkline_msgtab);
88     delete_capability("UNKLN");
89     delete_capability("KLN");
90     }
91    
92 knight 31 const char *_version = "$Revision$";
93 adx 30
94     /* mo_kline()
95     *
96     * inputs - pointer to server
97     * - pointer to client
98     * - parameter count
99     * - parameter list
100     * output -
101     * side effects - k line is added
102     */
103     static void
104     mo_kline(struct Client *client_p, struct Client *source_p,
105 michael 1058 int parc, char **parv)
106 adx 30 {
107     char *reason = NULL;
108     char *oper_reason;
109     char *user = NULL;
110     char *host = NULL;
111     const char *current_date;
112     char *target_server = NULL;
113     struct ConfItem *conf;
114     struct AccessItem *aconf;
115     time_t tkline_time = 0;
116     time_t cur_time;
117    
118     if (!IsOperK(source_p))
119     {
120     sendto_one(source_p, form_str(ERR_NOPRIVS),
121     me.name, source_p->name, "kline");
122     return;
123     }
124    
125     if (parse_aline("KLINE", source_p, parc, parv,
126     AWILD, &user, &host, &tkline_time, &target_server, &reason) < 0)
127     return;
128    
129     if (target_server != NULL)
130     {
131     if (HasID(source_p))
132     {
133 michael 885 sendto_server(NULL, NULL, CAP_KLN|CAP_TS6, NOCAPS,
134 adx 30 ":%s KLINE %s %lu %s %s :%s",
135     source_p->id, target_server, (unsigned long)tkline_time,
136     user, host, reason);
137 michael 885 sendto_server(NULL, NULL, CAP_KLN, CAP_TS6,
138 adx 30 ":%s KLINE %s %lu %s %s :%s",
139     source_p->name, target_server, (unsigned long)tkline_time,
140     user, host, reason);
141     }
142     else
143 michael 885 sendto_server(NULL, NULL, CAP_KLN, NOCAPS,
144 adx 30 ":%s KLINE %s %lu %s %s :%s",
145     source_p->name, target_server, (unsigned long)tkline_time,
146     user, host, reason);
147    
148     /* Allow ON to apply local kline as well if it matches */
149     if (!match(target_server, me.name))
150     return;
151     }
152     else
153     cluster_a_line(source_p, "KLINE", CAP_KLN, SHARED_KLINE,
154 michael 1058 "%d %s %s :%s", tkline_time, user, host, reason);
155 adx 30
156     if (already_placed_kline(source_p, user, host, YES))
157     return;
158    
159     /* Look for an oper reason */
160     if ((oper_reason = strchr(reason, '|')) != NULL)
161     *oper_reason++ = '\0';
162    
163     cur_time = CurrentTime;
164     current_date = smalldate(cur_time);
165     conf = make_conf_item(KLINE_TYPE);
166     aconf = map_to_conf(conf);
167    
168     DupString(aconf->host, host);
169     DupString(aconf->user, user);
170    
171     if (tkline_time != 0)
172     {
173     ircsprintf(buffer, "Temporary K-line %d min. - %s (%s)",
174     (int)(tkline_time/60), reason, current_date);
175     DupString(aconf->reason, buffer);
176    
177     if (oper_reason != NULL)
178     DupString(aconf->oper_reason, oper_reason);
179     apply_tkline(source_p, conf, tkline_time);
180     }
181     else
182     {
183     ircsprintf(buffer, "%s (%s)", reason, current_date);
184     DupString(aconf->reason, buffer);
185    
186     if (oper_reason != NULL)
187     DupString(aconf->oper_reason, oper_reason);
188     apply_kline(source_p, conf, current_date, cur_time);
189     }
190     }
191    
192     /* me_kline - handle remote kline. no propagation */
193     static void
194     me_kline(struct Client *client_p, struct Client *source_p,
195     int parc, char *parv[])
196     {
197     struct ConfItem *conf=NULL;
198     struct AccessItem *aconf=NULL;
199     int tkline_time;
200     const char* current_date;
201     time_t cur_time;
202     char *kuser, *khost, *kreason, *oper_reason;
203    
204 michael 352 if (parc != 6 || EmptyString(parv[5]))
205 adx 30 return;
206    
207     if (!match(parv[1], me.name))
208     return;
209    
210     tkline_time = valid_tkline(parv[2], TK_SECONDS);
211     kuser = parv[3];
212     khost = parv[4];
213     kreason = parv[5];
214    
215     if ((oper_reason = strchr(kreason, '|')) != NULL)
216     *oper_reason++ = '\0';
217    
218     cur_time = CurrentTime;
219     current_date = smalldate(cur_time);
220    
221     if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
222     source_p->username, source_p->host,
223     SHARED_KLINE))
224     {
225     if (!IsClient(source_p) ||
226     already_placed_kline(source_p, kuser, khost, YES))
227     return;
228    
229     conf = make_conf_item(KLINE_TYPE);
230     aconf = map_to_conf(conf);
231     DupString(aconf->host, khost);
232     DupString(aconf->user, kuser);
233    
234     if (tkline_time != 0)
235     {
236     ircsprintf(buffer, "Temporary K-line %d min. - %s (%s)",
237     (int)(tkline_time/60), kreason, current_date);
238     DupString(aconf->reason, buffer);
239    
240     if (oper_reason != NULL)
241     DupString(aconf->oper_reason, oper_reason);
242     apply_tkline(source_p, conf, tkline_time);
243     }
244     else
245     {
246     ircsprintf(buffer, "%s (%s)", kreason, current_date);
247     DupString(aconf->reason, buffer);
248    
249     if (oper_reason != NULL)
250     DupString(aconf->oper_reason, oper_reason);
251     apply_kline(source_p, conf, current_date, cur_time);
252     }
253     }
254     }
255    
256     static void
257     ms_kline(struct Client *client_p, struct Client *source_p,
258 michael 1058 int parc, char *parv[])
259 adx 30 {
260 michael 352 if (parc != 6 || EmptyString(parv[5]))
261 adx 30 return;
262    
263     /* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */
264     /* oper target_server tkline_time user host reason */
265     sendto_match_servs(source_p, parv[1], CAP_KLN,
266     "KLINE %s %s %s %s :%s",
267     parv[1], parv[2], parv[3], parv[4], parv[5]);
268    
269     me_kline(client_p, source_p, parc, parv);
270     }
271    
272     /* apply_kline()
273     *
274     * inputs -
275     * output - NONE
276     * side effects - kline as given, is added to the hashtable
277     * and conf file
278     */
279     static void
280     apply_kline(struct Client *source_p, struct ConfItem *conf,
281 michael 1058 const char *current_date, time_t cur_time)
282 adx 30 {
283     struct AccessItem *aconf = map_to_conf(conf);
284    
285     add_conf_by_address(CONF_KILL, aconf);
286     write_conf_line(source_p, conf, current_date, cur_time);
287     /* Now, activate kline against current online clients */
288     rehashed_klines = 1;
289     }
290    
291     /* apply_tkline()
292     *
293     * inputs -
294     * output - NONE
295     * side effects - tkline as given is placed
296     */
297     static void
298     apply_tkline(struct Client *source_p, struct ConfItem *conf,
299     int tkline_time)
300     {
301     struct AccessItem *aconf;
302    
303     aconf = (struct AccessItem *)map_to_conf(conf);
304     aconf->hold = CurrentTime + tkline_time;
305     add_temp_line(conf);
306     sendto_realops_flags(UMODE_ALL, L_ALL,
307     "%s added temporary %d min. K-Line for [%s@%s] [%s]",
308     get_oper_name(source_p), tkline_time/60,
309     aconf->user, aconf->host,
310     aconf->reason);
311     sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. K-Line [%s@%s]",
312     MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
313     source_p->name, tkline_time/60, aconf->user, aconf->host);
314     ilog(L_TRACE, "%s added temporary %d min. K-Line for [%s@%s] [%s]",
315     source_p->name, tkline_time/60,
316     aconf->user, aconf->host, aconf->reason);
317     log_oper_action(LOG_TEMP_KLINE_TYPE, source_p, "[%s@%s] [%s]\n",
318     aconf->user, aconf->host, aconf->reason);
319     rehashed_klines = 1;
320     }
321    
322     /* already_placed_kline()
323     * inputs - user to complain to, username & host to check for
324     * outputs - returns 1 on existing K-line, 0 if doesn't exist
325     * side effects - notifies source_p if the K-line already exists
326     */
327     /*
328     * Note: This currently works if the new K-line is a special case of an
329     * existing K-line, but not the other way round. To do that we would
330     * have to walk the hash and check every existing K-line. -A1kmm.
331     */
332     static int
333     already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int warn)
334     {
335     const char *reason;
336     struct irc_ssaddr iphost, *piphost;
337     struct AccessItem *aconf;
338     int t;
339    
340     if ((t = parse_netmask(lhost, &iphost, &t)) != HM_HOST)
341     {
342     #ifdef IPV6
343     if (t == HM_IPV6)
344     t = AF_INET6;
345     else
346     #endif
347     t = AF_INET;
348     piphost = &iphost;
349     }
350     else
351     {
352     t = 0;
353     piphost = NULL;
354     }
355    
356     if ((aconf = find_conf_by_address(lhost, piphost, CONF_KILL, t, luser, NULL)))
357     {
358     if (warn)
359     {
360     reason = aconf->reason ? aconf->reason : "No reason";
361     sendto_one(source_p,
362     ":%s NOTICE %s :[%s@%s] already K-Lined by [%s@%s] - %s",
363     me.name, source_p->name, luser, lhost, aconf->user,
364     aconf->host, reason);
365     }
366     return(1);
367     }
368    
369     return(0);
370     }
371    
372     /*
373     ** mo_unkline
374     ** Added Aug 31, 1997
375     ** common (Keith Fralick) fralick@gate.net
376     **
377     ** parv[0] = sender
378     ** parv[1] = address to remove
379     *
380     *
381     */
382     static void
383     mo_unkline(struct Client *client_p,struct Client *source_p,
384     int parc, char *parv[])
385     {
386     char *target_server = NULL;
387     char *user, *host;
388    
389     if (!IsOperUnkline(source_p))
390     {
391     sendto_one(source_p, form_str(ERR_NOPRIVS),
392     me.name, source_p->name, "unkline");
393     return;
394     }
395    
396     if (parc < 2 || EmptyString(parv[1]))
397     {
398     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
399     me.name, source_p->name, "UNKLINE");
400     return;
401     }
402    
403     if (parse_aline("UNKLINE", source_p, parc, parv, 0, &user,
404     &host, NULL, &target_server, NULL) < 0)
405     return;
406    
407     if (target_server != NULL)
408     {
409     sendto_match_servs(source_p, target_server, CAP_UNKLN,
410     "UNKLINE %s %s %s",
411     target_server, user, host);
412    
413     /* Allow ON to apply local unkline as well if it matches */
414     if (!match(target_server, me.name))
415     return;
416     }
417     else
418     cluster_a_line(source_p, "UNKLINE", CAP_UNKLN, SHARED_UNKLINE,
419 michael 1058 "%s %s", user, host);
420 adx 30
421     if (remove_tkline_match(host, user))
422     {
423     sendto_one(source_p,
424     ":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines",
425     me.name, source_p->name, user, host);
426     sendto_realops_flags(UMODE_ALL, L_ALL,
427     "%s has removed the temporary K-Line for: [%s@%s]",
428     get_oper_name(source_p), user, host);
429     ilog(L_NOTICE, "%s removed temporary K-Line for [%s@%s]",
430     source_p->name, user, host);
431     return;
432     }
433    
434     if (remove_conf_line(KLINE_TYPE, source_p, user, host) > 0)
435     {
436     sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed",
437 michael 1058 me.name, source_p->name, user,host);
438 adx 30 sendto_realops_flags(UMODE_ALL, L_ALL,
439 michael 1058 "%s has removed the K-Line for: [%s@%s]",
440     get_oper_name(source_p), user, host);
441 adx 30 ilog(L_NOTICE, "%s removed K-Line for [%s@%s]",
442 michael 1058 source_p->name, user, host);
443 adx 30 }
444     else
445     sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found",
446     me.name, source_p->name, user, host);
447     }
448    
449     /* me_unkline()
450     *
451     * inputs - server
452     * - client
453     * - parc
454     * - parv
455     * outputs - none
456     * side effects - if server is authorized, kline is removed
457     * does not propagate message
458     */
459     static void
460     me_unkline(struct Client *client_p, struct Client *source_p,
461     int parc, char *parv[])
462     {
463     const char *kuser, *khost;
464    
465     if (parc != 4)
466     return;
467    
468     kuser = parv[2];
469     khost = parv[3];
470    
471     if (!IsClient(source_p) || !match(parv[1], me.name))
472     return;
473    
474     if (find_matching_name_conf(ULINE_TYPE,
475     source_p->servptr->name,
476     source_p->username, source_p->host,
477     SHARED_UNKLINE))
478     {
479     if (remove_tkline_match(khost, kuser))
480     {
481     sendto_one(source_p,
482     ":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines",
483     me.name, source_p->name, kuser, khost);
484     sendto_realops_flags(UMODE_ALL, L_ALL,
485     "%s has removed the temporary K-Line for: [%s@%s]",
486     get_oper_name(source_p), kuser, khost);
487     ilog(L_NOTICE, "%s removed temporary K-Line for [%s@%s]",
488     source_p->name, kuser, khost);
489     return;
490     }
491    
492     if (remove_conf_line(KLINE_TYPE, source_p, kuser, khost) > 0)
493     {
494     sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed",
495     me.name, source_p->name, kuser, khost);
496     sendto_realops_flags(UMODE_ALL, L_ALL,
497     "%s has removed the K-Line for: [%s@%s]",
498     get_oper_name(source_p), kuser, khost);
499    
500     ilog(L_NOTICE, "%s removed K-Line for [%s@%s]",
501     source_p->name, kuser, khost);
502     }
503     else
504     sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found",
505     me.name, source_p->name, kuser, khost);
506     }
507     }
508    
509     /* ms_unkline - propagates and handles a remote unkline message */
510     static void
511     ms_unkline(struct Client *client_p, struct Client *source_p,
512     int parc, char *parv[])
513     {
514     if (parc != 4)
515     return;
516    
517     sendto_match_servs(source_p, parv[1], CAP_UNKLN,
518     "UNKLINE %s %s %s",
519     parv[1], parv[2], parv[3]);
520    
521     me_unkline(client_p, source_p, parc, parv);
522     }
523    
524     /* static int remove_tkline_match(const char *host, const char *user)
525     * Input: A hostname, a username to unkline.
526     * Output: returns YES on success, NO if no tkline removed.
527     * Side effects: Any matching tklines are removed.
528     */
529     static int
530     remove_tkline_match(const char *host, const char *user)
531     {
532     struct AccessItem *tk_c;
533     dlink_node *tk_n;
534     struct irc_ssaddr addr, caddr;
535     int nm_t, cnm_t, bits, cbits;
536     nm_t = parse_netmask(host, &addr, &bits);
537    
538     DLINK_FOREACH(tk_n, temporary_klines.head)
539     {
540     tk_c = map_to_conf(tk_n->data);
541     cnm_t = parse_netmask(tk_c->host, &caddr, &cbits);
542     if (cnm_t != nm_t || irccmp(user, tk_c->user))
543     continue;
544     if ((nm_t==HM_HOST && !irccmp(tk_c->host, host)) ||
545 michael 1058 (nm_t==HM_IPV4 && bits==cbits && match_ipv4(&addr, &caddr, bits))
546 adx 30 #ifdef IPV6
547 michael 1058 || (nm_t==HM_IPV6 && bits==cbits && match_ipv6(&addr, &caddr, bits))
548 adx 30 #endif
549 michael 1058 )
550 adx 30 {
551 michael 1058 dlinkDelete(tk_n, &temporary_klines);
552     delete_one_address_conf(tk_c->host, tk_c);
553     return 1;
554 adx 30 }
555     }
556    
557 michael 1058 return 0;
558 adx 30 }

Properties

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