ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_xline.c
Revision: 382
Committed: Tue Jan 31 12:13:42 2006 UTC (18 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 12552 byte(s)
Log Message:
- Fixed incorrect match handling in relay_xline as reported by ThaPrince.
  Damnit match() really shouldn't return 1 on match.  This will be changed
  sooner or later.

File Contents

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

Properties

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