ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_rxline.c
Revision: 32
Committed: Sun Oct 2 20:41:23 2005 UTC (18 years, 5 months ago) by knight
Content type: text/x-csrc
Original Path: ircd-hybrid/modules/m_rxline.c
File size: 11399 byte(s)
Log Message:
- svn:keywords

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

Properties

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