ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/m_rxline.c
Revision: 1029
Committed: Sun Nov 8 13:10:50 2009 UTC (16 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 11362 byte(s)
Log Message:
- branch off trunk to create 7.3 branch

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_rxline.c: xlines a user with regular expression support.
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 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 "parse.h"
46     #include "modules.h"
47     #include "resv.h"
48    
49     static void mo_rxline(struct Client *, struct Client *, int, char *[]);
50     static void ms_rxline(struct Client *, struct Client *, int, char *[]);
51     static void mo_unrxline(struct Client *, struct Client *, int, char *[]);
52     static void ms_unrxline(struct Client *, struct Client *, int, char *[]);
53    
54     static int valid_xline(struct Client *, char *, char *, int);
55     static void write_rxline(struct Client *, const char *, char *, time_t);
56     static void remove_xline(struct Client *, char *);
57     static int remove_txline(const char *);
58    
59     struct Message rxline_msgtab = {
60     "RXLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
61     { m_unregistered, m_not_oper, ms_rxline, m_ignore, mo_rxline, m_ignore }
62     };
63    
64     struct Message unrxline_msgtab = {
65     "UNRXLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
66     { m_unregistered, m_not_oper, ms_unrxline, m_ignore, mo_unrxline, m_ignore }
67     };
68    
69     #ifndef STATIC_MODULES
70     void
71     _modinit(void)
72     {
73     mod_add_cmd(&rxline_msgtab);
74     mod_add_cmd(&unrxline_msgtab);
75     }
76    
77     void
78     _moddeinit(void)
79     {
80     mod_del_cmd(&rxline_msgtab);
81     mod_del_cmd(&unrxline_msgtab);
82     }
83    
84 knight 31 const char *_version = "$Revision$";
85 adx 30 #endif
86    
87     static int
88     already_placed_rxline(struct Client *source_p, const char *gecos)
89     {
90     const dlink_node *ptr = NULL;
91    
92     DLINK_FOREACH(ptr, rxconf_items.head)
93     {
94     struct ConfItem *aptr = ptr->data;
95     const struct MatchItem *match_item = map_to_conf(aptr);
96    
97     if (!strcmp(gecos, aptr->name))
98     {
99     sendto_one(source_p, ":%s NOTICE %s :[%s] already RX-Lined by [%s] - %s",
100     me.name, source_p->name, gecos,
101     aptr->name, match_item->reason);
102     return 1;
103     }
104     }
105    
106     return 0;
107     }
108    
109     /* mo_rxline()
110     *
111     * inputs - pointer to server
112     * - pointer to client
113     * - parameter count
114     * - parameter list
115     * output -
116     * side effects - regular expression x line is added
117     *
118     */
119     static void
120     mo_rxline(struct Client *client_p, struct Client *source_p,
121     int parc, char *parv[])
122     {
123     char *reason = NULL;
124     char *gecos = NULL;
125     char *target_server = NULL;
126     time_t tkline_time = 0;
127    
128     if (!IsOperX(source_p))
129     {
130     sendto_one(source_p, form_str(ERR_NOPRIVS),
131     me.name, source_p->name, "rxline");
132     return;
133     }
134    
135     if (parse_aline("RXLINE", source_p, parc, parv, AWILD, &gecos,
136     NULL, &tkline_time, NULL, &reason) < 0)
137     return;
138    
139     if (target_server != NULL)
140     {
141     sendto_match_servs(source_p, target_server, CAP_CLUSTER,
142     "RXLINE %s %s %d :%s",
143     target_server, gecos, (int)tkline_time, reason);
144    
145     /* Allow ON to apply local rxline as well if it matches */
146     if (!match(target_server, me.name))
147     return;
148     }
149    
150     #if 0
151     cluster_a_line(source_p, "RXLINE", CAP_KLN, SHARED_XLINE,
152     "%s 0 :%s", gecos, reason);
153     #endif
154    
155     if (!valid_xline(source_p, gecos, reason, 0))
156     return;
157    
158     if (!already_placed_rxline(source_p, gecos))
159     write_rxline(source_p, gecos, reason, tkline_time);
160     }
161    
162     /* ms_rxline()
163     *
164     * inputs - oper, target server, rxline, {type}, reason
165     * deprecate {type} reserve for temp xlines later? XXX
166     *
167     * outputs - none
168     * side effects - propagates rxline, applies it if we are a target
169     */
170     static void
171     ms_rxline(struct Client *client_p, struct Client *source_p,
172     int parc, char *parv[])
173     {
174     int t_sec = 0;
175    
176     if (parc != 5 || EmptyString(parv[4]))
177     return;
178    
179     if (!IsClient(source_p))
180     return;
181    
182     if (!valid_xline(source_p, parv[2], parv[4], 0))
183     return;
184    
185     t_sec = atoi(parv[3]);
186     /* XXX kludge! */
187     if (t_sec < 3)
188     t_sec = 0;
189    
190     sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
191     "RXLINE %s %s %s :%s",
192     parv[1], parv[2], parv[3], parv[4]);
193    
194     if (!match(parv[1], me.name))
195     return;
196    
197     if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
198     source_p->username, source_p->host,
199     SHARED_XLINE))
200     if (!already_placed_rxline(source_p, parv[2]))
201     write_rxline(source_p, parv[2], parv[4], t_sec);
202     }
203    
204     static void
205     mo_unrxline(struct Client *client_p, struct Client *source_p,
206     int parc, char *parv[])
207     {
208     char *gecos = NULL;
209     char *target_server = NULL;
210    
211     if (!IsOperX(source_p))
212     {
213     sendto_one(source_p, form_str(ERR_NOPRIVS),
214     me.name, source_p->name, "unrxline");
215     return;
216     }
217    
218     if (parse_aline("UNRXLINE", source_p, parc, parv, 0, &gecos,
219     NULL, NULL, &target_server, NULL) < 0)
220     return;
221    
222     if (target_server != NULL)
223     {
224    
225     sendto_match_servs(source_p, target_server, CAP_CLUSTER,
226     "UNRXLINE %s %s", target_server, gecos);
227    
228     /* Allow ON to apply local unrxline as well if it matches */
229     if (!match(target_server, me.name))
230     return;
231     }
232    
233     #if 0
234     cluster_a_line(source_p, "UNRXLINE", CAP_CLUSTER, SHARED_UNXLINE,
235     "%s", gecos);
236     #endif
237    
238     remove_xline(source_p, gecos);
239     }
240    
241     /* ms_unrxline()
242     *
243     * inputs - oper, target server, gecos
244     * outputs - none
245     * side effects - propagates unrxline, applies it if we are a target
246     */
247     static void
248     ms_unrxline(struct Client *client_p, struct Client *source_p,
249     int parc, char *parv[])
250     {
251     if (parc != 3 || EmptyString(parv[2]))
252     return;
253    
254     sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
255     "UNRXLINE %s %s",
256     parv[1], parv[2]);
257    
258     if (!IsClient(source_p) || !match(parv[1], me.name))
259     return;
260    
261     if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
262     source_p->username, source_p->host,
263     SHARED_UNXLINE))
264     remove_xline(source_p, parv[2]);
265     }
266    
267     /* valid_xline()
268     *
269     * inputs - client to complain to, gecos, reason, whether to complain
270     * outputs - 1 for valid, else 0
271     * side effects - complains to client, when warn != 0
272     */
273     static int
274     valid_xline(struct Client *source_p, char *gecos, char *reason, int warn)
275     {
276     if (EmptyString(reason))
277     {
278     if (warn)
279     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
280     me.name, source_p->name, "RXLINE");
281     return 0;
282     }
283    
284     if (strchr(gecos, '"'))
285     {
286     sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"'",
287     me.name, source_p->name);
288     return 0;
289     }
290    
291     if (!valid_wild_card_simple(gecos))
292     {
293     if (warn)
294     sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the rxline",
295     me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple);
296    
297     return 0;
298     }
299    
300     return 1;
301     }
302    
303     /* write_rxline()
304     *
305     * inputs - client taking credit for rxline
306     * outputs - none
307     * side effects - when successful, adds an rxline to the conf
308     */
309     static void
310     write_rxline(struct Client *source_p, const char *gecos, char *reason,
311     time_t tkline_time)
312     {
313     struct ConfItem *conf = NULL;
314     struct MatchItem *match_item = NULL;
315     const char *current_date = NULL;
316     time_t cur_time = 0;
317 michael 1011 void *exp_gecos = NULL;
318 adx 30 const char *errptr = NULL;
319    
320     if (!(exp_gecos = ircd_pcre_compile(gecos, &errptr)))
321     {
322     sendto_realops_flags(UMODE_ALL, L_ALL,
323     "Failed to add regular expression based X-Line: %s", errptr);
324     return;
325     }
326    
327     conf = make_conf_item(RXLINE_TYPE);
328     conf->regexpname = exp_gecos;
329    
330     match_item = map_to_conf(conf);
331    
332     DupString(conf->name, gecos);
333     DupString(match_item->reason, reason);
334     DupString(match_item->oper_reason, ""); /* XXX */
335    
336     cur_time = CurrentTime;
337     current_date = smalldate(cur_time);
338    
339     if (tkline_time)
340     {
341     sendto_realops_flags(UMODE_ALL, L_ALL,
342     "%s added temporary %d min. RX-Line for [%s] [%s]",
343     get_oper_name(source_p), (int)tkline_time/60,
344     conf->name, match_item->reason);
345     sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. RX-Line [%s]",
346     MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
347     source_p->name, (int)tkline_time/60, conf->name);
348     ilog(L_TRACE, "%s added temporary %d min. RX-Line for [%s] [%s]",
349     source_p->name, (int)tkline_time/60,
350     conf->name, match_item->reason);
351     match_item->hold = CurrentTime + tkline_time;
352     add_temp_line(conf);
353     }
354     else
355     write_conf_line(source_p, conf, current_date, cur_time);
356     rehashed_klines = 1;
357     }
358    
359     static void
360     remove_xline(struct Client *source_p, char *gecos)
361     {
362     /* XXX use common temporary un function later */
363     if (remove_txline(gecos))
364     {
365     sendto_one(source_p,
366     ":%s NOTICE %s :Un-rxlined [%s] from temporary RX-Lines",
367     me.name, source_p->name, gecos);
368     sendto_realops_flags(UMODE_ALL, L_ALL,
369     "%s has removed the temporary RX-Line for: [%s]",
370     get_oper_name(source_p), gecos);
371     ilog(L_NOTICE, "%s removed temporary RX-Line for [%s]",
372     source_p->name, gecos);
373     return;
374     }
375    
376     if (remove_conf_line(RXLINE_TYPE, source_p, gecos, NULL) > 0)
377     {
378     sendto_one(source_p, ":%s NOTICE %s :RX-Line for [%s] is removed",
379     me.name, source_p->name, gecos);
380     sendto_realops_flags(UMODE_ALL, L_ALL,
381     "%s has removed the RX-Line for: [%s]",
382     get_oper_name(source_p), gecos);
383     ilog(L_NOTICE, "%s removed RX-Line for [%s]",
384     get_oper_name(source_p), gecos);
385     }
386     else
387     sendto_one(source_p, ":%s NOTICE %s :No RX-Line for %s",
388     me.name, source_p->name, gecos);
389     }
390    
391     /* static int remove_tkline_match(const char *host, const char *user)
392     *
393     * Inputs: gecos
394     * Output: returns YES on success, NO if no tkline removed.
395     * Side effects: Any matching tklines are removed.
396     */
397     static int
398     remove_txline(const char *const gecos)
399     {
400     dlink_node *ptr = NULL;
401    
402     DLINK_FOREACH(ptr, temporary_rxlines.head)
403     {
404     struct ConfItem *conf = ptr->data;
405    
406     if (!strcmp(gecos, conf->name))
407     {
408     dlinkDelete(ptr, &temporary_rxlines);
409     free_dlink_node(ptr);
410     delete_conf_item(conf);
411     return 1;
412     }
413     }
414    
415     return 0;
416     }

Properties

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