ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_rxline.c
Revision: 442
Committed: Sat Feb 11 23:14:21 2006 UTC (20 years, 5 months ago) by adx
Content type: text/x-csrc
File size: 11191 byte(s)
Log Message:
+ massive rewrite of module init/deinit/version headers,
  we are introducing a new module manager which deals with static
  and dynamic modules exactly the same way. (New possibilities
  include loading/unloading statically compiled modules and
  mixing static/dynamic ones in one build.)

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

Properties

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