ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_rkline.c
Revision: 885
Committed: Wed Oct 31 18:09:24 2007 UTC (16 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 16099 byte(s)
Log Message:
- Removed LazyLinks in 7.2 to stop people from asking why we keep
  broken code for half a decade. LL will be implemented in a smarter
  fashion in due time

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) 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 "tools.h"
27 #include "channel.h"
28 #include "client.h"
29 #include "common.h"
30 #include "pcre.h"
31 #include "irc_string.h"
32 #include "sprintf_irc.h"
33 #include "ircd.h"
34 #include "hostmask.h"
35 #include "numeric.h"
36 #include "list.h"
37 #include "fdlist.h"
38 #include "s_bsd.h"
39 #include "s_conf.h"
40 #include "s_log.h"
41 #include "s_misc.h"
42 #include "send.h"
43 #include "hash.h"
44 #include "handlers.h"
45 #include "s_serv.h"
46 #include "msg.h"
47 #include "s_gline.h"
48 #include "parse.h"
49 #include "modules.h"
50 #include "tools.h"
51
52 static void me_rkline(struct Client *, struct Client *, int, char *[]);
53 static void mo_rkline(struct Client *, struct Client *, int, char *[]);
54 static void ms_rkline(struct Client *, struct Client *, int, char *[]);
55
56 static void me_unrkline(struct Client *, struct Client *, int, char *[]);
57 static void mo_unrkline(struct Client *, struct Client *, int, char *[]);
58 static void ms_unrkline(struct Client *, struct Client *, int, char *[]);
59 /* Local function prototypes */
60 static int already_placed_rkline(struct Client *, const char *, const char *);
61 static void apply_rkline(struct Client *, struct ConfItem *, const char *, time_t);
62 static void apply_trkline(struct Client *, struct ConfItem *, int);
63
64 static char buffer[IRCD_BUFSIZE];
65 static int remove_trkline_match(const char *, const char *);
66
67 struct Message rkline_msgtab = {
68 "RKLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
69 {m_unregistered, m_not_oper, ms_rkline, me_rkline, mo_rkline, m_ignore}
70 };
71
72 struct Message unrkline_msgtab = {
73 "UNRKLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
74 {m_unregistered, m_not_oper, ms_unrkline, me_unrkline, mo_unrkline, m_ignore}
75 };
76
77 #ifndef STATIC_MODULES
78 void
79 _modinit(void)
80 {
81 mod_add_cmd(&rkline_msgtab);
82 mod_add_cmd(&unrkline_msgtab);
83 }
84
85 void
86 _moddeinit(void)
87 {
88 mod_del_cmd(&rkline_msgtab);
89 mod_del_cmd(&unrkline_msgtab);
90 }
91
92 const char *_version = "$Revision$";
93 #endif
94
95 /* mo_rkline()
96 *
97 * inputs - pointer to server
98 * - pointer to client
99 * - parameter count
100 * - parameter list
101 * output -
102 * side effects - rk line is added
103 */
104 static void
105 mo_rkline(struct Client *client_p, struct Client *source_p,
106 int parc, char *parv[])
107 {
108 pcre *exp_user = NULL, *exp_host = NULL;
109 const char *errptr = NULL;
110 char *reason = NULL;
111 char *oper_reason = NULL;
112 char *user = NULL;
113 char *host = NULL;
114 const char *current_date = NULL;
115 char *target_server = NULL;
116 struct ConfItem *conf = NULL;
117 struct AccessItem *aconf = NULL;
118 time_t tkline_time = 0;
119 time_t cur_time = 0;
120
121 if (!IsAdmin(source_p) || !IsOperK(source_p))
122 {
123 sendto_one(source_p, form_str(ERR_NOPRIVS),
124 me.name, source_p->name, "rkline");
125 return;
126 }
127
128 if (parse_aline("RKLINE", source_p, parc, parv, NOUSERLOOKUP, &user,
129 &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 RKLINE %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 RKLINE %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 RKLINE %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 #if 0
156 else
157 cluster_a_line(source_p, "RKLINE", CAP_KLN, SHARED_KLINE,
158 "%d %s %s :%s", tkline_time, user, host, reason);
159 #endif
160
161 if (already_placed_rkline(source_p, user, host))
162 return;
163
164 /* Look for an oper reason */
165 if ((oper_reason = strchr(reason, '|')) != NULL)
166 *oper_reason++ = '\0';
167
168 if (!(exp_user = ircd_pcre_compile(user, &errptr)) ||
169 !(exp_host = ircd_pcre_compile(host, &errptr)))
170 {
171 sendto_realops_flags(UMODE_ALL, L_ALL,
172 "Failed to add regular expression based K-Line: %s", errptr);
173 return;
174 }
175
176 cur_time = CurrentTime;
177 current_date = smalldate(cur_time);
178 conf = make_conf_item(RKLINE_TYPE);
179 aconf = map_to_conf(conf);
180
181 DupString(aconf->host, host);
182 DupString(aconf->user, user);
183
184 aconf->regexuser = exp_user;
185 aconf->regexhost = exp_host;
186
187 if (tkline_time != 0)
188 {
189 ircsprintf(buffer, "Temporary RK-line %d min. - %s (%s)",
190 (int)(tkline_time/60), reason, current_date);
191 DupString(aconf->reason, buffer);
192
193 if (oper_reason != NULL)
194 DupString(aconf->oper_reason, oper_reason);
195 apply_trkline(source_p, conf, tkline_time);
196 }
197 else
198 {
199 ircsprintf(buffer, "%s (%s)", reason, current_date);
200 DupString(aconf->reason, buffer);
201
202 if (oper_reason != NULL)
203 DupString(aconf->oper_reason, oper_reason);
204 apply_rkline(source_p, conf, current_date, cur_time);
205 }
206 }
207
208 /* me_rkline - handle remote rkline. no propagation */
209 static void
210 me_rkline(struct Client *client_p, struct Client *source_p,
211 int parc, char *parv[])
212 {
213 struct ConfItem *conf = NULL;
214 struct AccessItem *aconf = NULL;
215 int tkline_time;
216 const char *current_date = NULL;
217 time_t cur_time;
218 char *kuser, *khost, *kreason, *oper_reason;
219
220 if (parc != 6 || EmptyString(parv[5]))
221 return;
222
223 if (!match(parv[1], me.name))
224 return;
225
226 tkline_time = valid_tkline(parv[2], TK_SECONDS);
227 kuser = parv[3];
228 khost = parv[4];
229 kreason = parv[5];
230
231 if ((oper_reason = strchr(kreason, '|')) != NULL)
232 *oper_reason++ = '\0';
233
234 cur_time = CurrentTime;
235 current_date = smalldate(cur_time);
236
237 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
238 source_p->username, source_p->host,
239 SHARED_KLINE))
240 {
241 pcre *exp_user = NULL, *exp_host = NULL;
242 const char *errptr = NULL;
243
244 if (!IsClient(source_p) ||
245 already_placed_rkline(source_p, kuser, khost))
246 return;
247
248 if (!(exp_user = ircd_pcre_compile(kuser, &errptr)) ||
249 !(exp_host = ircd_pcre_compile(khost, &errptr)))
250 {
251 sendto_realops_flags(UMODE_ALL, L_ALL,
252 "Failed to add regular expression based K-Line: %s", errptr);
253 return;
254 }
255
256 conf = make_conf_item(RKLINE_TYPE);
257 aconf = map_to_conf(conf);
258 DupString(aconf->host, khost);
259 DupString(aconf->user, kuser);
260
261 aconf->regexuser = exp_user;
262 aconf->regexhost = exp_host;
263
264 if (tkline_time)
265 {
266 ircsprintf(buffer, "Temporary RK-line %d min. - %s (%s)",
267 (int)(tkline_time/60), kreason, current_date);
268 DupString(aconf->reason, buffer);
269
270 if (oper_reason != NULL)
271 DupString(aconf->oper_reason, oper_reason);
272 apply_trkline(source_p, conf, tkline_time);
273 }
274 else
275 {
276 ircsprintf(buffer, "%s (%s)", kreason, current_date);
277 DupString(aconf->reason, buffer);
278
279 if (oper_reason != NULL)
280 DupString(aconf->oper_reason, oper_reason);
281 apply_rkline(source_p, conf, current_date, cur_time);
282 }
283 }
284 }
285
286 static void
287 ms_rkline(struct Client *client_p, struct Client *source_p,
288 int parc, char *parv[])
289 {
290 if (parc != 6 || EmptyString(parv[5]))
291 return;
292
293 /* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */
294 /* oper target_server tkline_time user host reason */
295 sendto_match_servs(source_p, parv[1], CAP_KLN,
296 "RKLINE %s %s %s %s :%s",
297 parv[1], parv[2], parv[3], parv[4], parv[5]);
298
299 me_rkline(client_p, source_p, parc, parv);
300 }
301
302 /* apply_rkline()
303 *
304 * inputs -
305 * output - NONE
306 * side effects - kline as given, is added to the hashtable
307 * and conf file
308 */
309 static void
310 apply_rkline(struct Client *source_p, struct ConfItem *conf,
311 const char *current_date, time_t cur_time)
312 {
313 write_conf_line(source_p, conf, current_date, cur_time);
314 /* Now, activate kline against current online clients */
315 rehashed_klines = 1;
316 }
317
318 /* apply_trkline()
319 *
320 * inputs -
321 * output - NONE
322 * side effects - tkline as given is placed
323 */
324 static void
325 apply_trkline(struct Client *source_p, struct ConfItem *conf,
326 int tkline_time)
327 {
328 struct AccessItem *aconf = map_to_conf(conf);
329
330 aconf->hold = CurrentTime + tkline_time;
331 add_temp_line(conf);
332 sendto_realops_flags(UMODE_ALL, L_ALL,
333 "%s added temporary %d min. RK-Line for [%s@%s] [%s]",
334 get_oper_name(source_p), tkline_time/60,
335 aconf->user, aconf->host,
336 aconf->reason);
337 sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. RK-Line [%s@%s]",
338 MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
339 source_p->name, tkline_time/60, aconf->user, aconf->host);
340 ilog(L_TRACE, "%s added temporary %d min. RK-Line for [%s@%s] [%s]",
341 source_p->name, tkline_time/60,
342 aconf->user, aconf->host, aconf->reason);
343 rehashed_klines = 1;
344 }
345
346 /* already_placed_rkline()
347 * inputs - user to complain to, username & host to check for
348 * outputs - returns 1 on existing K-line, 0 if doesn't exist
349 * side effects - notifies source_p if the K-line already exists
350 */
351 static int
352 already_placed_rkline(struct Client *source_p, const char *user, const char *host)
353 {
354 const dlink_node *ptr = NULL;
355
356 DLINK_FOREACH(ptr, rkconf_items.head)
357 {
358 struct AccessItem *aptr = map_to_conf(ptr->data);
359
360 if (!strcmp(user, aptr->user) &&
361 !strcmp(aptr->host, host))
362 {
363 sendto_one(source_p,
364 ":%s NOTICE %s :[%s@%s] already RK-Lined by [%s@%s] - %s",
365 me.name, source_p->name, user, host, aptr->user,
366 aptr->host, aptr->reason ? aptr->reason : "No reason");
367 return 1;
368 }
369 }
370
371 return 0;
372 }
373
374 /*
375 * mo_unrkline
376 * parv[0] = sender
377 * parv[1] = address to remove
378 */
379 static void
380 mo_unrkline(struct Client *client_p,struct Client *source_p,
381 int parc, char *parv[])
382 {
383 char *target_server = NULL;
384 char *user, *host;
385
386 if (!IsAdmin(source_p) || !IsOperUnkline(source_p))
387 {
388 sendto_one(source_p, form_str(ERR_NOPRIVS),
389 me.name, source_p->name, "unrkline");
390 return;
391 }
392
393 if (parc < 2 || *parv[1] == '\0')
394 {
395 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
396 me.name, source_p->name, "UNRKLINE");
397 return;
398 }
399
400 if (parse_aline("UNRKLINE", source_p, parc, parv, NOUSERLOOKUP, &user,
401 &host, NULL, &target_server, NULL) < 0)
402 return;
403
404 if (target_server != NULL)
405 {
406 sendto_match_servs(source_p, target_server, CAP_UNKLN,
407 "UNRKLINE %s %s %s",
408 target_server, user, host);
409
410 /* Allow ON to apply local unkline as well if it matches */
411 if (!match(target_server, me.name))
412 return;
413 }
414 #if 0
415 else
416 cluster_a_line(source_p, "UNRKLINE", CAP_UNKLN, SHARED_UNKLINE,
417 "%s %s", user, host);
418 #endif
419
420 if (remove_trkline_match(host, user))
421 {
422 sendto_one(source_p,
423 ":%s NOTICE %s :Un-klined [%s@%s] from temporary RK-Lines",
424 me.name, source_p->name, user, host);
425 sendto_realops_flags(UMODE_ALL, L_ALL,
426 "%s has removed the temporary RK-Line for: [%s@%s]",
427 get_oper_name(source_p), user, host);
428 ilog(L_NOTICE, "%s removed temporary RK-Line for [%s@%s]",
429 source_p->name, user, host);
430 return;
431 }
432
433 if (remove_conf_line(RKLINE_TYPE, source_p, user, host) > 0)
434 {
435 sendto_one(source_p, ":%s NOTICE %s :RK-Line for [%s@%s] is removed",
436 me.name, source_p->name, user,host);
437 sendto_realops_flags(UMODE_ALL, L_ALL,
438 "%s has removed the RK-Line for: [%s@%s]",
439 get_oper_name(source_p), user, host);
440 ilog(L_NOTICE, "%s removed RK-Line for [%s@%s]",
441 source_p->name, user, host);
442 }
443 else
444 sendto_one(source_p, ":%s NOTICE %s :No RK-Line for [%s@%s] found",
445 me.name, source_p->name, user, host);
446 }
447
448 /* me_unrkline()
449 *
450 * inputs - server
451 * - client
452 * - parc
453 * - parv
454 * outputs - none
455 * side effects - if server is authorized, rkline is removed
456 * does not propagate message
457 */
458 static void
459 me_unrkline(struct Client *client_p, struct Client *source_p,
460 int parc, char *parv[])
461 {
462 const char *user = NULL, *host = NULL;
463
464 if (parc != 4 || EmptyString(parv[3]))
465 return;
466
467 user = parv[2];
468 host = parv[3];
469
470 if (!IsClient(source_p) || !match(parv[1], me.name))
471 return;
472
473 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
474 source_p->username, source_p->host,
475 SHARED_UNKLINE))
476 {
477 if (remove_trkline_match(host, user))
478 {
479 sendto_one(source_p,
480 ":%s NOTICE %s :Un-klined [%s@%s] from temporary RK-Lines",
481 me.name, source_p->name, user, host);
482 sendto_realops_flags(UMODE_ALL, L_ALL,
483 "%s has removed the temporary RK-Line for: [%s@%s]",
484 get_oper_name(source_p), user, host);
485 ilog(L_NOTICE, "%s removed temporary RK-Line for [%s@%s]",
486 source_p->name, user, host);
487 return;
488 }
489
490 if (remove_conf_line(RKLINE_TYPE, source_p, user, host) > 0)
491 {
492 sendto_one(source_p, ":%s NOTICE %s :RK-Line for [%s@%s] is removed",
493 me.name, source_p->name, user, host);
494 sendto_realops_flags(UMODE_ALL, L_ALL,
495 "%s has removed the RK-Line for: [%s@%s]",
496 get_oper_name(source_p), user, host);
497
498 ilog(L_NOTICE, "%s removed RK-Line for [%s@%s]",
499 source_p->name, user, host);
500 }
501 else
502 sendto_one(source_p, ":%s NOTICE %s :No RK-Line for [%s@%s] found",
503 me.name, source_p->name, user, host);
504 }
505 }
506
507 /* ms_unrkline - propagates and handles a remote unrkline message */
508 static void
509 ms_unrkline(struct Client *client_p, struct Client *source_p,
510 int parc, char *parv[])
511 {
512 if (parc != 4 || EmptyString(parv[3]))
513 return;
514
515 sendto_match_servs(source_p, parv[1], CAP_UNKLN,
516 "UNRKLINE %s %s %s",
517 parv[1], parv[2], parv[3]);
518
519 me_unrkline(client_p, source_p, parc, parv);
520 }
521
522 /* static int remove_rtkline_match(const char *host, const char *user)
523 * Input: A hostname, a username to unrkline.
524 * Output: returns YES on success, NO if no trkline removed.
525 * Side effects: Any matching trklines are removed.
526 */
527 static int
528 remove_trkline_match(const char *const host,
529 const char *const user)
530 {
531 dlink_node *ptr = NULL;
532
533 DLINK_FOREACH(ptr, temporary_rklines.head)
534 {
535 struct ConfItem *conf = ptr->data;
536 struct AccessItem *aptr = map_to_conf(ptr->data);
537
538 if (!strcmp(user, aptr->user) &&
539 !strcmp(aptr->host, host))
540 {
541 dlinkDelete(ptr, &temporary_rklines);
542 free_dlink_node(ptr);
543 delete_conf_item(conf);
544 return 1;
545 }
546 }
547
548 return 0;
549 }

Properties

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