ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_rkline.c
Revision: 719
Committed: Sun Jul 16 16:56:58 2006 UTC (20 years ago) by adx
Content type: text/x-csrc
File size: 16696 byte(s)
Log Message:
+ reworked operator{} blocks to make them independent from oldconf
+ moved some utilities from s_conf.* to libio
+ added stub for auth{} blocks

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 "conf/conf.h"
27 #include "client.h"
28 #include "common.h"
29 #include "ircd.h"
30 #include "hostmask.h"
31 #include "numeric.h"
32 #include "s_conf.h"
33 #include "parse_aline.h"
34 #include "send.h"
35 #include "hash.h"
36 #include "handlers.h"
37 #include "s_serv.h"
38 #include "msg.h"
39 #include "parse.h"
40
41 static void me_rkline(struct Client *, struct Client *, int, char *[]);
42 static void mo_rkline(struct Client *, struct Client *, int, char *[]);
43 static void ms_rkline(struct Client *, struct Client *, int, char *[]);
44
45 static void me_unrkline(struct Client *, struct Client *, int, char *[]);
46 static void mo_unrkline(struct Client *, struct Client *, int, char *[]);
47 static void ms_unrkline(struct Client *, struct Client *, int, char *[]);
48 /* Local function prototypes */
49 static int already_placed_rkline(struct Client *, const char *, const char *);
50 static void apply_rkline(struct Client *, struct ConfItem *, const char *, time_t);
51 static void apply_trkline(struct Client *, struct ConfItem *, int);
52
53 static char buffer[IRCD_BUFSIZE];
54 static int remove_trkline_match(const char *, const char *);
55
56 struct Message rkline_msgtab = {
57 "RKLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
58 {m_unregistered, m_not_oper, ms_rkline, me_rkline, mo_rkline, m_ignore}
59 };
60
61 struct Message unrkline_msgtab = {
62 "UNRKLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
63 {m_unregistered, m_not_oper, ms_unrkline, me_unrkline, mo_unrkline, m_ignore}
64 };
65
66 INIT_MODULE(m_rkline, "$Revision$")
67 {
68 mod_add_cmd(&rkline_msgtab);
69 mod_add_cmd(&unrkline_msgtab);
70 }
71
72 CLEANUP_MODULE
73 {
74 mod_del_cmd(&unrkline_msgtab);
75 mod_del_cmd(&rkline_msgtab);
76 }
77
78 /* mo_rkline()
79 *
80 * inputs - pointer to server
81 * - pointer to client
82 * - parameter count
83 * - parameter list
84 * output -
85 * side effects - rk line is added
86 */
87 static void
88 mo_rkline(struct Client *client_p, struct Client *source_p,
89 int parc, char *parv[])
90 {
91 pcre *exp_user = NULL, *exp_host = NULL;
92 const char *errptr = NULL;
93 char *reason = NULL;
94 char *oper_reason = NULL;
95 char *user = NULL;
96 char *host = NULL;
97 const char *current_date = NULL;
98 char *target_server = NULL;
99 struct ConfItem *conf = NULL;
100 struct AccessItem *aconf = NULL;
101 time_t tkline_time = 0;
102 time_t cur_time = 0;
103
104 if (!IsAdmin(source_p) || !IsOperK(source_p))
105 {
106 sendto_one(source_p, form_str(ERR_NOPRIVS),
107 me.name, source_p->name, "rkline");
108 return;
109 }
110
111 if (parse_aline("RKLINE", source_p, parc, parv, NOUSERLOOKUP, &user,
112 &host, &tkline_time, &target_server, &reason) < 0)
113 return;
114
115 if (target_server != NULL)
116 {
117 if (HasID(source_p))
118 {
119 sendto_server(NULL, source_p, NULL, CAP_KLN|CAP_TS6, NOCAPS,
120 ":%s RKLINE %s %lu %s %s :%s",
121 source_p->id, target_server, (unsigned long)tkline_time,
122 user, host, reason);
123 sendto_server(NULL, source_p, NULL, CAP_KLN, CAP_TS6,
124 ":%s RKLINE %s %lu %s %s :%s",
125 source_p->name, target_server, (unsigned long)tkline_time,
126 user, host, reason);
127 }
128 else
129 sendto_server(NULL, source_p, NULL, CAP_KLN, NOCAPS,
130 ":%s RKLINE %s %lu %s %s :%s",
131 source_p->name, target_server, (unsigned long)tkline_time,
132 user, host, reason);
133
134 /* Allow ON to apply local kline as well if it matches */
135 if (!match(target_server, me.name))
136 return;
137 }
138 #if 0
139 else
140 cluster_a_line(source_p, "RKLINE", CAP_KLN, SHARED_KLINE,
141 "%d %s %s :%s", tkline_time, user, host, reason);
142 #endif
143
144 if (already_placed_rkline(source_p, user, host))
145 return;
146
147 /* Look for an oper reason */
148 if ((oper_reason = strchr(reason, '|')) != NULL)
149 *oper_reason++ = '\0';
150
151 if (!(exp_user = ircd_pcre_compile(user, &errptr)) ||
152 !(exp_host = ircd_pcre_compile(host, &errptr)))
153 {
154 sendto_realops_flags(UMODE_ALL, L_ALL,
155 "Failed to add regular expression based K-Line: %s", errptr);
156 return;
157 }
158
159 cur_time = CurrentTime;
160 current_date = smalldate(cur_time);
161 conf = make_conf_item(RKLINE_TYPE);
162 aconf = &conf->conf.AccessItem;
163
164 DupString(aconf->host, host);
165 DupString(aconf->user, user);
166
167 aconf->regexuser = exp_user;
168 aconf->regexhost = exp_host;
169
170 if (tkline_time != 0)
171 {
172 ircsprintf(buffer, "Temporary RK-line %d min. - %s (%s)",
173 (int)(tkline_time/60), reason, current_date);
174 DupString(aconf->reason, buffer);
175
176 if (oper_reason != NULL)
177 DupString(aconf->oper_reason, oper_reason);
178 apply_trkline(source_p, conf, tkline_time);
179 }
180 else
181 {
182 ircsprintf(buffer, "%s (%s)", reason, current_date);
183 DupString(aconf->reason, buffer);
184
185 if (oper_reason != NULL)
186 DupString(aconf->oper_reason, oper_reason);
187 apply_rkline(source_p, conf, current_date, cur_time);
188 }
189 }
190
191 /* me_rkline - handle remote rkline. no propagation */
192 static void
193 me_rkline(struct Client *client_p, struct Client *source_p,
194 int parc, char *parv[])
195 {
196 struct ConfItem *conf = NULL;
197 struct AccessItem *aconf = NULL;
198 int tkline_time;
199 const char *current_date = NULL;
200 time_t cur_time;
201 char *kuser, *khost, *kreason, *oper_reason;
202
203 if (parc != 6 || EmptyString(parv[5]))
204 return;
205
206 if (!match(parv[1], me.name))
207 return;
208
209 tkline_time = valid_tkline(parv[2], TK_SECONDS);
210 kuser = parv[3];
211 khost = parv[4];
212 kreason = parv[5];
213
214 if ((oper_reason = strchr(kreason, '|')) != NULL)
215 *oper_reason++ = '\0';
216
217 cur_time = CurrentTime;
218 current_date = smalldate(cur_time);
219
220 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
221 source_p->username, source_p->host,
222 SHARED_KLINE))
223 {
224 pcre *exp_user = NULL, *exp_host = NULL;
225 const char *errptr = NULL;
226
227 if (!IsClient(source_p) ||
228 already_placed_rkline(source_p, kuser, khost))
229 return;
230
231 if (!(exp_user = ircd_pcre_compile(kuser, &errptr)) ||
232 !(exp_host = ircd_pcre_compile(khost, &errptr)))
233 {
234 sendto_realops_flags(UMODE_ALL, L_ALL,
235 "Failed to add regular expression based K-Line: %s", errptr);
236 return;
237 }
238
239 conf = make_conf_item(RKLINE_TYPE);
240 aconf = &conf->conf.AccessItem;
241 DupString(aconf->host, khost);
242 DupString(aconf->user, kuser);
243
244 aconf->regexuser = exp_user;
245 aconf->regexhost = exp_host;
246
247 if (tkline_time)
248 {
249 ircsprintf(buffer, "Temporary RK-line %d min. - %s (%s)",
250 (int)(tkline_time/60), kreason, current_date);
251 DupString(aconf->reason, buffer);
252
253 if (oper_reason != NULL)
254 DupString(aconf->oper_reason, oper_reason);
255 apply_trkline(source_p, conf, tkline_time);
256 }
257 else
258 {
259 ircsprintf(buffer, "%s (%s)", kreason, current_date);
260 DupString(aconf->reason, buffer);
261
262 if (oper_reason != NULL)
263 DupString(aconf->oper_reason, oper_reason);
264 apply_rkline(source_p, conf, current_date, cur_time);
265 }
266 }
267 }
268
269 static void
270 ms_rkline(struct Client *client_p, struct Client *source_p,
271 int parc, char *parv[])
272 {
273 if (parc != 6 || EmptyString(parv[5]))
274 return;
275
276 /* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */
277 /* oper target_server tkline_time user host reason */
278 sendto_match_servs(source_p, parv[1], CAP_KLN,
279 "RKLINE %s %s %s %s :%s",
280 parv[1], parv[2], parv[3], parv[4], parv[5]);
281
282 me_rkline(client_p, source_p, parc, parv);
283 }
284
285 /* apply_rkline()
286 *
287 * inputs -
288 * output - NONE
289 * side effects - kline as given, is added to the hashtable
290 * and conf file
291 */
292 static void
293 apply_rkline(struct Client *source_p, struct ConfItem *conf,
294 const char *current_date, time_t cur_time)
295 {
296 const struct AccessItem *aconf = &conf->conf.AccessItem;
297
298 write_conf_line(source_p, conf, current_date, cur_time);
299
300 sendto_realops_flags(UMODE_ALL, L_ALL,
301 "%s added RK-Line for [%s@%s] [%s]",
302 get_oper_name(source_p),
303 aconf->user, aconf->host, aconf->reason);
304 sendto_one(source_p, ":%s NOTICE %s :Added RK-Line [%s@%s] to %s",
305 MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
306 source_p->name, aconf->user, aconf->host, ConfigFileEntry.rklinefile);
307 ilog(L_TRACE, "%s added K-Line for [%s@%s] [%s]",
308 get_oper_name(source_p), aconf->user, aconf->host, aconf->reason);
309 log_oper_action(LOG_RKLINE_TYPE, source_p, "[%s@%s] [%s]\n",
310 aconf->user, aconf->host, aconf->reason);
311
312 /* Now, activate kline against current online clients */
313 rehashed_klines = 1;
314 }
315
316 /* apply_trkline()
317 *
318 * inputs -
319 * output - NONE
320 * side effects - tkline as given is placed
321 */
322 static void
323 apply_trkline(struct Client *source_p, struct ConfItem *conf,
324 int tkline_time)
325 {
326 struct AccessItem *aconf = &conf->conf.AccessItem;
327
328 aconf->hold = CurrentTime + tkline_time;
329 add_temp_line(conf);
330
331 sendto_realops_flags(UMODE_ALL, L_ALL,
332 "%s added temporary %d min. RK-Line for [%s@%s] [%s]",
333 get_oper_name(source_p), tkline_time/60,
334 aconf->user, aconf->host,
335 aconf->reason);
336 sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. RK-Line [%s@%s]",
337 MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
338 source_p->name, tkline_time/60, aconf->user, aconf->host);
339 ilog(L_TRACE, "%s added temporary %d min. RK-Line for [%s@%s] [%s]",
340 get_oper_name(source_p), tkline_time/60,
341 aconf->user, aconf->host, aconf->reason);
342
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 = &((struct ConfItem *)(ptr->data))->conf.AccessItem;
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 (EmptyString(parv[1]))
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 get_oper_name(source_p), 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 get_oper_name(source_p), user, host);
442 return;
443 }
444
445 sendto_one(source_p, ":%s NOTICE %s :No RK-Line for [%s@%s] found",
446 me.name, source_p->name, user, host);
447 }
448
449 /* me_unrkline()
450 *
451 * inputs - server
452 * - client
453 * - parc
454 * - parv
455 * outputs - none
456 * side effects - if server is authorized, rkline is removed
457 * does not propagate message
458 */
459 static void
460 me_unrkline(struct Client *client_p, struct Client *source_p,
461 int parc, char *parv[])
462 {
463 const char *user = NULL, *host = NULL;
464
465 if (parc != 4 || EmptyString(parv[3]))
466 return;
467
468 user = parv[2];
469 host = parv[3];
470
471 if (!IsClient(source_p) || !match(parv[1], me.name))
472 return;
473
474 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
475 source_p->username, source_p->host,
476 SHARED_UNKLINE))
477 {
478 if (remove_trkline_match(host, user))
479 {
480 sendto_one(source_p,
481 ":%s NOTICE %s :Un-klined [%s@%s] from temporary RK-Lines",
482 me.name, source_p->name, user, host);
483 sendto_realops_flags(UMODE_ALL, L_ALL,
484 "%s has removed the temporary RK-Line for: [%s@%s]",
485 get_oper_name(source_p), user, host);
486 ilog(L_NOTICE, "%s removed temporary RK-Line for [%s@%s]",
487 get_oper_name(source_p), user, host);
488 return;
489 }
490
491 if (remove_conf_line(RKLINE_TYPE, source_p, user, host) > 0)
492 {
493 sendto_one(source_p, ":%s NOTICE %s :RK-Line for [%s@%s] is removed",
494 me.name, source_p->name, user, host);
495 sendto_realops_flags(UMODE_ALL, L_ALL,
496 "%s has removed the RK-Line for: [%s@%s]",
497 get_oper_name(source_p), user, host);
498
499 ilog(L_NOTICE, "%s removed RK-Line for [%s@%s]",
500 get_oper_name(source_p), user, host);
501 return;
502 }
503
504 sendto_one(source_p, ":%s NOTICE %s :No RK-Line for [%s@%s] found",
505 me.name, source_p->name, user, host);
506 }
507 }
508
509 /* ms_unrkline - propagates and handles a remote unrkline message */
510 static void
511 ms_unrkline(struct Client *client_p, struct Client *source_p,
512 int parc, char *parv[])
513 {
514 if (parc != 4 || EmptyString(parv[3]))
515 return;
516
517 sendto_match_servs(source_p, parv[1], CAP_UNKLN,
518 "UNRKLINE %s %s %s",
519 parv[1], parv[2], parv[3]);
520
521 me_unrkline(client_p, source_p, parc, parv);
522 }
523
524 /* static int remove_rtkline_match(const char *host, const char *user)
525 * Input: A hostname, a username to unrkline.
526 * Output: returns YES on success, NO if no trkline removed.
527 * Side effects: Any matching trklines are removed.
528 */
529 static int
530 remove_trkline_match(const char *const host,
531 const char *const user)
532 {
533 dlink_node *ptr = NULL;
534
535 DLINK_FOREACH(ptr, temporary_rklines.head)
536 {
537 struct ConfItem *conf = ptr->data;
538 struct AccessItem *aptr = &conf->conf.AccessItem;
539
540 if (!strcmp(user, aptr->user) &&
541 !strcmp(aptr->host, host))
542 {
543 dlinkDelete(ptr, &temporary_rklines);
544 free_dlink_node(ptr);
545 delete_conf_item(conf);
546 return 1;
547 }
548 }
549
550 return 0;
551 }

Properties

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