ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_gline.c
Revision: 1369
Committed: Wed Apr 25 19:04:19 2012 UTC (14 years, 5 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_gline.c
File size: 20675 byte(s)
Log Message:
- cleanup temporary k/d/g line code

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

Properties

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