]> jfr.im git - irc/atheme/atheme.git/commitdiff
Alter several modules to use `numsvcmembers` in `struct channel`, instead of inferrin...
authorRyan Schoppmeyer <redacted>
Sun, 1 Feb 2015 10:20:14 +0000 (02:20 -0800)
committerWilliam Pitcock <redacted>
Mon, 2 Feb 2015 02:19:41 +0000 (20:19 -0600)
A number of bugs have been corrected, mostly caused by incorrect checking of emptying channels:
- chanserv/main: not kicking users who create channels that are MLOCK'd +i if a botserv bot is present
- groupserv/main/hooks: permission changes not taking effect immediately if a botserv bot is present
- chanserv/sync: rare crash caused by use-after-free when removing the last non-services user from a channel

modules/botserv/main.c
modules/chanserv/main.c
modules/chanserv/sync.c
modules/groupserv/main/hooks.c

index 9e05220853e78dbab383c1abf49cf97cea06106c..40a34484cb3a699be5081b704afaf317a4425d13 100644 (file)
@@ -1162,7 +1162,7 @@ bs_part(hook_channel_joinpart_t *hdata)
        */
        if (config_options.leave_chans
                        && !(mc->flags & MC_INHABIT)
-                       && (cu->chan->nummembers <= 2)
+                       && (cu->chan->nummembers - cu->chan->numsvcmembers == 1)
                        && !is_internal_client(cu->user))
        {
                if (bot)
index b9a8aa36108c15f17e260fb371c15ae380dd2865..6520bcc2eb3220accc9fbbdc2df1360c1e50ebfc 100644 (file)
@@ -346,7 +346,6 @@ static void cs_join(hook_channel_joinpart_t *hdata)
        unsigned int flags;
        bool noop;
        bool secure;
-       bool guard;
        metadata_t *md;
        chanacs_t *ca2;
        char akickreason[120] = "User is banned from this channel", *p;
@@ -368,9 +367,6 @@ static void cs_join(hook_channel_joinpart_t *hdata)
         * sophisticated mechanism is disabled */
        secure = mc->flags & MC_SECURE || (!chansvs.changets &&
                        chan->nummembers == 1 && chan->ts > CURRTIME - 300);
-       /* chanserv or a botserv bot should join */
-       guard = mc->flags & MC_GUARD ||
-               metadata_find(mc, "private:botserv:bot-assigned") != NULL;
 
        if (chan->nummembers == 1 && mc->flags & MC_GUARD &&
                metadata_find(mc, "private:botserv:bot-assigned") == NULL)
@@ -383,10 +379,10 @@ static void cs_join(hook_channel_joinpart_t *hdata)
        if ((mc->flags & MC_RESTRICTED) && !(flags & CA_ALLPRIVS) && !has_priv_user(u, PRIV_JOIN_STAFFONLY))
        {
                /* Stay on channel if this would empty it -- jilles */
-               if (chan->nummembers <= (guard ? 2 : 1))
+               if (chan->nummembers - chan->numsvcmembers == 1)
                {
                        mc->flags |= MC_INHABIT;
-                       if (!guard)
+                       if (chan->numsvcmembers == 0)
                                join(chan->name, chansvs.nick);
                }
                if (mc->mlock_on & CMODE_INVITE || chan->modes & CMODE_INVITE)
@@ -409,10 +405,10 @@ static void cs_join(hook_channel_joinpart_t *hdata)
        if (flags & CA_AKICK && !(flags & CA_EXEMPT))
        {
                /* Stay on channel if this would empty it -- jilles */
-               if (chan->nummembers <= (guard ? 2 : 1))
+               if (chan->nummembers - chan->numsvcmembers == 1)
                {
                        mc->flags |= MC_INHABIT;
-                       if (!guard)
+                       if (chan->numsvcmembers == 0)
                                join(chan->name, chansvs.nick);
                }
                /* use a user-given ban mask if possible -- jilles */
@@ -471,13 +467,13 @@ static void cs_join(hook_channel_joinpart_t *hdata)
         */
        if (mc->mlock_on & CMODE_INVITE && !(flags & CA_INVITE) &&
                        (!me.bursting || mc->flags & MC_RECREATED) &&
-                       (!(u->server->flags & SF_EOB) || (chan->nummembers <= 2 && (chan->nummembers <= 1 || chanuser_find(chan, chansvs.me->me)))) &&
+                       (!(u->server->flags & SF_EOB) || (chan->nummembers - chan->numsvcmembers == 1)) &&
                        (!ircd->invex_mchar || !next_matching_ban(chan, u, ircd->invex_mchar, chan->bans.head)))
        {
-               if (chan->nummembers <= (guard ? 2 : 1))
+               if (chan->nummembers - chan->numsvcmembers == 1)
                {
                        mc->flags |= MC_INHABIT;
-                       if (!guard)
+                       if (chan->numsvcmembers == 0)
                                join(chan->name, chansvs.nick);
                }
                if (!(chan->modes & CMODE_INVITE))
@@ -494,7 +490,7 @@ static void cs_join(hook_channel_joinpart_t *hdata)
         * triggering autocycle-for-ops scripts and immediately
         * destroying channels with kick on split riding.
         */
-       if (mc->flags & MC_INHABIT && chan->nummembers >= 3)
+       if (mc->flags & MC_INHABIT && chan->nummembers - chan->numsvcmembers >= 2)
        {
                mc->flags &= ~MC_INHABIT;
                if (!(mc->flags & MC_GUARD) && !(chan->flags & CHAN_LOG) && chanuser_find(chan, chansvs.me->me))
@@ -624,7 +620,7 @@ static void cs_part(hook_channel_joinpart_t *hdata)
                return;
 
        /* we're not parting if the channel has more than one person on it */
-       if (cu->chan->nummembers > 2)
+       if (cu->chan->nummembers - cu->chan->numsvcmembers > 1)
                return;
 
        /* internal clients parting a channel shouldn't cause chanserv to leave. */
@@ -893,13 +889,13 @@ static void cs_leave_empty(void *unused)
                if (!(mc->flags & MC_INHABIT))
                        continue;
                /* If there is only one user, stay indefinitely. */
-               if (mc->chan != NULL && mc->chan->nummembers == 2)
+               if (mc->chan != NULL && mc->chan->nummembers - mc->chan->numsvcmembers == 1)
                        continue;
                mc->flags &= ~MC_INHABIT;
                if (mc->chan != NULL &&
                                !(mc->chan->flags & CHAN_LOG) &&
                                (!(mc->flags & MC_GUARD) ||
-                                (config_options.leave_chans && mc->chan->nummembers == 1) ||
+                                (config_options.leave_chans && mc->chan->nummembers == mc->chan->numsvcmembers) ||
                                 metadata_find(mc, "private:close:closer")) &&
                                chanuser_find(mc->chan, chansvs.me->me))
                {
index a9126d88c8ced3026eed043c2034365ec9d8b7ba..79af9df5b98ebf848c769f3c724e77d9c4517546 100644 (file)
@@ -48,10 +48,10 @@ static void do_chanuser_sync(mychan_t *mc, chanuser_t *cu, chanacs_t *ca,
        if (take && !(fl & CA_ALLPRIVS) && (mc->flags & MC_RESTRICTED) && !has_priv_user(cu->user, PRIV_JOIN_STAFFONLY))
        {
                /* Stay on channel if this would empty it -- jilles */
-               if (mc->chan->nummembers <= (mc->flags & MC_GUARD ? 2 : 1))
+               if (mc->chan->nummembers - mc->chan->numsvcmembers == 1)
                {
                        mc->flags |= MC_INHABIT;
-                       if (!(mc->flags & MC_GUARD))
+                       if (mc->chan->numsvcmembers == 0)
                                join(mc->chan->name, chansvs.nick);
                }
 
@@ -77,10 +77,10 @@ static void do_chanuser_sync(mychan_t *mc, chanuser_t *cu, chanacs_t *ca,
                metadata_t *md;
 
                /* Stay on channel if this would empty it -- jilles */
-               if (mc->chan->nummembers <= (mc->flags & MC_GUARD ? 2 : 1))
+               if (mc->chan->nummembers - mc->chan->numsvcmembers == 1)
                {
                        mc->flags |= MC_INHABIT;
-                       if (!(mc->flags & MC_GUARD))
+                       if (mc->chan->numsvcmembers == 0)
                                join(mc->chan->name, chansvs.nick);
                }
 
index 77a0f7b00896c341e382d784b05a7045a7768426..c116d350bddd3846c3d9b1a31cb626f674c9cefd 100644 (file)
@@ -56,10 +56,10 @@ static void grant_channel_access_hook(user_t *u)
                                if (ca->level & CA_AKICK && !(ca->level & CA_EXEMPT))
                                {
                                        /* Stay on channel if this would empty it -- jilles */
-                                       if (ca->mychan->chan->nummembers <= (ca->mychan->flags & MC_GUARD ? 2 : 1))
+                                       if (ca->mychan->chan->nummembers - ca->mychan->chan->numsvcmembers == 1)
                                        {
                                                ca->mychan->flags |= MC_INHABIT;
-                                               if (!(ca->mychan->flags & MC_GUARD))
+                                               if (ca->mychan->chan->numsvcmembers == 0)
                                                        join(cu->chan->name, chansvs.nick);
                                        }
                                        ban(chansvs.me->me, ca->mychan->chan, u);