ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/releases/8.1.0beta5/modules/m_xline.c
Revision: 1618
Committed: Tue Oct 30 21:04:38 2012 UTC (12 years, 9 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/m_xline.c
File size: 12445 byte(s)
Log Message:
- Made m_globops() and ms_globops() use sendto_realops_flags()
- Added message-type parameter to sendto_realops_flags() which can be one of
  SEND_NOTICE, SEND_GLOBAL, SEND_LOCOPS
- Forward-port -r1617

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

Properties

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