2 # Parent b303d3fb110ec90c10a105cc533a8a0b9b2baefb
4 diff -r b303d3fb110e include/gline.h
5 --- a/include/gline.h Sat Jul 20 14:49:32 2013 +0100
6 +++ b/include/gline.h Sat Jul 20 14:50:19 2013 +0100
9 extern struct Gline *gline_find(char *userhost, unsigned int flags);
10 extern struct Gline *gline_lookup(struct Client *cptr, unsigned int flags);
11 +extern struct Gline *gline_lookup_badchan(char *userhost, unsigned int flags);
12 extern void gline_free(struct Gline *gline);
13 extern void gline_burst(struct Client *cptr);
14 extern int gline_resend(struct Client *cptr, struct Gline *gline);
15 diff -r b303d3fb110e ircd/gline.c
16 --- a/ircd/gline.c Sat Jul 20 14:49:32 2013 +0100
17 +++ b/ircd/gline.c Sat Jul 20 14:50:19 2013 +0100
24 #include "ircd_alloc.h"
25 #include "ircd_features.h"
29 /** Check local clients against a new G-line.
30 - * If the G-line is inactive or a badchan, return immediately.
31 - * Otherwise, if any users match it, disconnect them.
32 + * If the G-line is inactive, return immediately.
33 + * Otherwise, if any users match it, disconnect them or kick them if the G-line is a BADCHAN.
34 * @param[in] cptr Peer connect that sent the G-line.
35 * @param[in] sptr Client that originated the G-line.
36 * @param[in] gline New G-line to check.
38 if (feature_bool(FEAT_DISABLE_GLINES))
39 return 0; /* G-lines are disabled */
41 - if (GlineIsBadChan(gline)) /* no action taken on badchan glines */
43 if (!GlineIsActive(gline)) /* no action taken on inactive glines */
46 - for (fd = HighestFd; fd >= 0; --fd) {
50 - if ((acptr = LocalClientArray[fd])) {
51 - if (!cli_user(acptr))
53 + if (GlineIsBadChan(gline)) {
54 + /* Handle BADCHAN gline */
55 + struct Channel *chptr,*nchptr;
56 + struct Membership *member,*nmember;
58 - if (GlineIsRealName(gline)) { /* Realname Gline */
59 - Debug((DEBUG_DEBUG,"Realname Gline: %s %s",(cli_info(acptr)),
61 - if (match(gline->gl_user+2, cli_info(acptr)) != 0)
63 - Debug((DEBUG_DEBUG,"Matched!"));
64 - } else { /* Host/IP gline */
65 - if (cli_user(acptr)->username &&
66 - match(gline->gl_user, (cli_user(acptr))->realusername) != 0)
67 + for(chptr=GlobalChannelList;chptr;chptr=nchptr) {
69 + if (match(gline->gl_user, chptr->chname))
71 + for (member=chptr->members;member;member=nmember) {
72 + nmember=member->next_member;
73 + if (!MyUser(member->user) || IsZombie(member) || IsAnOper(member->user))
75 + sendcmdto_serv_butone(&me, CMD_KICK, NULL, "%H %C :Badchanneled (%s)", chptr, member->user, gline->gl_reason);
76 + sendcmdto_channel_butserv_butone(&his, CMD_KICK, chptr, NULL, 0, "%H %C :Badchanneled (%s)", chptr, member->user, gline->gl_reason);
77 + make_zombie(member, member->user, &me, &me, chptr);
82 + for (fd = HighestFd; fd >= 0; --fd) {
86 + if ((acptr = LocalClientArray[fd])) {
87 + if (!cli_user(acptr))
90 - if (GlineIsIpMask(gline)) {
91 - if (!ipmask_check(&cli_ip(acptr), &gline->gl_addr, gline->gl_bits))
92 + if (GlineIsRealName(gline)) { /* Realname Gline */
93 + Debug((DEBUG_DEBUG,"Realname Gline: %s %s",(cli_info(acptr)),
95 + if (match(gline->gl_user+2, cli_info(acptr)) != 0)
97 + Debug((DEBUG_DEBUG,"Matched!"));
98 + } else { /* Host/IP gline */
99 + if (cli_user(acptr)->username &&
100 + match(gline->gl_user, (cli_user(acptr))->realusername) != 0)
103 + if (GlineIsIpMask(gline)) {
104 + if (!ipmask_check(&cli_ip(acptr), &gline->gl_addr, gline->gl_bits))
108 + if (match(gline->gl_host, cli_sockhost(acptr)) != 0)
113 - if (match(gline->gl_host, cli_sockhost(acptr)) != 0)
117 + /* ok, here's one that got G-lined */
118 + send_reply(acptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s",
121 + /* let the ops know about it */
122 + sendto_opmask_butone(0, SNO_GLINE, "G-line active for %s",
123 + get_client_name(acptr, SHOW_IP));
125 + /* and get rid of him */
126 + /* Asuka - Reimplement HEAD_IN_SAND_GLINE from Lain */
127 + if ((tval = exit_client_msg(cptr, acptr, &me,
128 + feature_bool(FEAT_HIS_GLINE) ? "G-lined" : "G-lined (%s)", gline->gl_reason)))
129 + retval = tval; /* retain killed status */
132 - /* ok, here's one that got G-lined */
133 - send_reply(acptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s",
136 - /* let the ops know about it */
137 - sendto_opmask_butone(0, SNO_GLINE, "G-line active for %s",
138 - get_client_name(acptr, SHOW_IP));
140 - /* and get rid of him */
141 - /* Asuka - Reimplement HEAD_IN_SAND_GLINE from Lain */
142 - if ((tval = exit_client_msg(cptr, acptr, &me,
143 - feature_bool(FEAT_HIS_GLINE) ? "G-lined" : "G-lined (%s)", gline->gl_reason)))
144 - retval = tval; /* retain killed status */
148 @@ -984,6 +1004,29 @@
153 +gline_lookup_badchan(char *userhost, unsigned int flags)
155 + struct Gline *gline;
156 + struct Gline *sgline;
158 + if (flags & (GLINE_BADCHAN | GLINE_ANY)) {
159 + gliter(BadChanGlineList, gline, sgline) {
160 + if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) ||
161 + (flags & GLINE_LASTMOD && !gline->gl_lastmod))
164 + if ((flags & GLINE_EXACT ? ircd_strcmp(gline->gl_user, userhost) :
165 + match(gline->gl_user, userhost)) == 0) {
166 + if (GlineIsActive(gline))
175 /** Find a matching G-line for a user.
176 * @param[in] cptr Client to compare against.
177 * @param[in] flags Bitwise combination of GLINE_GLOBAL and/or
178 @@ -1174,6 +1217,16 @@
179 GlineIsRemActive(gline) ? '+' : '-',
183 + gliter(BadChanGlineList, gline, sgline) {
184 + send_reply(sptr, RPL_STATSGLINE, 'G', gline->gl_user, "", "", "", "",
185 + gline->gl_expire + TSoffset, gline->gl_lastmod,
186 + gline->gl_lifetime + TSoffset,
187 + gline->gl_state == GLOCAL_ACTIVATED ? ">" :
188 + (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""),
189 + GlineIsRemActive(gline) ? '+' : '-', gline->gl_reason);
194 /** Calculate memory used by G-lines.
195 diff -r b303d3fb110e ircd/m_join.c
196 --- a/ircd/m_join.c Sat Jul 20 14:49:32 2013 +0100
197 +++ b/ircd/m_join.c Sat Jul 20 14:50:19 2013 +0100
201 /* BADCHANed channel */
202 - if ((gline = gline_find(name, GLINE_BADCHAN | GLINE_EXACT)) &&
203 - GlineIsActive(gline) && !IsAnOper(sptr)) {
204 - send_reply(sptr, ERR_BANNEDFROMCHAN, name);
205 + if (!IsAnOper(sptr)
206 + && (gline = gline_lookup_badchan(name, GLINE_BADCHAN))) {
207 + send_reply(sptr, ERR_BADCHANNAME, name, gline->gl_reason);
211 diff -r b303d3fb110e ircd/s_err.c
212 --- a/ircd/s_err.c Sat Jul 20 14:49:32 2013 +0100
213 +++ b/ircd/s_err.c Sat Jul 20 14:50:19 2013 +0100
216 { ERR_BANLISTFULL, "%s %s :Channel ban/ignore list is full", "478" },
218 - { ERR_BADCHANNAME, "%s :Cannot join channel (access denied on this server)", "479" },
219 + { ERR_BADCHANNAME, "%s :Cannot join channel (G-lined: %s)", "479" },