ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/m_kline.c
Revision: 1058
Committed: Tue Feb 2 22:15:03 2010 UTC (14 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 16189 byte(s)
Log Message:
- move DLINE into its own m_dline module

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

Properties

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