]>
jfr.im git - irc/quakenet/newserv.git/blob - channel/channelbans.c
8 #include "../nick/nick.h"
9 #include "../lib/irc_string.h"
10 #include "../irc/irc_config.h"
11 #include "../irc/irc.h"
15 * Returns true iff the supplied nick* matches the supplied ban*
18 int nickmatchban(nick
*np
, chanban
*bp
) {
20 char fakehost
[HOSTLEN
+1];
22 /* nick/ident section: return 0 (no match) if they don't match */
24 if (bp
->flags
& CHANBAN_INVALID
)
27 if (bp
->flags
& CHANBAN_USEREXACT
&&
28 ircd_strcmp(np
->ident
,bp
->user
->content
) &&
29 (!IsSetHost(np
) || !np
->shident
||
30 ircd_strcmp(np
->shident
->content
,bp
->user
->content
)))
33 if (bp
->flags
& CHANBAN_NICKEXACT
&& ircd_strcmp(np
->nick
,bp
->nick
->content
))
36 if (bp
->flags
& CHANBAN_USERMASK
&&
37 !match2strings(bp
->user
->content
,np
->ident
) &&
38 (!IsSetHost(np
) || !np
->shident
||
39 !match2strings(bp
->user
->content
, np
->shident
->content
)))
42 if (bp
->flags
& CHANBAN_NICKMASK
&& !match2strings(bp
->nick
->content
,np
->nick
))
45 /* host section. Return 1 (match) if they do match
46 * Note that if user or ident was specified, they've already been checked
49 if (bp
->flags
& CHANBAN_HOSTANY
)
52 if ((bp
->flags
& CHANBAN_CIDR
) && (bp
->flags
& CHANBAN_HOSTEXACT
)) {
56 /* CIDR bans don't match IPv6 hosts */
57 if (!irc_in_addr_is_ipv4(&(np
->p_ipaddr
)))
60 /* Extract the client's IP address into a usable format */
61 ch
=(unsigned char *)&(np
->p_ipaddr
.in6_16
[6]);
62 cip
=(ch
[0]<<24) | (ch
[1]<<16) | (ch
[2]<<8) | (ch
[3]);
64 if ((cip
& bp
->mask
) == bp
->ipaddr
)
67 return 0; /* A CIDR ban won't match any other way */
70 if (bp
->flags
& CHANBAN_IP
) {
71 if (bp
->flags
& CHANBAN_HOSTEXACT
) {
72 /* If it's an exact IP ban we can compare it numerically */
76 /* Well, it won't match if it's not an IPv4 host */
77 if (!irc_in_addr_is_ipv4(&(np
->p_ipaddr
)))
80 /* Extract the client's IP address into a usable format */
81 ch
=(unsigned char *)&(np
->p_ipaddr
.in6_16
[6]);
82 cip
=(ch
[0]<<24) | (ch
[1]<<16) | (ch
[2]<<8) | (ch
[3]);
87 /* It's not an exact IP ban so let's generate the string */
88 ipstring
=IPtostr(np
->p_ipaddr
);
90 if (bp
->flags
& CHANBAN_HOSTMASK
&& match2strings(bp
->host
->content
,ipstring
))
94 /* Hostname bans need to be checked against +x host, +h host (if set)
95 * and actual host. Note that the +x host is only generated (and checked) if it's
96 * possible for the ban to match a hidden host.. */
98 if ((bp
->flags
& CHANBAN_HIDDENHOST
) && IsAccount(np
)) {
99 sprintf(fakehost
,"%s.%s",np
->authname
, HIS_HIDDENHOST
);
101 if ((bp
->flags
& CHANBAN_HOSTEXACT
) &&
102 !ircd_strcmp(fakehost
, bp
->host
->content
))
105 if ((bp
->flags
& CHANBAN_HOSTMASK
) &&
106 match2strings(bp
->host
->content
, fakehost
))
111 if ((bp
->flags
& CHANBAN_HOSTEXACT
) &&
112 !ircd_strcmp(np
->sethost
->content
, bp
->host
->content
))
115 if ((bp
->flags
& CHANBAN_HOSTMASK
) &&
116 match2strings(bp
->host
->content
, np
->sethost
->content
))
120 if (bp
->flags
& CHANBAN_HOSTEXACT
&& !ircd_strcmp(np
->host
->name
->content
,bp
->host
->content
))
123 if (bp
->flags
& CHANBAN_HOSTMASK
&& match2strings(bp
->host
->content
,np
->host
->name
->content
))
132 * Returns true iff the supplied nick* is banned on the supplied chan*
135 int nickbanned(nick
*np
, channel
*cp
) {
138 for (cbp
=cp
->bans
;cbp
;cbp
=cbp
->next
) {
139 if (nickmatchban(np
,cbp
))
148 * Set the specified ban; if it completely encloses any existing bans
151 * Returns 1 if the ban was set, or 0 if the ban was not set because an
152 * existing ban overlapped it.
155 int setban(channel
*cp
, const char *ban
) {
156 chanban
**cbh
,*cbp
,*cbp2
;
160 /* Don't set our ban if something encloses it */
161 for (cbp2
=cp
->bans
;cbp2
;cbp2
=cbp2
->next
) {
162 if (banoverlap(cbp2
, cbp
)) {
163 /* This ban overlaps the one we are adding. Abort. */
169 /* Remove enclosed bans first */
170 for (cbh
=&(cp
->bans
);*cbh
;) {
171 if (banoverlap(cbp
,*cbh
)) {
175 /* Break out of the loop if we just deleted the last ban */
180 cbh
=(chanban
**)&((*cbh
)->next
);
184 /* Now set the new ban */
185 cbp
->next
=(struct chanban
*)cp
->bans
;
193 * Remove the specified ban iff an exact match is found
194 * Returns 1 if the ban was cleared, 0 if the ban didn't exist.
195 * If "optional" is 0 and the ban didn't exist, flags an error
198 int clearban(channel
*cp
, const char *ban
, int optional
) {
199 chanban
**cbh
,*cbp
,*cbp2
;
208 for (cbh
=&(cp
->bans
);*cbh
;cbh
=(chanban
**)&((*cbh
)->next
)) {
209 if (banequal(cbp
,*cbh
)) {
218 if (!found
&& !optional
) {
219 Error("channel",ERR_DEBUG
,"Couldn't remove ban %s from %s. Dumping banlist:",ban
,cp
->index
->name
->content
);
220 for (cbp2
=cp
->bans
;cbp2
;cbp2
=cbp2
->next
) {
221 Error("channel",ERR_DEBUG
,"%s %d %s",cp
->index
->name
->content
, i
++, bantostringdebug(cbp2
));
232 * Just free all the bans on the channel
235 void clearallbans(channel
*cp
) {
238 for (cbp
=cp
->bans
;cbp
;cbp
=ncbp
) {
239 ncbp
=(chanban
*)cbp
->next
;