|
@@ -757,10 +757,6 @@ func debugHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
757
|
757
|
rb.Notice(fmt.Sprintf("CPU profiling stopped"))
|
758
|
758
|
|
759
|
759
|
case "CRASHSERVER":
|
760
|
|
- if !client.HasRoleCapabs("rehash") {
|
761
|
|
- rb.Notice(client.t("You must have rehash permissions in order to execute DEBUG CRASHSERVER"))
|
762
|
|
- return false
|
763
|
|
- }
|
764
|
760
|
code := utils.ConfirmationCode(server.name, server.ctime)
|
765
|
761
|
if len(msg.Params) == 1 || msg.Params[1] != code {
|
766
|
762
|
rb.Notice(fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/DEBUG CRASHSERVER %s", code)))
|
|
@@ -1293,6 +1289,7 @@ func sajoinHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
|
1293
|
1289
|
|
1294
|
1290
|
// KICK <channel>{,<channel>} <user>{,<user>} [<comment>]
|
1295
|
1291
|
func kickHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
|
1292
|
+ hasPrivs := client.HasRoleCapabs("samode")
|
1296
|
1293
|
channels := strings.Split(msg.Params[0], ",")
|
1297
|
1294
|
users := strings.Split(msg.Params[1], ",")
|
1298
|
1295
|
if (len(channels) != len(users)) && (len(users) != 1) {
|
|
@@ -1336,7 +1333,7 @@ func kickHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
1336
|
1333
|
if comment == "" {
|
1337
|
1334
|
comment = kick.nick
|
1338
|
1335
|
}
|
1339
|
|
- channel.Kick(client, target, comment, rb, false)
|
|
1336
|
+ channel.Kick(client, target, comment, rb, hasPrivs)
|
1340
|
1337
|
}
|
1341
|
1338
|
return false
|
1342
|
1339
|
}
|
|
@@ -1618,7 +1615,7 @@ func listHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
1618
|
1615
|
rb.Add(nil, client.server.name, RPL_LIST, nick, name, strconv.Itoa(members), topic)
|
1619
|
1616
|
}
|
1620
|
1617
|
|
1621
|
|
- clientIsOp := client.HasMode(modes.Operator)
|
|
1618
|
+ clientIsOp := client.HasRoleCapabs("sajoin")
|
1622
|
1619
|
if len(channels) == 0 {
|
1623
|
1620
|
for _, channel := range server.channels.Channels() {
|
1624
|
1621
|
if !clientIsOp && channel.flags.HasMode(modes.Secret) {
|
|
@@ -1775,7 +1772,7 @@ func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
1775
|
1772
|
rb.Add(nil, cDetails.nickMask, "MODE", args...)
|
1776
|
1773
|
} else if hasPrivs {
|
1777
|
1774
|
rb.Add(nil, server.name, RPL_UMODEIS, targetNick, target.ModeString())
|
1778
|
|
- if target.HasMode(modes.LocalOperator) || target.HasMode(modes.Operator) {
|
|
1775
|
+ if target.HasMode(modes.Operator) {
|
1779
|
1776
|
masks := server.snomasks.String(target)
|
1780
|
1777
|
if 0 < len(masks) {
|
1781
|
1778
|
rb.Add(nil, server.name, RPL_SNOMASKIS, targetNick, masks, client.t("Server notice masks"))
|
|
@@ -1959,7 +1956,7 @@ func namesHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
1959
|
1956
|
success := false
|
1960
|
1957
|
channel := server.channels.Get(chname)
|
1961
|
1958
|
if channel != nil {
|
1962
|
|
- if !channel.flags.HasMode(modes.Secret) || channel.hasClient(client) || client.HasMode(modes.Operator) {
|
|
1959
|
+ if !channel.flags.HasMode(modes.Secret) || channel.hasClient(client) || client.HasRoleCapabs("sajoin") {
|
1963
|
1960
|
channel.Names(client, rb)
|
1964
|
1961
|
success = true
|
1965
|
1962
|
}
|
|
@@ -2338,6 +2335,10 @@ func applyOper(client *Client, oper *Oper, rb *ResponseBuffer) {
|
2338
|
2335
|
|
2339
|
2336
|
// DEOPER
|
2340
|
2337
|
func deoperHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
|
2338
|
+ if client.Oper() == nil {
|
|
2339
|
+ rb.Notice(client.t("Insufficient oper privs"))
|
|
2340
|
+ return false
|
|
2341
|
+ }
|
2341
|
2342
|
// pretend they sent /MODE $nick -o
|
2342
|
2343
|
fakeModeMsg := ircmsg.MakeMessage(nil, "", "MODE", client.Nick(), "-o")
|
2343
|
2344
|
return umodeHandler(server, client, fakeModeMsg, rb)
|
|
@@ -2944,7 +2945,7 @@ func operStatusVisible(client, target *Client, hasPrivs bool) bool {
|
2944
|
2945
|
|
2945
|
2946
|
// USERHOST <nickname>{ <nickname>}
|
2946
|
2947
|
func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
2947
|
|
- hasPrivs := client.HasMode(modes.Operator) // TODO(#1176) figure out the right capab for this
|
|
2948
|
+ hasPrivs := client.HasMode(modes.Operator)
|
2948
|
2949
|
returnedClients := make(ClientSet)
|
2949
|
2950
|
|
2950
|
2951
|
var tl utils.TokenLineBuilder
|
|
@@ -3083,7 +3084,7 @@ func (fields whoxFields) Has(field rune) bool {
|
3083
|
3084
|
// <channel> <user> <host> <server> <nick> <H|G>[*][~|&|@|%|+][B] :<hopcount> <real name>
|
3084
|
3085
|
// whox format:
|
3085
|
3086
|
// <type> <channel> <user> <ip> <host> <server> <nick> <H|G>[*][~|&|@|%|+][B] <hops> <idle> <account> <rank> :<real name>
|
3086
|
|
-func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, hasPrivs, includeRFlag, isWhox bool, fields whoxFields, whoType string) {
|
|
3087
|
+func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, canSeeIPs, canSeeOpers, includeRFlag, isWhox bool, fields whoxFields, whoType string) {
|
3087
|
3088
|
params := []string{client.Nick()}
|
3088
|
3089
|
|
3089
|
3090
|
details := target.Details()
|
|
@@ -3103,7 +3104,7 @@ func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *Response
|
3103
|
3104
|
}
|
3104
|
3105
|
if fields.Has('i') {
|
3105
|
3106
|
fIP := "255.255.255.255"
|
3106
|
|
- if hasPrivs || client == target {
|
|
3107
|
+ if canSeeIPs || client == target {
|
3107
|
3108
|
// you can only see a target's IP if they're you or you're an oper
|
3108
|
3109
|
fIP = target.IPString()
|
3109
|
3110
|
}
|
|
@@ -3126,7 +3127,7 @@ func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *Response
|
3126
|
3127
|
flags.WriteRune('H') // Here
|
3127
|
3128
|
}
|
3128
|
3129
|
|
3129
|
|
- if target.HasMode(modes.Operator) && operStatusVisible(client, target, hasPrivs) {
|
|
3130
|
+ if target.HasMode(modes.Operator) && operStatusVisible(client, target, canSeeOpers) {
|
3130
|
3131
|
flags.WriteRune('*')
|
3131
|
3132
|
}
|
3132
|
3133
|
|
|
@@ -3229,23 +3230,23 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
|
3229
|
3230
|
// operatorOnly = true
|
3230
|
3231
|
//}
|
3231
|
3232
|
|
3232
|
|
- isOper := client.HasMode(modes.Operator)
|
|
3233
|
+ oper := client.Oper()
|
|
3234
|
+ hasPrivs := oper.HasRoleCapab("sajoin")
|
|
3235
|
+ canSeeIPs := oper.HasRoleCapab("ban")
|
3233
|
3236
|
if mask[0] == '#' {
|
3234
|
|
- // TODO implement wildcard matching
|
3235
|
|
- //TODO(dan): ^ only for opers
|
3236
|
3237
|
channel := server.channels.Get(mask)
|
3237
|
3238
|
if channel != nil {
|
3238
|
3239
|
isJoined := channel.hasClient(client)
|
3239
|
|
- if !channel.flags.HasMode(modes.Secret) || isJoined || isOper {
|
|
3240
|
+ if !channel.flags.HasMode(modes.Secret) || isJoined || hasPrivs {
|
3240
|
3241
|
var members []*Client
|
3241
|
|
- if isOper {
|
|
3242
|
+ if hasPrivs {
|
3242
|
3243
|
members = channel.Members()
|
3243
|
3244
|
} else {
|
3244
|
3245
|
members = channel.auditoriumFriends(client)
|
3245
|
3246
|
}
|
3246
|
3247
|
for _, member := range members {
|
3247
|
|
- if !member.HasMode(modes.Invisible) || isJoined || isOper {
|
3248
|
|
- client.rplWhoReply(channel, member, rb, isOper, includeRFlag, isWhox, fields, whoType)
|
|
3248
|
+ if !member.HasMode(modes.Invisible) || isJoined || hasPrivs {
|
|
3249
|
+ client.rplWhoReply(channel, member, rb, canSeeIPs, oper != nil, includeRFlag, isWhox, fields, whoType)
|
3249
|
3250
|
}
|
3250
|
3251
|
}
|
3251
|
3252
|
}
|
|
@@ -3275,8 +3276,8 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
|
3275
|
3276
|
}
|
3276
|
3277
|
|
3277
|
3278
|
for mclient := range server.clients.FindAll(mask) {
|
3278
|
|
- if isOper || !mclient.HasMode(modes.Invisible) || isFriend(mclient) {
|
3279
|
|
- client.rplWhoReply(nil, mclient, rb, isOper, includeRFlag, isWhox, fields, whoType)
|
|
3279
|
+ if hasPrivs || !mclient.HasMode(modes.Invisible) || isFriend(mclient) {
|
|
3280
|
+ client.rplWhoReply(nil, mclient, rb, canSeeIPs, oper != nil, includeRFlag, isWhox, fields, whoType)
|
3280
|
3281
|
}
|
3281
|
3282
|
}
|
3282
|
3283
|
}
|
|
@@ -3319,7 +3320,7 @@ func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
3319
|
3320
|
return true
|
3320
|
3321
|
}
|
3321
|
3322
|
|
3322
|
|
- hasPrivs := client.HasMode(modes.Operator) // TODO(#1176) figure out the right capab for this
|
|
3323
|
+ hasPrivs := client.HasRoleCapabs("samode")
|
3323
|
3324
|
if hasPrivs {
|
3324
|
3325
|
for _, mask := range strings.Split(masksString, ",") {
|
3325
|
3326
|
matches := server.clients.FindAll(mask)
|