]>
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"
12 #include "../lib/irc_ipv6.h"
16 * Returns true iff the supplied nick* matches the supplied ban*
18 * "visibleonly" flag indicates that we shouldn't check against the real
19 * host if it's masked.
22 int nickmatchban(nick
*np
, chanban
*bp
, int visibleonly
) {
23 char fakehost
[HOSTLEN
+1];
26 /* If it's not valid, don't bother */
27 if (bp
->flags
& CHANBAN_INVALID
)
30 /* nick/ident section: return 0 (no match) if they don't match */
32 /* Pick up the visible username. If a sethost username is set, the real
33 * username is not checked. */
35 if (IsSetHost(np
) && np
->shident
)
36 ident
=np
->shident
->content
;
38 if (bp
->flags
& CHANBAN_USEREXACT
&&
39 ircd_strcmp(ident
,bp
->user
->content
))
42 if (bp
->flags
& CHANBAN_NICKEXACT
&& ircd_strcmp(np
->nick
,bp
->nick
->content
))
45 if (bp
->flags
& CHANBAN_USERMASK
&&
46 !match2strings(bp
->user
->content
,ident
))
49 if (bp
->flags
& CHANBAN_NICKMASK
&& !match2strings(bp
->nick
->content
,np
->nick
))
52 /* host section. Return 1 (match) if they do match
53 * Note that if user or ident was specified, they've already been checked
56 if (bp
->flags
& CHANBAN_HOSTANY
)
59 /* "visibleonly" means don't check IP/realhost if they are sethosted/+x.
60 * We change this to mean "Don't check IP/realhost unconditionally" - by
61 * clearing it to 0 if the user isn't sethosted or +x. Simplifies logic
64 if (!(IsSetHost(np
) || (IsAccount(np
) && IsHideHost(np
))))
67 if ((bp
->flags
& CHANBAN_IP
) && !visibleonly
) {
68 if (ipmask_check(&(np
->ipnode
->prefix
->sin
), &(bp
->ipaddr
), bp
->prefixlen
))
72 /* Hostname bans need to be checked against +x host, +h host (if set)
73 * and actual host. Note that the +x host is only generated (and checked) if it's
74 * possible for the ban to match a hidden host. And it's checked regardless
75 * of whether the user is actually +x. */
77 if ((bp
->flags
& CHANBAN_HIDDENHOST
) && IsAccount(np
)) {
78 sprintf(fakehost
,"%s.%s",np
->authname
, HIS_HIDDENHOST
);
80 if ((bp
->flags
& CHANBAN_HOSTEXACT
) &&
81 !ircd_strcmp(fakehost
, bp
->host
->content
))
84 if ((bp
->flags
& CHANBAN_HOSTMASK
) &&
85 match2strings(bp
->host
->content
, fakehost
))
90 if ((bp
->flags
& CHANBAN_HOSTEXACT
) &&
91 !ircd_strcmp(np
->sethost
->content
, bp
->host
->content
))
94 if ((bp
->flags
& CHANBAN_HOSTMASK
) &&
95 match2strings(bp
->host
->content
, np
->sethost
->content
))
99 /* If we are only checking visible host and the host is somehow masked, don't check
100 * against the real one. */
104 if (bp
->flags
& CHANBAN_HOSTEXACT
&& !ircd_strcmp(np
->host
->name
->content
,bp
->host
->content
))
107 if (bp
->flags
& CHANBAN_HOSTMASK
&& match2strings(bp
->host
->content
,np
->host
->name
->content
))
115 * Returns true iff the supplied nick* is banned on the supplied chan*
117 * Pass the visibleonly flag on to nickbanned().
119 int nickbanned(nick
*np
, channel
*cp
, int visibleonly
) {
122 for (cbp
=cp
->bans
;cbp
;cbp
=cbp
->next
) {
123 if (nickmatchban(np
,cbp
,visibleonly
))
132 * Set the specified ban; if it completely encloses any existing bans
135 * Returns 1 if the ban was set, or 0 if the ban was not set because an
136 * existing ban overlapped it.
139 int setban(channel
*cp
, const char *ban
) {
140 chanban
**cbh
,*cbp
,*cbp2
;
144 /* Don't set our ban if something encloses it */
145 for (cbp2
=cp
->bans
;cbp2
;cbp2
=cbp2
->next
) {
146 if (banoverlap(cbp2
, cbp
)) {
147 /* This ban overlaps the one we are adding. Abort. */
153 /* Remove enclosed bans first */
154 for (cbh
=&(cp
->bans
);*cbh
;) {
155 if (banoverlap(cbp
,*cbh
)) {
159 /* Break out of the loop if we just deleted the last ban */
164 cbh
=(chanban
**)&((*cbh
)->next
);
168 /* Now set the new ban */
169 cbp
->next
=(struct chanban
*)cp
->bans
;
177 * Remove the specified ban iff an exact match is found
178 * Returns 1 if the ban was cleared, 0 if the ban didn't exist.
179 * If "optional" is 0 and the ban didn't exist, flags an error
182 int clearban(channel
*cp
, const char *ban
, int optional
) {
183 chanban
**cbh
,*cbp
,*cbp2
;
192 for (cbh
=&(cp
->bans
);*cbh
;cbh
=(chanban
**)&((*cbh
)->next
)) {
193 if (banequal(cbp
,*cbh
)) {
202 if (!found
&& !optional
) {
203 Error("channel",ERR_DEBUG
,"Couldn't remove ban %s from %s. Dumping banlist:",ban
,cp
->index
->name
->content
);
204 for (cbp2
=cp
->bans
;cbp2
;cbp2
=cbp2
->next
) {
205 Error("channel",ERR_DEBUG
,"%s %d %s",cp
->index
->name
->content
, i
++, bantostringdebug(cbp2
));
216 * Just free all the bans on the channel
219 void clearallbans(channel
*cp
) {
222 for (cbp
=cp
->bans
;cbp
;cbp
=ncbp
) {
223 ncbp
=(chanban
*)cbp
->next
;