diff --git a/CHANGELOG.md b/CHANGELOG.md index 375e8968..9dc09342 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ New release of Oragono! * Fixed bug where `HELP` wouldn't correctly display for operators, and added more help topics. * Fixed display of large `MONITOR` lists. * Fixed bug where you would always have certain capabilities enabled. +* Fixed being able to change modes when not an operator. ## [0.3.0] - 2016-10-23 diff --git a/irc/modes.go b/irc/modes.go index 8baf51af..246e0c84 100644 --- a/irc/modes.go +++ b/irc/modes.go @@ -409,7 +409,20 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { // so we only output one warning for each list type when full listFullWarned := make(map[ChannelMode]bool) + clientIsOp := channel.ClientIsAtLeast(client, ChannelOperator) + var alreadySentPrivError bool + for _, change := range changes { + // chan priv modes are checked specially so ignore them + // means regular users can't view ban/except lists... but I'm not worried about that + if ChannelModePrefixes[change.mode] == "" && !clientIsOp { + if !alreadySentPrivError { + alreadySentPrivError = true + client.Send(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, "You're not a channel operator") + } + continue + } + switch change.mode { case BanMask, ExceptMask, InviteMask: mask := change.arg @@ -519,7 +532,10 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { if change.op == Remove && casefoldedName == client.nickCasefolded { // success! } else { - client.Send(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, "You're not a channel operator") + if !alreadySentPrivError { + alreadySentPrivError = true + client.Send(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, "You're not a channel operator") + } continue } }