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 (15 years, 9 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

# Content
1 /*
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 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "list.h"
27 #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 const char *_version = "$Revision$";
85 #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 void *exp_gecos = NULL;
318 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