ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_gline.c
Revision: 1247
Committed: Sat Oct 1 07:54:24 2011 UTC (13 years, 11 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_gline.c
File size: 20903 byte(s)
Log Message:
- Rewrite and cleanup half-broken logging subsystem.
  Logfile rotating is not working yet

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     *
4     * Copyright (C) 2002 by the past and present ircd coders, and others.
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19     * USA
20     */
21    
22 michael 1008 /*! \file m_gline.c
23     * \brief Includes required functions for processing the GLINE command.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1011 #include "list.h"
29 adx 30 #include "s_gline.h"
30     #include "channel.h"
31     #include "client.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 "s_bsd.h"
38     #include "s_conf.h"
39     #include "s_misc.h"
40     #include "send.h"
41     #include "fileio.h"
42     #include "s_serv.h"
43     #include "hash.h"
44     #include "parse.h"
45     #include "modules.h"
46     #include "s_log.h"
47    
48     #define GLINE_NOT_PLACED 0
49     #define GLINE_ALREADY_VOTED -1
50     #define GLINE_PLACED 1
51    
52    
53 michael 1009 /*! \brief Adds a GLINE to the configuration subsystem.
54     *
55     * \param source_p Operator requesting gline
56     * \param user Username covered by the gline
57     * \param host Hostname covered by the gline
58     * \param reason Reason for the gline
59     */
60     static void
61     set_local_gline(const struct Client *source_p, const char *user,
62     const char *host, const char *reason)
63     {
64     char buffer[IRCD_BUFSIZE];
65     struct ConfItem *conf;
66     struct AccessItem *aconf;
67 michael 1008
68    
69 michael 1009 conf = make_conf_item(GLINE_TYPE);
70     aconf = map_to_conf(conf);
71    
72     snprintf(buffer, sizeof(buffer), "%s (%s)", reason, smalldate(CurrentTime));
73     DupString(aconf->reason, buffer);
74     DupString(aconf->user, user);
75     DupString(aconf->host, host);
76    
77     aconf->hold = CurrentTime + ConfigFileEntry.gline_time;
78     add_temp_line(conf);
79    
80     sendto_realops_flags(UMODE_ALL, L_ALL,
81     "%s added G-Line for [%s@%s] [%s]",
82     get_oper_name(source_p),
83     aconf->user, aconf->host, aconf->reason);
84 michael 1247 ilog(LOG_TYPE_GLINE, "%s added G-Line for [%s@%s] [%s]",
85 michael 1009 get_oper_name(source_p), aconf->user, aconf->host, aconf->reason);
86 michael 1247
87 michael 1009 /* Now, activate gline against current online clients */
88     rehashed_klines = 1;
89     }
90    
91     /*! \brief Removes a GLINE from the configuration subsystem.
92     *
93     * \param user Username covered by the gline
94     * \param host Hostname covered by the gline
95     */
96     static int
97     remove_gline_match(const char *user, const char *host)
98     {
99     struct AccessItem *aconf;
100     dlink_node *ptr = NULL;
101     struct irc_ssaddr addr, caddr;
102     int nm_t, cnm_t, bits, cbits;
103    
104     nm_t = parse_netmask(host, &addr, &bits);
105    
106     DLINK_FOREACH(ptr, temporary_glines.head)
107     {
108     aconf = map_to_conf(ptr->data);
109     cnm_t = parse_netmask(aconf->host, &caddr, &cbits);
110    
111     if (cnm_t != nm_t || irccmp(user, aconf->user))
112     continue;
113    
114     if ((nm_t == HM_HOST && !irccmp(aconf->host, host)) ||
115     (nm_t == HM_IPV4 && bits == cbits && match_ipv4(&addr, &caddr, bits))
116     #ifdef IPV6
117     || (nm_t == HM_IPV6 && bits == cbits && match_ipv6(&addr, &caddr, bits))
118     #endif
119     )
120     {
121     dlinkDelete(ptr, &temporary_glines);
122     delete_one_address_conf(aconf->host, aconf);
123     return 1;
124     }
125     }
126    
127     return 0;
128     }
129    
130 michael 1008 /*! \brief This function is called once a majority of opers have agreed on a
131     * GLINE/GUNGLINE, and it can be placed. The information about an
132     * operator being passed to us happens to be the operator who pushed us
133     * over the "majority" level needed. See check_majority() for more
134     * information.
135 adx 30 *
136 michael 1008 * \param source_p Operator requesting gline
137     * \param user Username covered by the gline
138     * \param host Hostname covered by the gline
139     * \param reason Reason for the gline
140     * \param type Valid values are either GLINE_PENDING_ADD_TYPE, or
141     * GLINE_PENDING_DEL_TYPE
142 adx 30 */
143 michael 1008 static void
144     add_new_majority(const struct Client *source_p, const char *user,
145     const char *host, const char *reason, const unsigned int type)
146     {
147     struct gline_pending *pending = MyMalloc(sizeof(struct gline_pending));
148    
149     strlcpy(pending->vote_1.oper_nick, source_p->name, sizeof(pending->vote_1.oper_nick));
150     strlcpy(pending->vote_1.oper_user, source_p->username, sizeof(pending->vote_1.oper_user));
151     strlcpy(pending->vote_1.oper_host, source_p->host, sizeof(pending->vote_1.oper_host));
152     strlcpy(pending->vote_1.oper_server, source_p->servptr->name, sizeof(pending->vote_1.oper_server));
153    
154     strlcpy(pending->user, user, sizeof(pending->user));
155     strlcpy(pending->host, host, sizeof(pending->host));
156     strlcpy(pending->vote_1.reason, reason, sizeof(pending->vote_1.reason));
157    
158     pending->last_gline_time = CurrentTime;
159     pending->vote_1.time_request = CurrentTime;
160    
161     dlinkAdd(pending, &pending->node, &pending_glines[type]);
162     }
163    
164     /*! \brief See if there is a majority agreement on a GLINE on the given user.
165     * There must be at least 3 different opers agreeing on this
166     * GLINE/GUNGLINE
167 adx 30 *
168 michael 1008 * \param source_p Operator requesting gline
169     * \param user Username covered by the gline
170     * \param host Hostname covered by the gline
171     * \param reason Reason for the gline
172     * \param type Valid values are either GLINE_PENDING_ADD_TYPE, or
173     * GLINE_PENDING_DEL_TYPE
174     *
175     * \return
176     * - GLINE_ALREADY_VOTED returned if oper/server has already voted
177     * - GLINE_PLACED returned if this triggers a gline
178     * - GLINE_NOT_PLACED returned if not triggered
179 adx 30 */
180 michael 1008 static int
181     check_majority(const struct Client *source_p, const char *user,
182     const char *host, const char *reason, const int type)
183 adx 30 {
184 michael 1008 dlink_node *dn_ptr = NULL;
185 adx 30
186 michael 1008 cleanup_glines(NULL);
187 adx 30
188 michael 1008 /* if its already glined, why bother? :) -- fl_ */
189     if ((type == GLINE_PENDING_ADD_TYPE) && find_is_glined(host, user))
190     return GLINE_NOT_PLACED;
191    
192     DLINK_FOREACH(dn_ptr, pending_glines[type].head)
193 adx 30 {
194 michael 1008 struct gline_pending *gp_ptr = dn_ptr->data;
195 adx 30
196 michael 1008 if (irccmp(gp_ptr->user, user) ||
197     irccmp(gp_ptr->host, host))
198     continue;
199 adx 30
200 michael 1008 if ((!irccmp(gp_ptr->vote_1.oper_user, source_p->username) &&
201     !irccmp(gp_ptr->vote_1.oper_host, source_p->host)) ||
202     !irccmp(gp_ptr->vote_1.oper_server, source_p->servptr->name))
203     return GLINE_ALREADY_VOTED;
204    
205     if (gp_ptr->vote_2.oper_user[0] != '\0')
206 adx 30 {
207 michael 1008 /* if two other opers on two different servers have voted yes */
208     if ((!irccmp(gp_ptr->vote_2.oper_user, source_p->username) &&
209     !irccmp(gp_ptr->vote_2.oper_host, source_p->host)) ||
210     !irccmp(gp_ptr->vote_2.oper_server, source_p->servptr->name))
211     return GLINE_ALREADY_VOTED;
212    
213     if (type == GLINE_PENDING_DEL_TYPE)
214     {
215     if (remove_gline_match(user, host))
216     {
217     sendto_realops_flags(UMODE_ALL, L_ALL,
218     "%s has removed the G-Line for: [%s@%s]",
219     get_oper_name(source_p), user, host);
220 michael 1247 ilog(LOG_TYPE_GLINE, "%s removed G-Line for [%s@%s]",
221 michael 1008 get_oper_name(source_p), user, host);
222     }
223     }
224     else
225     /* trigger the gline using the original reason --fl */
226     set_local_gline(source_p, user, host, gp_ptr->vote_1.reason);
227    
228     cleanup_glines(gp_ptr);
229     return GLINE_PLACED;
230 adx 30 }
231 michael 1008
232     strlcpy(gp_ptr->vote_2.oper_nick, source_p->name,
233     sizeof(gp_ptr->vote_2.oper_nick));
234     strlcpy(gp_ptr->vote_2.oper_user, source_p->username,
235     sizeof(gp_ptr->vote_2.oper_user));
236     strlcpy(gp_ptr->vote_2.oper_host, source_p->host,
237     sizeof(gp_ptr->vote_2.oper_host));
238     strlcpy(gp_ptr->vote_2.reason, reason,
239     sizeof(gp_ptr->vote_2.reason));
240     strlcpy(gp_ptr->vote_2.oper_server, source_p->servptr->name,
241     sizeof(gp_ptr->vote_2.oper_server));
242     gp_ptr->last_gline_time = CurrentTime;
243     gp_ptr->vote_2.time_request = CurrentTime;
244     return GLINE_NOT_PLACED;
245 adx 30 }
246    
247 michael 552 /*
248 michael 1008 * Didn't find this user@host gline in pending gline list
249     * so add it.
250 adx 30 */
251 michael 1008 add_new_majority(source_p, user, host, reason, type);
252     return GLINE_NOT_PLACED;
253 adx 30 }
254    
255     static void
256 michael 1008 do_sgline(struct Client *source_p, int parc, char *parv[], int prop)
257 adx 30 {
258     const char *reason = NULL; /* reason for "victims" demise */
259     char *user = NULL;
260     char *host = NULL; /* user and host of GLINE "victim" */
261 michael 1008 int var_offset = 0, logged = 0;
262 adx 30 dlink_node *ptr;
263 michael 1008 struct Client *target_p = NULL;
264 adx 30
265 michael 1008 switch (parc)
266 adx 30 {
267 michael 1008 case 4: /* hyb-7 style */
268     if (!IsClient(source_p))
269     return;
270     break;
271     case 8: /* hyb-6 style */
272     if (!IsServer(source_p))
273     return;
274     target_p = find_person(source_p->from, parv[1]);
275     if (target_p == NULL || target_p->servptr != source_p)
276     return;
277     source_p = target_p, var_offset = 4;
278     break;
279     default:
280 adx 30 return;
281     }
282    
283     assert(source_p->servptr != NULL);
284    
285 michael 1008 user = parv[++var_offset];
286     host = parv[++var_offset];
287     reason = parv[++var_offset];
288 adx 30
289 michael 1011 var_offset = 0;
290    
291 adx 30 DLINK_FOREACH(ptr, gdeny_items.head)
292     {
293 michael 1008 struct ConfItem *conf = ptr->data;
294     struct AccessItem *aconf = map_to_conf(conf);
295 adx 30
296     if (match(conf->name, source_p->servptr->name) &&
297     match(aconf->user, source_p->username) &&
298     match(aconf->host, source_p->host))
299     {
300     var_offset = aconf->flags;
301     break;
302     }
303     }
304    
305     if (prop && !(var_offset & GDENY_BLOCK))
306     {
307 michael 1008 sendto_server(source_p->from, NULL, CAP_GLN, NOCAPS,
308 adx 30 ":%s GLINE %s %s :%s",
309     source_p->name, user, host, reason);
310     /* hyb-6 version to the rest */
311 michael 1008 sendto_server(source_p->from, NULL, NOCAPS, CAP_GLN,
312 adx 30 ":%s GLINE %s %s %s %s %s %s :%s",
313     source_p->servptr->name,
314     source_p->name, source_p->username, source_p->host,
315     source_p->servptr->name,
316     user, host, reason);
317     }
318     else if (ConfigFileEntry.gline_logging & GDENY_BLOCK && ServerInfo.hub)
319     {
320     sendto_realops_flags(UMODE_ALL, L_ALL, "Blocked G-Line %s requested on [%s@%s] [%s]",
321     get_oper_name(source_p), user, host, reason);
322 michael 1247 ilog(LOG_TYPE_GLINE, "Blocked G-Line %s requested on [%s@%s] [%s]",
323 adx 30 get_oper_name(source_p), user, host, reason);
324     logged = 1;
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 michael 1247 ilog(LOG_TYPE_GLINE, "Rejected G-Line %s requested on [%s@%s] [%s]",
334 adx 30 get_oper_name(source_p), user, host, reason);
335     }
336 michael 958
337 adx 30 return;
338     }
339    
340     if (ConfigFileEntry.glines)
341     {
342 michael 1243 if (!valid_wild_card(source_p, 1, 2, user, host))
343 adx 30 return;
344    
345     if (IsClient(source_p))
346     {
347     const char *p = NULL;
348 michael 958
349 adx 30 if ((p = strchr(host, '/')))
350     {
351     int bitlen = strtol(++p, NULL, 10);
352     int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
353     ConfigFileEntry.gline_min_cidr;
354    
355     if (bitlen < min_bitlen)
356     {
357     sendto_realops_flags(UMODE_ALL, L_ALL, "%s!%s@%s on %s is requesting "
358     "a GLINE with a CIDR mask < %d for [%s@%s] [%s]",
359     source_p->name, source_p->username, source_p->host,
360     source_p->servptr->name, min_bitlen, user, host, reason);
361     return;
362     }
363     }
364     }
365    
366     /* If at least 3 opers agree this user should be G lined then do it */
367 michael 988 if (check_majority(source_p, user, host, reason, GLINE_PENDING_ADD_TYPE) ==
368 adx 30 GLINE_ALREADY_VOTED)
369     {
370     sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
371     return;
372     }
373    
374 michael 554 sendto_realops_flags(UMODE_ALL, L_ALL,
375     "%s requesting G-Line for [%s@%s] [%s]",
376     get_oper_name(source_p),
377     user, host, reason);
378 michael 1247 ilog(LOG_TYPE_GLINE, "#gline for %s@%s [%s] requested by %s",
379 adx 30 user, host, reason, get_oper_name(source_p));
380     }
381     }
382    
383 michael 1008
384     /*! \brief GLINE command handler (called by operators)
385 adx 30 *
386 michael 1008 * \param client_p Pointer to allocated Client struct with physical connection
387     * to this server, i.e. with an open socket connected.
388     * \param source_p Pointer to allocated Client struct from which the message
389     * originally comes from. This can be a local or remote client.
390     * \param parc Integer holding the number of supplied arguments.
391     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
392     * pointers.
393     * \note Valid arguments for this command are:
394     * - parv[0] = sender prefix
395     * - parv[1] = user\@host mask
396     * - parv[2] = reason
397 adx 30 */
398     static void
399 michael 1008 mo_gline(struct Client *client_p, struct Client *source_p,
400     int parc, char *parv[])
401 adx 30 {
402 michael 1008 char *user = NULL;
403     char *host = NULL;
404     char *reason = NULL;
405     char *p;
406 adx 30
407 michael 1008 if (!ConfigFileEntry.glines)
408     {
409     sendto_one(source_p, ":%s NOTICE %s :GLINE disabled",
410     me.name, source_p->name);
411     return;
412     }
413 adx 30
414 michael 1219 if (!HasOFlag(source_p, OPER_FLAG_GLINE))
415 michael 1008 {
416     sendto_one(source_p, form_str(ERR_NOPRIVS),
417     me.name, source_p->name, "gline");
418     return;
419     }
420 adx 30
421 michael 1008 if (parse_aline("GLINE", source_p, parc, parv, AWILD,
422     &user, &host, NULL, NULL, &reason) < 0)
423     return;
424 adx 30
425 michael 1008 if ((p = strchr(host, '/')) != NULL)
426 adx 30 {
427 michael 1008 int bitlen = strtol(++p, NULL, 10);
428     int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
429     ConfigFileEntry.gline_min_cidr;
430     if (bitlen < min_bitlen)
431 adx 30 {
432 michael 1008 sendto_one(source_p, ":%s NOTICE %s :Cannot set G-Lines with CIDR length < %d",
433     me.name, source_p->name, min_bitlen);
434     return;
435 michael 957 }
436 adx 30 }
437 michael 1008
438     /* If at least 3 opers agree this user should be G lined then do it */
439     if (check_majority(source_p, user, host, reason, GLINE_PENDING_ADD_TYPE) ==
440     GLINE_ALREADY_VOTED)
441     {
442     sendto_one(source_p,
443     ":%s NOTICE %s :This server or oper has already voted",
444     me.name, source_p->name);
445     return;
446     }
447 adx 30
448 michael 957 /*
449 michael 1008 * call these two functions first so the 'requesting' notice always comes
450     * before the 'has triggered' notice. -bill
451 adx 30 */
452 michael 1008 sendto_realops_flags(UMODE_ALL, L_ALL,
453     "%s requesting G-Line for [%s@%s] [%s]",
454     get_oper_name(source_p),
455     user, host, reason);
456 michael 1247 ilog(LOG_TYPE_GLINE, "#gline for %s@%s [%s] requested by %s!%s@%s",
457 michael 1008 user, host, reason, source_p->name, source_p->username,
458     source_p->host);
459 adx 30
460 michael 1008 /* 4 param version for hyb-7 servers */
461     sendto_server(NULL, NULL, CAP_GLN|CAP_TS6, NOCAPS,
462     ":%s GLINE %s %s :%s",
463     ID(source_p), user, host, reason);
464     sendto_server(NULL, NULL, CAP_GLN, CAP_TS6,
465     ":%s GLINE %s %s :%s",
466     source_p->name, user, host, reason);
467 adx 30
468 michael 1008 /* 8 param for hyb-6 */
469     sendto_server(NULL, NULL, CAP_TS6, CAP_GLN,
470     ":%s GLINE %s %s %s %s %s %s :%s",
471     ID(&me),
472     ID(source_p), source_p->username,
473     source_p->host, source_p->servptr->name, user, host,
474     reason);
475     sendto_server(NULL, NULL, NOCAPS, CAP_GLN|CAP_TS6,
476     ":%s GLINE %s %s %s %s %s %s :%s",
477     me.name, source_p->name, source_p->username,
478     source_p->host, source_p->servptr->name, user, host,
479     reason);
480 adx 30 }
481    
482 michael 1008 /* ms_gline()
483     * me_gline()
484     * do_sgline()
485 db 937 *
486     * inputs - The usual for a m_ function
487     * output -
488     * side effects -
489     *
490 michael 1008 * Place a G line if 3 opers agree on the identical user@host
491 db 937 *
492 michael 1008 * Allow this server to pass along GLINE if received and
493     * GLINES is not defined.
494     *
495     * ENCAP'd GLINES are propagated by encap code.
496 db 937 */
497    
498     static void
499 michael 1008 ms_gline(struct Client *client_p, struct Client *source_p,
500     int parc, char *parv[])
501 db 937 {
502 michael 1008 do_sgline(source_p, parc, parv, 1);
503 db 937 }
504    
505     static void
506 michael 1008 me_gline(struct Client *client_p, struct Client *source_p,
507     int parc, char *parv[])
508     {
509     do_sgline(source_p, parc, parv, 0);
510     }
511    
512     static void
513 michael 1006 do_sungline(struct Client *source_p, const char *user,
514     const char *host, const char *reason, int prop)
515 db 937 {
516     assert(source_p->servptr != NULL);
517    
518 michael 957 sendto_realops_flags(UMODE_ALL, L_ALL,
519     "%s requesting UNG-Line for [%s@%s] [%s]",
520 michael 1006 get_oper_name(source_p), user, host, reason);
521 michael 1247 ilog(LOG_TYPE_GLINE, "#ungline for %s@%s [%s] requested by %s",
522 michael 957 user, host, reason, get_oper_name(source_p));
523 db 937
524 michael 957 /* If at least 3 opers agree this user should be un G lined then do it */
525 michael 958 if (check_majority(source_p, user, host, reason, GLINE_PENDING_DEL_TYPE) ==
526 michael 957 GLINE_ALREADY_VOTED)
527     sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
528 michael 1006
529     if (prop)
530     {
531     sendto_server(source_p->from, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
532     ":%s ENCAP * GUNGLINE %s %s :%s",
533     ID(source_p), user, host, reason);
534     sendto_server(source_p->from, NULL, CAP_ENCAP, CAP_TS6,
535     ":%s ENCAP * GUNGLINE %s %s :%s",
536     source_p->name, user, host, reason);
537     }
538 db 937 }
539    
540 michael 1008 /*! \brief GUNGLINE command handler (called in response to an encapsulated
541     * GUNGLINE command)
542 db 937 *
543 michael 1008 * \param client_p Pointer to allocated Client struct with physical connection
544     * to this server, i.e. with an open socket connected.
545     * \param source_p Pointer to allocated Client struct from which the message
546     * originally comes from. This can be a local or remote client.
547     * \param parc Integer holding the number of supplied arguments.
548     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
549     * pointers.
550     * \note Valid arguments for this command are:
551     * - parv[0] = sender prefix
552     * - parv[1] = username
553     * - parv[2] = hostname
554     * - parv[3] = reason
555 db 937 */
556 michael 1008 static void
557     me_gungline(struct Client *client_p, struct Client *source_p,
558     int parc, char *parv[])
559     {
560     if (ConfigFileEntry.glines)
561     do_sungline(source_p, parv[1], parv[2], parv[3], 0);
562     }
563    
564     /*! \brief GUNGLINE command handler (called by operators)
565 db 937 *
566 michael 1008 * \param client_p Pointer to allocated Client struct with physical connection
567     * to this server, i.e. with an open socket connected.
568     * \param source_p Pointer to allocated Client struct from which the message
569     * originally comes from. This can be a local or remote client.
570     * \param parc Integer holding the number of supplied arguments.
571     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
572     * pointers.
573     * \note Valid arguments for this command are:
574     * - parv[0] = sender prefix
575     * - parv[1] = user\@host mask
576     * - parv[2] = reason
577 db 937 */
578     static void
579 db 940 mo_gungline(struct Client *client_p, struct Client *source_p,
580 michael 957 int parc, char *parv[])
581 db 937 {
582     char *user = NULL;
583 michael 1008 char *host = NULL;
584     char *reason = NULL;
585 db 937
586     if (!ConfigFileEntry.glines)
587     {
588 michael 957 sendto_one(source_p, ":%s NOTICE %s :GUNGLINE disabled",
589 db 937 me.name, source_p->name);
590     return;
591     }
592    
593 michael 1219 if (!HasOFlag(source_p, OPER_FLAG_GLINE))
594 db 937 {
595     sendto_one(source_p, form_str(ERR_NOPRIVS),
596 michael 957 me.name, source_p->name, "gungline");
597 db 937 return;
598     }
599    
600 michael 957 if (parse_aline("GUNGLINE", source_p, parc, parv, 0, &user,
601     &host, NULL, NULL, &reason) < 0)
602 db 937 return;
603    
604 michael 1006 do_sungline(source_p, user, host, reason, 1);
605 db 937 }
606 michael 1230
607     /*
608     * gline enforces 3 parameters to force operator to give a reason
609     * a gline is not valid with "No reason"
610     * -db
611     */
612     static struct Message gline_msgtab = {
613     "GLINE", 0, 0, 3, MAXPARA, MFLG_SLOW, 0,
614     { m_unregistered, m_not_oper, ms_gline, me_gline, mo_gline, m_ignore }
615     };
616    
617     static struct Message ungline_msgtab = {
618     "GUNGLINE", 0, 0, 3, MAXPARA, MFLG_SLOW, 0,
619     { m_unregistered, m_not_oper, m_ignore, me_gungline, mo_gungline, m_ignore }
620     };
621    
622     static void
623     module_init(void)
624     {
625     mod_add_cmd(&gline_msgtab);
626     mod_add_cmd(&ungline_msgtab);
627     add_capability("GLN", CAP_GLN, 1);
628     }
629    
630     static void
631     module_exit(void)
632     {
633     mod_del_cmd(&gline_msgtab);
634     mod_del_cmd(&ungline_msgtab);
635     delete_capability("GLN");
636     }
637    
638     struct module module_entry = {
639     .node = { NULL, NULL, NULL },
640     .name = NULL,
641     .version = "$Revision$",
642     .handle = NULL,
643     .modinit = module_init,
644     .modexit = module_exit,
645     .flags = 0
646     };

Properties

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