ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.0.x/modules/m_kline.c
Revision: 1275
Committed: Mon Jan 30 23:50:03 2012 UTC (14 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_kline.c
File size: 15921 byte(s)
Error occurred while calculating annotation data.
Log Message:
- services that are specified in the services{} block may now set remote k/x-lines

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_kline.c: Bans a 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 "s_conf.h"
37 #include "s_log.h"
38 #include "s_misc.h"
39 #include "send.h"
40 #include "hash.h"
41 #include "s_serv.h"
42 #include "s_gline.h"
43 #include "parse.h"
44 #include "modules.h"
45
46
47 static int already_placed_kline(struct Client *, const char *, const char *, int);
48 static void apply_kline(struct Client *, struct ConfItem *, const char *, time_t);
49 static void apply_tkline(struct Client *, struct ConfItem *, int);
50
51 static char buffer[IRCD_BUFSIZE];
52 static int remove_tkline_match(const char *, const char *);
53
54
55 /* mo_kline()
56 *
57 * inputs - pointer to server
58 * - pointer to client
59 * - parameter count
60 * - parameter list
61 * output -
62 * side effects - k line is added
63 */
64 static void
65 mo_kline(struct Client *client_p, struct Client *source_p,
66 int parc, char **parv)
67 {
68 char *reason = NULL;
69 char *oper_reason;
70 char *user = NULL;
71 char *host = NULL;
72 const char *current_date;
73 char *target_server = NULL;
74 struct ConfItem *conf;
75 struct AccessItem *aconf;
76 time_t tkline_time = 0;
77 time_t cur_time;
78
79 if (!HasOFlag(source_p, OPER_FLAG_K))
80 {
81 sendto_one(source_p, form_str(ERR_NOPRIVS),
82 me.name, source_p->name, "kline");
83 return;
84 }
85
86 if (parse_aline("KLINE", source_p, parc, parv,
87 AWILD, &user, &host, &tkline_time, &target_server, &reason) < 0)
88 return;
89
90 if (target_server != NULL)
91 {
92 if (HasID(source_p))
93 {
94 sendto_server(NULL, NULL, CAP_KLN|CAP_TS6, NOCAPS,
95 ":%s KLINE %s %lu %s %s :%s",
96 source_p->id, target_server, (unsigned long)tkline_time,
97 user, host, reason);
98 sendto_server(NULL, NULL, CAP_KLN, CAP_TS6,
99 ":%s KLINE %s %lu %s %s :%s",
100 source_p->name, target_server, (unsigned long)tkline_time,
101 user, host, reason);
102 }
103 else
104 sendto_server(NULL, NULL, CAP_KLN, NOCAPS,
105 ":%s KLINE %s %lu %s %s :%s",
106 source_p->name, target_server, (unsigned long)tkline_time,
107 user, host, reason);
108
109 /* Allow ON to apply local kline as well if it matches */
110 if (!match(target_server, me.name))
111 return;
112 }
113 else
114 cluster_a_line(source_p, "KLINE", CAP_KLN, SHARED_KLINE,
115 "%d %s %s :%s", tkline_time, user, host, reason);
116
117 if (already_placed_kline(source_p, user, host, 1))
118 return;
119
120 /* Look for an oper reason */
121 if ((oper_reason = strchr(reason, '|')) != NULL)
122 *oper_reason++ = '\0';
123
124 cur_time = CurrentTime;
125 current_date = smalldate(cur_time);
126 conf = make_conf_item(KLINE_TYPE);
127 aconf = map_to_conf(conf);
128
129 DupString(aconf->host, host);
130 DupString(aconf->user, user);
131
132 if (tkline_time != 0)
133 {
134 snprintf(buffer, sizeof(buffer), "Temporary K-line %d min. - %s (%s)",
135 (int)(tkline_time/60), reason, current_date);
136 DupString(aconf->reason, buffer);
137
138 if (oper_reason != NULL)
139 DupString(aconf->oper_reason, oper_reason);
140 apply_tkline(source_p, conf, tkline_time);
141 }
142 else
143 {
144 snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
145 DupString(aconf->reason, buffer);
146
147 if (oper_reason != NULL)
148 DupString(aconf->oper_reason, oper_reason);
149 apply_kline(source_p, conf, current_date, cur_time);
150 }
151 }
152
153 /* me_kline - handle remote kline. no propagation */
154 static void
155 me_kline(struct Client *client_p, struct Client *source_p,
156 int parc, char *parv[])
157 {
158 struct ConfItem *conf=NULL;
159 struct AccessItem *aconf=NULL;
160 int tkline_time;
161 const char* current_date;
162 time_t cur_time;
163 char *kuser, *khost, *kreason, *oper_reason;
164
165 if (parc != 6 || EmptyString(parv[5]))
166 return;
167
168 if (!match(parv[1], me.name))
169 return;
170
171 tkline_time = valid_tkline(parv[2], TK_SECONDS);
172 kuser = parv[3];
173 khost = parv[4];
174 kreason = parv[5];
175
176 if ((oper_reason = strchr(kreason, '|')) != NULL)
177 *oper_reason++ = '\0';
178
179 cur_time = CurrentTime;
180 current_date = smalldate(cur_time);
181
182 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
183 source_p->username, source_p->host,
184 SHARED_KLINE))
185 {
186 if (!IsClient(source_p) ||
187 already_placed_kline(source_p, kuser, khost, 1))
188 return;
189
190 conf = make_conf_item(KLINE_TYPE);
191 aconf = map_to_conf(conf);
192 DupString(aconf->host, khost);
193 DupString(aconf->user, kuser);
194
195 if (tkline_time != 0)
196 {
197 snprintf(buffer, sizeof(buffer), "Temporary K-line %d min. - %s (%s)",
198 (int)(tkline_time/60), kreason, current_date);
199 DupString(aconf->reason, buffer);
200
201 if (oper_reason != NULL)
202 DupString(aconf->oper_reason, oper_reason);
203 apply_tkline(source_p, conf, tkline_time);
204 }
205 else
206 {
207 snprintf(buffer, sizeof(buffer), "%s (%s)", kreason, current_date);
208 DupString(aconf->reason, buffer);
209
210 if (oper_reason != NULL)
211 DupString(aconf->oper_reason, oper_reason);
212 apply_kline(source_p, conf, current_date, cur_time);
213 }
214 }
215 }
216
217 static void
218 ms_kline(struct Client *client_p, struct Client *source_p,
219 int parc, char *parv[])
220 {
221 if (parc != 6 || EmptyString(parv[5]))
222 return;
223
224 /* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */
225 /* oper target_server tkline_time user host reason */
226 sendto_match_servs(source_p, parv[1], CAP_KLN,
227 "KLINE %s %s %s %s :%s",
228 parv[1], parv[2], parv[3], parv[4], parv[5]);
229
230 me_kline(client_p, source_p, parc, parv);
231 }
232
233 /* apply_kline()
234 *
235 * inputs -
236 * output - NONE
237 * side effects - kline as given, is added to the hashtable
238 * and conf file
239 */
240 static void
241 apply_kline(struct Client *source_p, struct ConfItem *conf,
242 const char *current_date, time_t cur_time)
243 {
244 struct AccessItem *aconf = map_to_conf(conf);
245
246 add_conf_by_address(CONF_KILL, aconf);
247 write_conf_line(source_p, conf, current_date, cur_time);
248 /* Now, activate kline against current online clients */
249 rehashed_klines = 1;
250 }
251
252 /* apply_tkline()
253 *
254 * inputs -
255 * output - NONE
256 * side effects - tkline as given is placed
257 */
258 static void
259 apply_tkline(struct Client *source_p, struct ConfItem *conf,
260 int tkline_time)
261 {
262 struct AccessItem *aconf;
263
264 aconf = (struct AccessItem *)map_to_conf(conf);
265 aconf->hold = CurrentTime + tkline_time;
266 add_temp_line(conf);
267 sendto_realops_flags(UMODE_ALL, L_ALL,
268 "%s added temporary %d min. K-Line for [%s@%s] [%s]",
269 get_oper_name(source_p), tkline_time/60,
270 aconf->user, aconf->host,
271 aconf->reason);
272 sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. K-Line [%s@%s]",
273 MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
274 source_p->name, tkline_time/60, aconf->user, aconf->host);
275 ilog(LOG_TYPE_KLINE, "%s added temporary %d min. K-Line for [%s@%s] [%s]",
276 source_p->name, tkline_time/60,
277 aconf->user, aconf->host, aconf->reason);
278
279 rehashed_klines = 1;
280 }
281
282 /* already_placed_kline()
283 * inputs - user to complain to, username & host to check for
284 * outputs - returns 1 on existing K-line, 0 if doesn't exist
285 * side effects - notifies source_p if the K-line already exists
286 */
287 /*
288 * Note: This currently works if the new K-line is a special case of an
289 * existing K-line, but not the other way round. To do that we would
290 * have to walk the hash and check every existing K-line. -A1kmm.
291 */
292 static int
293 already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int warn)
294 {
295 const char *reason;
296 struct irc_ssaddr iphost, *piphost;
297 struct AccessItem *aconf;
298 int t;
299
300 if ((t = parse_netmask(lhost, &iphost, &t)) != HM_HOST)
301 {
302 #ifdef IPV6
303 if (t == HM_IPV6)
304 t = AF_INET6;
305 else
306 #endif
307 t = AF_INET;
308 piphost = &iphost;
309 }
310 else
311 {
312 t = 0;
313 piphost = NULL;
314 }
315
316 if ((aconf = find_conf_by_address(lhost, piphost, CONF_KILL, t, luser, NULL)))
317 {
318 if (warn)
319 {
320 reason = aconf->reason ? aconf->reason : "No reason";
321 sendto_one(source_p,
322 ":%s NOTICE %s :[%s@%s] already K-Lined by [%s@%s] - %s",
323 me.name, source_p->name, luser, lhost, aconf->user,
324 aconf->host, reason);
325 }
326 return(1);
327 }
328
329 return(0);
330 }
331
332 /*
333 ** mo_unkline
334 ** Added Aug 31, 1997
335 ** common (Keith Fralick) fralick@gate.net
336 **
337 ** parv[0] = sender
338 ** parv[1] = address to remove
339 *
340 *
341 */
342 static void
343 mo_unkline(struct Client *client_p,struct Client *source_p,
344 int parc, char *parv[])
345 {
346 char *target_server = NULL;
347 char *user, *host;
348
349 if (!HasOFlag(source_p, OPER_FLAG_UNKLINE))
350 {
351 sendto_one(source_p, form_str(ERR_NOPRIVS),
352 me.name, source_p->name, "unkline");
353 return;
354 }
355
356 if (parc < 2 || EmptyString(parv[1]))
357 {
358 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
359 me.name, source_p->name, "UNKLINE");
360 return;
361 }
362
363 if (parse_aline("UNKLINE", source_p, parc, parv, 0, &user,
364 &host, NULL, &target_server, NULL) < 0)
365 return;
366
367 if (target_server != NULL)
368 {
369 sendto_match_servs(source_p, target_server, CAP_UNKLN,
370 "UNKLINE %s %s %s",
371 target_server, user, host);
372
373 /* Allow ON to apply local unkline as well if it matches */
374 if (!match(target_server, me.name))
375 return;
376 }
377 else
378 cluster_a_line(source_p, "UNKLINE", CAP_UNKLN, SHARED_UNKLINE,
379 "%s %s", user, host);
380
381 if (remove_tkline_match(host, user))
382 {
383 sendto_one(source_p,
384 ":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines",
385 me.name, source_p->name, user, host);
386 sendto_realops_flags(UMODE_ALL, L_ALL,
387 "%s has removed the temporary K-Line for: [%s@%s]",
388 get_oper_name(source_p), user, host);
389 ilog(LOG_TYPE_KLINE, "%s removed temporary K-Line for [%s@%s]",
390 source_p->name, user, host);
391 return;
392 }
393
394 if (remove_conf_line(KLINE_TYPE, source_p, user, host) > 0)
395 {
396 sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed",
397 me.name, source_p->name, user,host);
398 sendto_realops_flags(UMODE_ALL, L_ALL,
399 "%s has removed the K-Line for: [%s@%s]",
400 get_oper_name(source_p), user, host);
401 ilog(LOG_TYPE_KLINE, "%s removed K-Line for [%s@%s]",
402 source_p->name, user, host);
403 }
404 else
405 sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found",
406 me.name, source_p->name, user, host);
407 }
408
409 /* me_unkline()
410 *
411 * inputs - server
412 * - client
413 * - parc
414 * - parv
415 * outputs - none
416 * side effects - if server is authorized, kline is removed
417 * does not propagate message
418 */
419 static void
420 me_unkline(struct Client *client_p, struct Client *source_p,
421 int parc, char *parv[])
422 {
423 const char *kuser, *khost;
424
425 if (parc != 4)
426 return;
427
428 kuser = parv[2];
429 khost = parv[3];
430
431 if (!IsClient(source_p) || !match(parv[1], me.name))
432 return;
433
434 if (!HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE,
435 source_p->servptr->name,
436 source_p->username, source_p->host,
437 SHARED_UNKLINE))
438 {
439 if (remove_tkline_match(khost, kuser))
440 {
441 sendto_one(source_p,
442 ":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines",
443 me.name, source_p->name, kuser, khost);
444 sendto_realops_flags(UMODE_ALL, L_ALL,
445 "%s has removed the temporary K-Line for: [%s@%s]",
446 get_oper_name(source_p), kuser, khost);
447 ilog(LOG_TYPE_KLINE, "%s removed temporary K-Line for [%s@%s]",
448 source_p->name, kuser, khost);
449 return;
450 }
451
452 if (remove_conf_line(KLINE_TYPE, source_p, kuser, khost) > 0)
453 {
454 sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed",
455 me.name, source_p->name, kuser, khost);
456 sendto_realops_flags(UMODE_ALL, L_ALL,
457 "%s has removed the K-Line for: [%s@%s]",
458 get_oper_name(source_p), kuser, khost);
459
460 ilog(LOG_TYPE_KLINE, "%s removed K-Line for [%s@%s]",
461 source_p->name, kuser, khost);
462 }
463 else
464 sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found",
465 me.name, source_p->name, kuser, khost);
466 }
467 }
468
469 /* ms_unkline - propagates and handles a remote unkline message */
470 static void
471 ms_unkline(struct Client *client_p, struct Client *source_p,
472 int parc, char *parv[])
473 {
474 if (parc != 4)
475 return;
476
477 sendto_match_servs(source_p, parv[1], CAP_UNKLN,
478 "UNKLINE %s %s %s",
479 parv[1], parv[2], parv[3]);
480
481 me_unkline(client_p, source_p, parc, parv);
482 }
483
484 /* static int remove_tkline_match(const char *host, const char *user)
485 * Input: A hostname, a username to unkline.
486 * Output: returns YES on success, NO if no tkline removed.
487 * Side effects: Any matching tklines are removed.
488 */
489 static int
490 remove_tkline_match(const char *host, const char *user)
491 {
492 struct AccessItem *tk_c;
493 dlink_node *tk_n;
494 struct irc_ssaddr addr, caddr;
495 int nm_t, cnm_t, bits, cbits;
496 nm_t = parse_netmask(host, &addr, &bits);
497
498 DLINK_FOREACH(tk_n, temporary_klines.head)
499 {
500 tk_c = map_to_conf(tk_n->data);
501 cnm_t = parse_netmask(tk_c->host, &caddr, &cbits);
502 if (cnm_t != nm_t || irccmp(user, tk_c->user))
503 continue;
504 if ((nm_t==HM_HOST && !irccmp(tk_c->host, host)) ||
505 (nm_t==HM_IPV4 && bits==cbits && match_ipv4(&addr, &caddr, bits))
506 #ifdef IPV6
507 || (nm_t==HM_IPV6 && bits==cbits && match_ipv6(&addr, &caddr, bits))
508 #endif
509 )
510 {
511 dlinkDelete(tk_n, &temporary_klines);
512 delete_one_address_conf(tk_c->host, tk_c);
513 return 1;
514 }
515 }
516
517 return 0;
518 }
519
520 static struct Message kline_msgtab = {
521 "KLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
522 {m_unregistered, m_not_oper, ms_kline, me_kline, mo_kline, m_ignore}
523 };
524
525 static struct Message unkline_msgtab = {
526 "UNKLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
527 {m_unregistered, m_not_oper, ms_unkline, me_unkline, mo_unkline, m_ignore}
528 };
529
530 static void
531 module_init(void)
532 {
533 mod_add_cmd(&kline_msgtab);
534 mod_add_cmd(&unkline_msgtab);
535 add_capability("KLN", CAP_KLN, 1);
536 add_capability("UNKLN", CAP_UNKLN, 1);
537 }
538
539 static void
540 module_exit(void)
541 {
542 mod_del_cmd(&kline_msgtab);
543 mod_del_cmd(&unkline_msgtab);
544 delete_capability("UNKLN");
545 delete_capability("KLN");
546 }
547
548 struct module module_entry = {
549 .node = { NULL, NULL, NULL },
550 .name = NULL,
551 .version = "$Revision$",
552 .handle = NULL,
553 .modinit = module_init,
554 .modexit = module_exit,
555 .flags = 0
556 };

Properties

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