Revert mode source when opping a user on channel creation (bug #1197510).
[ircu2.10.12-pk.git] / ircd / channel.c
index a593438595df47040b5084914d160d8c803f6675..472d92759cf885dd5d7ea1f6586f52af54615eb2 100644 (file)
@@ -655,6 +655,9 @@ int member_can_send_to_channel(struct Membership* member, int reveal)
    */
   if (member->channel->mode.mode & MODE_MODERATED)
     return 0;
+  /* If only logged in users may join and you're not one, you can't speak. */
+  if (member->channel->mode.mode & MODE_REGONLY && !IsAccount(member->user))
+    return 0;
   /*
    * If you're banned then you can't speak either.
    * but because of the amount of CPU time that is_banned chews
@@ -2484,6 +2487,11 @@ mode_parse_upass(struct ParseState *state, int *flag_p)
       send_reply(state->sptr, ERR_UPASSNOTSET, state->chptr->chname, state->chptr->chname);
       return;
     }
+    /* cannot set a +U password that is the same as +A */
+    if (state->dir == MODE_ADD && !ircd_strcmp(state->chptr->mode.apass, t_str)) {
+      send_reply(state->sptr, ERR_UPASS_SAME_APASS, state->chptr->chname);
+      return;
+    }
     /* can't add a upass if one is set, nor can one remove the wrong upass */
     if ((state->dir == MODE_ADD && *state->chptr->mode.upass) ||
        (state->dir == MODE_DEL &&
@@ -2696,6 +2704,8 @@ int apply_ban(struct Ban **banlist, struct Ban *newban, int do_free)
       if (!bmatch(ban, newban)) {
         if (do_free)
           free_ban(newban);
+        else
+          MyFree(newban->banstr);
         return 1;
       }
       if (!(ban->flags & (BAN_OVERLAPPED|BAN_DEL))) {
@@ -2732,6 +2742,8 @@ int apply_ban(struct Ban **banlist, struct Ban *newban, int do_free)
   }
   if (do_free)
     free_ban(newban);
+  else
+    MyFree(newban->banstr);
   return 4;
 }
 
@@ -2890,6 +2902,13 @@ mode_process_bans(struct ParseState *state)
     prevban = ban;
   } /* for (prevban = 0, ban = state->chptr->banlist; ban; ban = nextban) { */
 
+  /* Release all masks of removed bans */
+  for (count = 0; count < state->numbans; ++count) {
+    ban = state->banlist + count;
+    if (ban->flags & BAN_DEL)
+      MyFree(ban->banstr);
+  }
+
   if (changed) /* if we changed the ban list, we must invalidate the bans */
     mode_ban_invalidate(state->chptr);
 }
@@ -3372,7 +3391,9 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags)
        is_local) /* got to remove user here */
       remove_user_from_channel(jbuf->jb_source, chan);
   } else {
-    int oplevel = chan->mode.apass[0] ? 0 : MAXOPLEVEL;
+    int oplevel = !chan->mode.apass[0] ? MAXOPLEVEL
+        : (flags & CHFL_CHANNEL_MANAGER) ? 0
+        : 1;
     /* Add user to channel */
     if ((chan->mode.mode & MODE_DELJOINS) && !(flags & CHFL_VOICED_OR_OPPED))
       add_user_to_channel(chan, jbuf->jb_source, flags | CHFL_DELAYED, oplevel);
@@ -3381,16 +3402,23 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags)
 
     /* send notification to all servers */
     if (jbuf->jb_type != JOINBUF_TYPE_CREATE && !is_local)
-      sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
-                           "%H %Tu", chan, chan->creationtime);
+    {
+      if (flags & CHFL_CHANOP)
+        sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
+                              "%u:%H %Tu", oplevel, chan, chan->creationtime);
+      else
+        sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
+                              "%H %Tu", chan, chan->creationtime);
+    }
 
     if (!((chan->mode.mode & MODE_DELJOINS) && !(flags & CHFL_VOICED_OR_OPPED))) {
       /* Send the notification to the channel */
       sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_JOIN, chan, NULL, 0, "%H", chan);
 
       /* send an op, too, if needed */
-      if (!MyUser(jbuf->jb_source) && jbuf->jb_type == JOINBUF_TYPE_CREATE)
-       sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_MODE, chan, NULL, 0, "%H +o %C",
+      if (flags & CHFL_CHANOP)
+       sendcmdto_channel_butserv_butone((chan->mode.apass[0] ? &me : jbuf->jb_source),
+                                         CMD_MODE, chan, NULL, 0, "%H +o %C",
                                         chan, jbuf->jb_source);
     } else if (MyUser(jbuf->jb_source))
       sendcmdto_one(jbuf->jb_source, CMD_JOIN, jbuf->jb_source, ":%H", chan);