about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlexander Barton <alex@barton.de>2011-01-09 23:08:15 +0100
committerAlexander Barton <alex@barton.de>2011-01-09 23:08:15 +0100
commit5ed7a4ea5755954dc6e25349125963cff7a4355c (patch)
tree2805fc6d4d6c3240602ac87bd9d0d376c266e9c9 /src
parentba32d594fd7a93305cd01a14978971d948392510 (diff)
downloadngircd-5ed7a4ea5755954dc6e25349125963cff7a4355c.tar.gz
ngircd-5ed7a4ea5755954dc6e25349125963cff7a4355c.zip
TOPIC command: test for channel admin rights correctly
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.
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/irc-channel.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c
index 8aa27c01..81a9eb2e 100644
--- a/src/ngircd/irc-channel.c
+++ b/src/ngircd/irc-channel.c
@@ -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",