2 * ircd-ratbox: A slightly useful ircd.
3 * m_dline.c: Bans/unbans a user.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
34 #include "s_newconf.h"
45 static const char dline_desc
[] = "Provides the DLINE facility to ban users via IP address";
47 static void mo_dline(struct MsgBuf
*, struct Client
*, struct Client
*, int, const char **);
48 static void me_dline(struct MsgBuf
*, struct Client
*, struct Client
*, int, const char **);
49 static void mo_undline(struct MsgBuf
*, struct Client
*, struct Client
*, int, const char **);
50 static void me_undline(struct MsgBuf
*, struct Client
*, struct Client
*, int, const char **);
52 struct Message dline_msgtab
= {
54 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, {me_dline
, 4}, {mo_dline
, 2}}
57 struct Message undline_msgtab
= {
58 "UNDLINE", 0, 0, 0, 0,
59 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, {me_undline
, 2}, {mo_undline
, 2}}
62 mapi_clist_av1 dline_clist
[] = { &dline_msgtab
, &undline_msgtab
, NULL
};
64 DECLARE_MODULE_AV2(dline
, NULL
, NULL
, dline_clist
, NULL
, NULL
, NULL
, NULL
, dline_desc
);
66 static bool remove_temp_dline(struct ConfItem
*);
67 static void apply_dline(struct Client
*, const char *, int, char *);
68 static void apply_undline(struct Client
*, const char *);
72 * parv[1] - dline to add
76 mo_dline(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
78 char def
[] = "No Reason";
82 const char *target_server
= NULL
;
85 if(!IsOperK(source_p
))
87 sendto_one(source_p
, form_str(ERR_NOPRIVS
), me
.name
, source_p
->name
, "kline");
91 if((tdline_time
= valid_temp_time(parv
[loc
])) >= 0)
96 sendto_one_notice(source_p
, ":Need an IP to D-Line");
103 /* would break the protocol */
106 sendto_one_notice(source_p
, ":Invalid D-Line [%s] - IP cannot start with :", dlhost
);
110 int ty
= parse_netmask_strict(dlhost
, NULL
, NULL
);
111 if (ty
!= HM_IPV4
&& ty
!= HM_IPV6
)
113 sendto_one_notice(source_p
, ":Invalid D-Line [%s] - doesn't look like IP[/cidr]", dlhost
);
117 if(parc
>= loc
+ 2 && !irccmp(parv
[loc
], "ON"))
119 if(!IsOperRemoteBan(source_p
))
121 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
122 me
.name
, source_p
->name
, "remoteban");
126 target_server
= parv
[loc
+ 1];
130 if(parc
>= loc
+ 1 && !EmptyString(parv
[loc
]))
131 reason
= LOCAL_COPY(parv
[loc
]);
133 if(target_server
!= NULL
)
135 sendto_match_servs(source_p
, target_server
,
137 "ENCAP %s DLINE %d %s :%s",
138 target_server
, tdline_time
, dlhost
, reason
);
140 if(!match(target_server
, me
.name
))
144 apply_dline(source_p
, dlhost
, tdline_time
, reason
);
151 * parv[1] = dline to remove
154 mo_undline(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
157 const char *target_server
= NULL
;
159 if(!IsOperK(source_p
))
161 sendto_one(source_p
, form_str(ERR_NOPRIVS
), me
.name
, source_p
->name
, "unkline");
167 if(parc
>= 4 && !irccmp(parv
[2], "ON"))
169 if(!IsOperRemoteBan(source_p
))
171 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
172 me
.name
, source_p
->name
, "remoteban");
176 target_server
= parv
[3];
177 sendto_match_servs(source_p
, target_server
,
178 CAP_ENCAP
, NOCAPS
, "ENCAP %s UNDLINE %s", target_server
, cidr
);
180 if(!match(target_server
, me
.name
))
184 apply_undline(source_p
, cidr
);
188 me_dline(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
190 int tdline_time
= atoi(parv
[1]);
191 /* Since this is coming over a server link, assume that the originating
192 * server did the relevant permission/sanity checks...
195 if(!IsPerson(source_p
))
198 apply_dline(source_p
, parv
[2], tdline_time
, LOCAL_COPY(parv
[3]));
204 me_undline(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
206 if(!IsPerson(source_p
))
209 apply_undline(source_p
, parv
[1]);
213 apply_dline(struct Client
*source_p
, const char *dlhost
, int tdline_time
, char *reason
)
215 struct ConfItem
*aconf
;
217 struct rb_sockaddr_storage daddr
;
218 int t
= AF_INET
, ty
, b
;
221 ty
= parse_netmask_strict(dlhost
, &daddr
, &b
);
222 if(ty
!= HM_IPV4
&& ty
!= HM_IPV6
)
224 sendto_one(source_p
, ":%s NOTICE %s :Invalid D-Line", me
.name
, source_p
->name
);
232 /* This means dlines wider than /16 cannot be set remotely */
233 if(IsOperAdmin(source_p
))
237 sendto_one_notice(source_p
,
238 ":For safety, bitmasks less than 8 require conf access.");
246 sendto_one_notice(source_p
,
247 ":Dline bitmasks less than 16 are for admins only.");
252 if(ConfigFileEntry
.non_redundant_klines
)
254 if((aconf
= find_dline((struct sockaddr
*) &daddr
, t
)) != NULL
)
257 int masktype
= parse_netmask_strict(aconf
->host
, NULL
, &bx
);
259 if (masktype
!= HM_ERROR
&& b
>= bx
)
261 creason
= aconf
->passwd
? aconf
->passwd
: "<No Reason>";
262 if(IsConfExemptKline(aconf
))
264 ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
265 me
.name
, source_p
->name
, dlhost
, aconf
->host
,
269 ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
270 me
.name
, source_p
->name
, dlhost
, aconf
->host
,
280 aconf
->status
= CONF_DLINE
;
281 aconf
->created
= rb_current_time();
282 aconf
->host
= rb_strdup(dlhost
);
283 aconf
->passwd
= rb_strdup(reason
);
284 aconf
->info
.oper
= operhash_add(get_oper_name(source_p
));
286 if(strlen(reason
) > BANREASONLEN
)
287 reason
[BANREASONLEN
] = '\0';
289 /* Look for an oper reason */
290 if((oper_reason
= strchr(reason
, '|')) != NULL
)
295 if(!EmptyString(oper_reason
))
296 aconf
->spasswd
= rb_strdup(oper_reason
);
301 aconf
->hold
= rb_current_time() + tdline_time
;
302 add_temp_dline(aconf
);
304 if(EmptyString(oper_reason
))
306 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
307 "%s added temporary %d min. D-Line for [%s] [%s]",
308 get_oper_name(source_p
), tdline_time
/ 60,
309 aconf
->host
, reason
);
310 ilog(L_KLINE
, "D %s %d %s %s",
311 get_oper_name(source_p
), tdline_time
/ 60, aconf
->host
, reason
);
315 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
316 "%s added temporary %d min. D-Line for [%s] [%s|%s]",
317 get_oper_name(source_p
), tdline_time
/ 60,
318 aconf
->host
, reason
, oper_reason
);
319 ilog(L_KLINE
, "D %s %d %s %s|%s",
320 get_oper_name(source_p
), tdline_time
/ 60,
321 aconf
->host
, reason
, oper_reason
);
324 sendto_one(source_p
, ":%s NOTICE %s :Added temporary %d min. D-Line for [%s]",
325 me
.name
, source_p
->name
, tdline_time
/ 60, aconf
->host
);
329 add_conf_by_address(aconf
->host
, CONF_DLINE
, NULL
, NULL
, aconf
);
331 bandb_add(BANDB_DLINE
, source_p
, aconf
->host
, NULL
,
332 reason
, EmptyString(aconf
->spasswd
) ? NULL
: aconf
->spasswd
, 0);
334 if(EmptyString(oper_reason
))
336 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
337 "%s added D-Line for [%s] [%s]",
338 get_oper_name(source_p
), aconf
->host
, reason
);
339 ilog(L_KLINE
, "D %s 0 %s %s",
340 get_oper_name(source_p
), aconf
->host
, reason
);
344 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
345 "%s added D-Line for [%s] [%s|%s]",
346 get_oper_name(source_p
), aconf
->host
, reason
, oper_reason
);
347 ilog(L_KLINE
, "D %s 0 %s %s|%s",
348 get_oper_name(source_p
),
349 aconf
->host
, reason
, oper_reason
);
355 apply_undline(struct Client
*source_p
, const char *cidr
)
358 struct ConfItem
*aconf
;
360 int masktype
= parse_netmask(cidr
, NULL
, NULL
);
362 if(masktype
!= HM_IPV4
&& masktype
!= HM_IPV6
)
364 sendto_one_notice(source_p
, ":Invalid D-Line [%s] - doesn't look like IP[/cidr]", cidr
);
368 aconf
= find_exact_conf_by_address(cidr
, CONF_DLINE
, NULL
);
371 sendto_one_notice(source_p
, ":No D-Line for %s", cidr
);
375 rb_strlcpy(buf
, aconf
->host
, sizeof buf
);
376 if(remove_temp_dline(aconf
))
379 ":%s NOTICE %s :Un-dlined [%s] from temporary D-lines",
380 me
.name
, source_p
->name
, buf
);
381 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
382 "%s has removed the temporary D-Line for: [%s]",
383 get_oper_name(source_p
), buf
);
384 ilog(L_KLINE
, "UD %s %s", get_oper_name(source_p
), buf
);
388 bandb_del(BANDB_DLINE
, aconf
->host
, NULL
);
390 sendto_one(source_p
, ":%s NOTICE %s :D-Line for [%s] is removed", me
.name
, source_p
->name
,
392 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "%s has removed the D-Line for: [%s]",
393 get_oper_name(source_p
), aconf
->host
);
394 ilog(L_KLINE
, "UD %s %s", get_oper_name(source_p
), aconf
->host
);
395 delete_one_address_conf(aconf
->host
, aconf
);
398 /* remove_temp_dline()
400 * inputs - confitem to undline
401 * outputs - true if removed, false otherwise.
402 * side effects - tries to undline anything that matches
405 remove_temp_dline(struct ConfItem
*aconf
)
410 for(i
= 0; i
< LAST_TEMP_TYPE
; i
++)
412 RB_DLINK_FOREACH(ptr
, temp_dlines
[i
].head
)
414 if(aconf
== ptr
->data
)
416 rb_dlinkDestroy(ptr
, &temp_dlines
[i
]);
417 delete_one_address_conf(aconf
->host
, aconf
);