]> arthur.barton.de Git - ngircd-alex.git/commitdiff
TOPIC command: test for channel admin rights correctly
authorAlexander Barton <alex@barton.de>
Sun, 9 Jan 2011 22:08:15 +0000 (23:08 +0100)
committerAlexander Barton <alex@barton.de>
Sun, 9 Jan 2011 22:08:15 +0000 (23:08 +0100)
This enables other servers, services and IRC operators to change
channel topics, even when the client is not joined to this channel.

Now the handler for TOPIC behaves like the one for MODE.

src/ngircd/irc-channel.c

index 8aa27c01aabfc586ebede81d5586df2a0d071e6c..81a9eb2e89f5f017f7dc9a9007441655df66059d 100644 (file)
@@ -407,7 +407,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
        CHANNEL *chan;
        CLIENT *from;
        char *topic;
-       bool r;
+       bool onchannel, topicok, use_servermode, r;
 
        assert( Client != NULL );
        assert( Req != NULL );
@@ -430,7 +430,10 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
                return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
                                          Client_ID(from), Req->argv[0]);
 
-       if (!Channel_IsMemberOf(chan, from))
+       Channel_CheckAdminRights(chan, Client, from,
+                                &onchannel, &topicok, &use_servermode);
+
+       if (!onchannel && !topicok)
                return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
                                          Client_ID(from), Req->argv[0]);
 
@@ -457,8 +460,8 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
        }
 
        if (strchr(Channel_Modes(chan), 't')) {
-               /* Topic Lock. Is the user a channel operator? */
-               if (!strchr(Channel_UserModes(chan, from), 'o'))
+               /* Topic Lock. Is the user a channel or IRC operator? */
+               if (!topicok)
                        return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
                                                  Client_ID(from),
                                                  Channel_Name(chan));
@@ -470,6 +473,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
                 Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
                 Req->argv[1][0] ? Req->argv[1] : "<none>");
 
+       if (use_servermode)
+               from = Client_ThisServer();
+
        /* Update channel and forward new topic to other servers */
        if (!Channel_IsLocal(chan))
                IRC_WriteStrServersPrefix(Client, from, "TOPIC %s :%s",