ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/branches/ircd-hybrid-newconf/modules/m_rxline.c
Revision: 1027
Committed: Sun Nov 8 13:01:13 2009 UTC (16 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 11221 byte(s)
Log Message:
- Move old 7.3 sources to branches/ircd-hybrid-newconf

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

Properties

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