ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/m_gline.c
Revision: 933
Committed: Wed Apr 8 20:32:49 2009 UTC (17 years, 6 months ago) by db
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/m_gline.c
File size: 17765 byte(s)
Log Message:
- Remove the old m_ungline code to start.



File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_gline.c: Votes towards globally banning a mask.
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 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "tools.h"
27     #include "handlers.h"
28     #include "s_gline.h"
29     #include "channel.h"
30     #include "client.h"
31     #include "common.h"
32     #include "irc_string.h"
33     #include "sprintf_irc.h"
34     #include "ircd.h"
35     #include "hostmask.h"
36     #include "numeric.h"
37     #include "fdlist.h"
38     #include "s_bsd.h"
39     #include "s_conf.h"
40     #include "s_misc.h"
41     #include "send.h"
42     #include "msg.h"
43     #include "fileio.h"
44     #include "s_serv.h"
45     #include "hash.h"
46     #include "parse.h"
47     #include "modules.h"
48     #include "list.h"
49     #include "s_log.h"
50    
51     #define GLINE_NOT_PLACED 0
52     #ifdef GLINE_VOTING
53     #define GLINE_ALREADY_VOTED -1
54     #endif /* GLINE_VOTING */
55     #define GLINE_PLACED 1
56    
57     extern dlink_list gdeny_items;
58    
59     /* internal functions */
60     static void set_local_gline(const struct Client *,
61     const char *, const char *, const char *);
62    
63     #ifdef GLINE_VOTING
64     static int check_majority_gline(const struct Client *,
65     const char *, const char *, const char *);
66    
67     static void add_new_majority_gline(const struct Client *,
68     const char *, const char *, const char *);
69     #endif /* GLINE_VOTING */
70    
71     static void do_sgline(struct Client *, struct Client *, int, char **, int);
72    
73     static void me_gline(struct Client *, struct Client *, int, char **);
74     static void ms_gline(struct Client *, struct Client *, int, char **);
75     static void mo_gline(struct Client *, struct Client *, int, char **);
76    
77     /*
78     * gline enforces 3 parameters to force operator to give a reason
79     * a gline is not valid with "No reason"
80     * -db
81     */
82     struct Message gline_msgtab = {
83     "GLINE", 0, 0, 3, 0, MFLG_SLOW, 0,
84     {m_unregistered, m_not_oper, ms_gline, me_gline, mo_gline, m_ignore}
85     };
86    
87    
88     #ifndef STATIC_MODULES
89     void
90     _modinit(void)
91     {
92     mod_add_cmd(&gline_msgtab);
93     add_capability("GLN", CAP_GLN, 1);
94     }
95    
96     void
97     _moddeinit(void)
98     {
99     mod_del_cmd(&gline_msgtab);
100     delete_capability("GLN");
101     }
102    
103 knight 31 const char *_version = "$Revision$";
104 adx 30 #endif
105    
106     /* mo_gline()
107     *
108     * inputs - The usual for a m_ function
109     * output -
110     * side effects -
111     *
112     * Place a G line if 3 opers agree on the identical user@host
113     *
114     */
115     /* Allow this server to pass along GLINE if received and
116     * GLINES is not defined.
117     *
118     */
119    
120     static void
121     mo_gline(struct Client *client_p, struct Client *source_p,
122     int parc, char *parv[])
123     {
124     char *user = NULL;
125     char *host = NULL; /* user and host of GLINE "victim" */
126     char *reason = NULL; /* reason for "victims" demise */
127     char *p;
128    
129     if (!ConfigFileEntry.glines)
130     {
131     sendto_one(source_p, ":%s NOTICE %s :GLINE disabled",
132     me.name, source_p->name);
133     return;
134     }
135    
136     if (!IsOperGline(source_p))
137     {
138     sendto_one(source_p, form_str(ERR_NOPRIVS),
139     me.name, source_p->name, "gline");
140     return;
141     }
142    
143     if (parse_aline("GLINE", source_p, parc, parv,
144     AWILD, &user, &host, NULL, NULL, &reason) < 0)
145     return;
146    
147     if ((p = strchr(host, '/')) != NULL)
148     {
149     int bitlen = strtol(++p, NULL, 10);
150     int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
151     ConfigFileEntry.gline_min_cidr;
152     if (bitlen < min_bitlen)
153     {
154     sendto_one(source_p, ":%s NOTICE %s :Cannot set G-Lines with CIDR length < %d",
155     me.name, source_p->name, min_bitlen);
156     return;
157     }
158     }
159    
160     #ifdef GLINE_VOTING
161     /* If at least 3 opers agree this user should be G lined then do it */
162     if (check_majority_gline(source_p, user, host, reason) ==
163     GLINE_ALREADY_VOTED)
164     {
165     sendto_one(source_p,
166     ":%s NOTICE %s :This server or oper has already voted",
167     me.name, source_p->name);
168     return;
169     }
170    
171 michael 552 /*
172     * call these two functions first so the 'requesting' notice always comes
173 adx 30 * before the 'has triggered' notice. -bill
174     */
175     sendto_realops_flags(UMODE_ALL, L_ALL,
176     "%s requesting G-Line for [%s@%s] [%s]",
177     get_oper_name(source_p),
178     user, host, reason);
179     ilog(L_TRACE, "#gline for %s@%s [%s] requested by %s!%s@%s",
180     user, host, reason, source_p->name, source_p->username,
181     source_p->host);
182     #else
183     set_local_gline(source_p, user, host, reason);
184     #endif /* GLINE_VOTING */
185    
186     /* 4 param version for hyb-7 servers */
187 michael 885 sendto_server(NULL, NULL, CAP_GLN|CAP_TS6, NOCAPS,
188     ":%s GLINE %s %s :%s",
189 adx 30 ID(source_p), user, host, reason);
190 michael 885 sendto_server(NULL, NULL, CAP_GLN, CAP_TS6,
191     ":%s GLINE %s %s :%s",
192 adx 30 source_p->name, user, host, reason);
193    
194     /* 8 param for hyb-6 */
195 michael 885 sendto_server(NULL, NULL, CAP_TS6, CAP_GLN,
196 adx 30 ":%s GLINE %s %s %s %s %s %s :%s",
197     ID(&me),
198     ID(source_p), source_p->username,
199     source_p->host, source_p->servptr->name, user, host,
200     reason);
201 michael 885 sendto_server(NULL, NULL, NOCAPS, CAP_GLN|CAP_TS6,
202 adx 30 ":%s GLINE %s %s %s %s %s %s :%s",
203     me.name, source_p->name, source_p->username,
204     source_p->host, source_p->servptr->name, user, host,
205     reason);
206     }
207    
208     /* ms_gline()
209     * me_gline()
210     * do_sgline()
211     *
212     * inputs - The usual for a m_ function
213     * output -
214     * side effects -
215     *
216     * Place a G line if 3 opers agree on the identical user@host
217     *
218     * Allow this server to pass along GLINE if received and
219     * GLINES is not defined.
220     *
221     * ENCAP'd GLINES are propagated by encap code.
222     */
223    
224     static void
225     ms_gline(struct Client *client_p, struct Client *source_p,
226     int parc, char *parv[])
227     {
228     do_sgline(client_p, source_p, parc, parv, 1);
229     }
230    
231     static void
232     me_gline(struct Client *client_p, struct Client *source_p,
233     int parc, char *parv[])
234     {
235     do_sgline(client_p, source_p, parc, parv, 0);
236     }
237    
238     static void
239     do_sgline(struct Client *client_p, struct Client *source_p,
240     int parc, char *parv[], int prop)
241     {
242     const char *reason = NULL; /* reason for "victims" demise */
243     char *user = NULL;
244     char *host = NULL; /* user and host of GLINE "victim" */
245     int var_offset, logged = 0;
246     dlink_node *ptr;
247     struct ConfItem *conf;
248     struct AccessItem *aconf;
249    
250     /* hyb-7 style gline (post beta3) */
251     if (parc == 4 && IsClient(source_p))
252     var_offset = 0;
253     /* or it's a hyb-6 style */
254     else if (parc == 8 && IsServer(source_p))
255     {
256     var_offset = 4;
257    
258     /*
259     * if we are dealing with an old style formatted gline,
260     * the gline message is originating from the oper's server,
261     * so we update source_p to point to the oper now, so that
262     * logging works down the line. -bill
263     */
264     if ((source_p = find_person(client_p, parv[1])) == NULL)
265     return;
266    
267     if (irccmp(parv[2], source_p->username) != 0 ||
268     irccmp(parv[3], source_p->host) != 0 ||
269     irccmp(parv[4], source_p->servptr->name) != 0)
270     {
271     /*
272     * at this point we know one of the parameters provided by
273     * the h6 server was faulty. bail out.
274     */
275     return;
276     }
277     }
278     /* none of the above */
279     else
280     return;
281    
282     assert(source_p->servptr != NULL);
283    
284     user = parv[++var_offset];
285     host = parv[++var_offset];
286     reason = parv[++var_offset];
287    
288     var_offset = 0;
289    
290     DLINK_FOREACH(ptr, gdeny_items.head)
291     {
292     conf = ptr->data;
293     aconf = (struct AccessItem *)map_to_conf(conf);
294    
295     if (match(conf->name, source_p->servptr->name) &&
296     match(aconf->user, source_p->username) &&
297     match(aconf->host, source_p->host))
298     {
299     var_offset = aconf->flags;
300     break;
301     }
302     }
303    
304     if (prop && !(var_offset & GDENY_BLOCK))
305     {
306 michael 885 sendto_server(client_p, NULL, CAP_GLN, NOCAPS,
307 adx 30 ":%s GLINE %s %s :%s",
308     source_p->name, user, host, reason);
309     /* hyb-6 version to the rest */
310 michael 885 sendto_server(client_p, NULL, NOCAPS, CAP_GLN,
311 adx 30 ":%s GLINE %s %s %s %s %s %s :%s",
312     source_p->servptr->name,
313     source_p->name, source_p->username, source_p->host,
314     source_p->servptr->name,
315     user, host, reason);
316     }
317     else if (ConfigFileEntry.gline_logging & GDENY_BLOCK && ServerInfo.hub)
318     {
319     sendto_realops_flags(UMODE_ALL, L_ALL, "Blocked G-Line %s requested on [%s@%s] [%s]",
320     get_oper_name(source_p), user, host, reason);
321     ilog(L_TRACE, "Blocked G-Line %s requested on [%s@%s] [%s]",
322     get_oper_name(source_p), user, host, reason);
323     logged = 1;
324     }
325    
326    
327     if (var_offset & GDENY_REJECT)
328     {
329     if (ConfigFileEntry.gline_logging & GDENY_REJECT && !logged)
330     {
331     sendto_realops_flags(UMODE_ALL, L_ALL, "Rejected G-Line %s requested on [%s@%s] [%s]",
332     get_oper_name(source_p), user, host, reason);
333     ilog(L_TRACE, "Rejected G-Line %s requested on [%s@%s] [%s]",
334     get_oper_name(source_p), user, host, reason);
335     }
336     return;
337     }
338    
339     if (ConfigFileEntry.glines)
340     {
341     if (!valid_wild_card(source_p, YES, 2, user, host))
342     return;
343    
344     if (IsClient(source_p))
345     {
346     const char *p = NULL;
347     if ((p = strchr(host, '/')))
348     {
349     int bitlen = strtol(++p, NULL, 10);
350     int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
351     ConfigFileEntry.gline_min_cidr;
352    
353     if (bitlen < min_bitlen)
354     {
355     sendto_realops_flags(UMODE_ALL, L_ALL, "%s!%s@%s on %s is requesting "
356     "a GLINE with a CIDR mask < %d for [%s@%s] [%s]",
357     source_p->name, source_p->username, source_p->host,
358     source_p->servptr->name, min_bitlen, user, host, reason);
359     return;
360     }
361     }
362     }
363    
364     #ifdef GLINE_VOTING
365     /* If at least 3 opers agree this user should be G lined then do it */
366     if (check_majority_gline(source_p, user, host, reason) ==
367     GLINE_ALREADY_VOTED)
368     {
369     sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
370     return;
371     }
372    
373 michael 554 sendto_realops_flags(UMODE_ALL, L_ALL,
374     "%s requesting G-Line for [%s@%s] [%s]",
375     get_oper_name(source_p),
376     user, host, reason);
377 adx 30 ilog(L_TRACE, "#gline for %s@%s [%s] requested by %s",
378     user, host, reason, get_oper_name(source_p));
379     #else
380     set_local_gline(source_p, user, host, reason);
381     #endif /* GLINE_VOTING */
382     }
383     }
384    
385     /* set_local_gline()
386     *
387     * inputs - pointer to client struct of oper
388     * - pointer to victim user
389     * - pointer to victim host
390     * - pointer reason
391     * output - NONE
392     * side effects -
393     */
394     static void
395     set_local_gline(const struct Client *source_p, const char *user,
396     const char *host, const char *reason)
397     {
398     char buffer[IRCD_BUFSIZE];
399     struct ConfItem *conf;
400     struct AccessItem *aconf;
401     const char *current_date;
402     time_t cur_time;
403    
404     set_time();
405     cur_time = CurrentTime;
406    
407     current_date = smalldate(cur_time);
408     conf = make_conf_item(GLINE_TYPE);
409     aconf = (struct AccessItem *)map_to_conf(conf);
410    
411     ircsprintf(buffer, "%s (%s)", reason, current_date);
412     DupString(aconf->reason, buffer);
413     DupString(aconf->user, user);
414     DupString(aconf->host, host);
415    
416     aconf->hold = CurrentTime + ConfigFileEntry.gline_time;
417     add_temp_line(conf);
418    
419     sendto_realops_flags(UMODE_ALL, L_ALL,
420     "%s added G-Line for [%s@%s] [%s]",
421     get_oper_name(source_p),
422     aconf->user, aconf->host, aconf->reason);
423     ilog(L_TRACE, "%s added G-Line for [%s@%s] [%s]",
424     get_oper_name(source_p), aconf->user, aconf->host, aconf->reason);
425     log_oper_action(LOG_GLINE_TYPE, source_p, "[%s@%s] [%s]\n",
426     aconf->user, aconf->host, aconf->reason);
427     /* Now, activate gline against current online clients */
428     rehashed_klines = 1;
429     }
430    
431     #ifdef GLINE_VOTING
432     /* add_new_majority_gline()
433     *
434     * inputs - operator requesting gline
435     * - username covered by the gline
436     * - hostname covered by the gline
437     * - reason for the gline
438     * output - NONE
439     * side effects -
440     * This function is called once a majority of opers
441     * have agreed on a gline, and it can be placed. The
442     * information about an operator being passed to us
443     * happens to be the operator who pushed us over the
444     * "majority" level needed. See check_majority_gline()
445     * for more information.
446     */
447     static void
448     add_new_majority_gline(const struct Client *source_p,
449     const char *user, const char *host, const char *reason)
450     {
451     struct gline_pending *pending = MyMalloc(sizeof(struct gline_pending));
452    
453     strlcpy(pending->oper_nick1, source_p->name, sizeof(pending->oper_nick1));
454     strlcpy(pending->oper_user1, source_p->username, sizeof(pending->oper_user1));
455     strlcpy(pending->oper_host1, source_p->host, sizeof(pending->oper_host1));
456    
457     strlcpy(pending->oper_server1, source_p->servptr->name, sizeof(pending->oper_server1));
458    
459     strlcpy(pending->user, user, sizeof(pending->user));
460     strlcpy(pending->host, host, sizeof(pending->host));
461     strlcpy(pending->reason1, reason, sizeof(pending->reason1));
462    
463     pending->last_gline_time = CurrentTime;
464     pending->time_request1 = CurrentTime;
465    
466     dlinkAdd(pending, &pending->node, &pending_glines);
467     }
468    
469     /* check_majority_gline()
470     *
471     * inputs - source, user, host, reason
472     *
473     * output - one of three results
474     *
475     * GLINE_ALREADY_VOTED - returned if oper/server has already voted
476     * GLINE_PLACED - returned if this triggers a gline
477     * GLINE_NOT_PLACED - returned if not triggered
478     *
479     * Side effects -
480     * See if there is a majority agreement on a GLINE on the given user
481     * There must be at least 3 different opers agreeing on this GLINE
482     *
483     */
484     static int
485     check_majority_gline(const struct Client *source_p,
486     const char *user, const char *host, const char *reason)
487     {
488     dlink_node *pending_node;
489     struct gline_pending *gline_pending_ptr;
490    
491     /* if its already glined, why bother? :) -- fl_ */
492     if (find_is_glined(host, user))
493     return(GLINE_NOT_PLACED);
494    
495     /* special case condition where there are no pending glines */
496     if (dlink_list_length(&pending_glines) == 0) /* first gline request placed */
497     {
498     add_new_majority_gline(source_p, user, host, reason);
499     return(GLINE_NOT_PLACED);
500     }
501    
502     DLINK_FOREACH(pending_node, pending_glines.head)
503     {
504     gline_pending_ptr = pending_node->data;
505    
506     if ((irccmp(gline_pending_ptr->user, user) == 0) &&
507     (irccmp(gline_pending_ptr->host, host) == 0))
508     {
509     if (((irccmp(gline_pending_ptr->oper_user1, source_p->username) == 0) ||
510     (irccmp(gline_pending_ptr->oper_host1, source_p->host) == 0)) ||
511     (irccmp(gline_pending_ptr->oper_server1, source_p->servptr->name) == 0))
512     {
513     return(GLINE_ALREADY_VOTED);
514     }
515    
516     if (gline_pending_ptr->oper_user2[0] != '\0')
517     {
518     /* if two other opers on two different servers have voted yes */
519    
520     if(((irccmp(gline_pending_ptr->oper_user2, source_p->username)==0) ||
521     (irccmp(gline_pending_ptr->oper_host2, source_p->host)==0)) ||
522     (irccmp(gline_pending_ptr->oper_server2, source_p->servptr->name)==0))
523     {
524     return(GLINE_ALREADY_VOTED);
525     }
526    
527     /* trigger the gline using the original reason --fl */
528     set_local_gline(source_p, user, host, gline_pending_ptr->reason1);
529     cleanup_glines(NULL);
530     return(GLINE_PLACED);
531     }
532     else
533     {
534     strlcpy(gline_pending_ptr->oper_nick2, source_p->name,
535     sizeof(gline_pending_ptr->oper_nick2));
536     strlcpy(gline_pending_ptr->oper_user2, source_p->username,
537     sizeof(gline_pending_ptr->oper_user2));
538     strlcpy(gline_pending_ptr->oper_host2, source_p->host,
539     sizeof(gline_pending_ptr->oper_host2));
540     strlcpy(gline_pending_ptr->reason2, reason,
541     sizeof(gline_pending_ptr->reason2));
542     strlcpy(gline_pending_ptr->oper_server2, source_p->servptr->name,
543     sizeof(gline_pending_ptr->oper_server2));
544     gline_pending_ptr->last_gline_time = CurrentTime;
545     gline_pending_ptr->time_request2 = CurrentTime;
546     return(GLINE_NOT_PLACED);
547     }
548     }
549     }
550    
551     /* Didn't find this user@host gline in pending gline list
552     * so add it.
553     */
554     add_new_majority_gline(source_p, user, host, reason);
555     return(GLINE_NOT_PLACED);
556     }
557     #endif /* GLINE_VOTING */
558    
559     static int
560     remove_gline_match(const char *user, const char *host)
561     {
562     struct AccessItem *aconf;
563     dlink_node *ptr = NULL;
564     struct irc_ssaddr addr, caddr;
565     int nm_t, cnm_t, bits, cbits;
566    
567     nm_t = parse_netmask(host, &addr, &bits);
568    
569     DLINK_FOREACH(ptr, temporary_glines.head)
570     {
571     aconf = map_to_conf(ptr->data);
572     cnm_t = parse_netmask(aconf->host, &caddr, &cbits);
573    
574     if (cnm_t != nm_t || irccmp(user, aconf->user))
575     continue;
576    
577     if ((nm_t == HM_HOST && !irccmp(aconf->host, host)) ||
578     (nm_t == HM_IPV4 && bits == cbits && match_ipv4(&addr, &caddr, bits))
579     #ifdef IPV6
580     || (nm_t == HM_IPV6 && bits == cbits && match_ipv6(&addr, &caddr, bits))
581     #endif
582     )
583     {
584     dlinkDelete(ptr, &temporary_glines);
585     delete_one_address_conf(aconf->host, aconf);
586     return(1);
587     }
588     }
589    
590     return(0);
591     }
592    

Properties

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