ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_rkline.c
Revision: 885
Committed: Wed Oct 31 18:09:24 2007 UTC (18 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 16099 byte(s)
Log Message:
- Removed LazyLinks in 7.2 to stop people from asking why we keep
  broken code for half a decade. LL will be implemented in a smarter
  fashion in due time

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

Properties

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