commit - 58abd0777b0924e5cb8fa6c01b56305d9b175608
commit + 8d9cfa157a7fd067dab3483614d427f35dfa4ad1
blob - 4a157d67e5fca76d8461f421644da3d00e7b7dd0
blob + f9d2dc125d3708b11ad629ed9551b7f08f4b2598
--- src/ngircd/irc-channel.c
+++ src/ngircd/irc-channel.c
CHANNEL *chan;
CLIENT *from;
char *topic;
- bool r, is_oper;
+ bool r, topic_power;
assert( Client != NULL );
assert( Req != NULL );
return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
Client_ID(from), Req->argv[0]);
- /* Only IRC opers and channel members allowed */
- is_oper = Client_OperByMe(from);
- if (!Channel_IsMemberOf(chan, from) && !is_oper)
- return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
- Client_ID(from), Req->argv[0]);
+ /* Only remote servers and channel members are allowed to change the
+ * channel topic, and IRC opreators when the Conf_OperCanMode option
+ * is set in the server configuration. */
+ if (Client_Type(Client) != CLIENT_SERVER) {
+ topic_power = Client_HasMode(from, 'o');
+ if (!Channel_IsMemberOf(chan, from)
+ && !(Conf_OperCanMode && topic_power))
+ return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
+ Client_ID(from), Req->argv[0]);
+ } else
+ topic_power = true;
if (Req->argc == 1) {
/* Request actual topic */
if (strchr(Channel_Modes(chan), 't')) {
/* Topic Lock. Is the user a channel op or IRC operator? */
- if(!strchr(Channel_UserModes(chan, from), 'h') &&
+ if(!topic_power &&
+ !strchr(Channel_UserModes(chan, from), 'h') &&
!strchr(Channel_UserModes(chan, from), 'o') &&
!strchr(Channel_UserModes(chan, from), 'a') &&
- !strchr(Channel_UserModes(chan, from), 'q') &&
- !is_oper)
+ !strchr(Channel_UserModes(chan, from), 'q'))
return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(from),
Channel_Name(chan));