ソースを参照

fix #1176

Transition most "is an operator" checks to require a specific operator
capability
tags/v2.6.0-rc1
Shivaram Lingamneni 3年前
コミット
42316bc04f
11個のファイルの変更59行の追加65行の削除
  1. 1
    0
      default.yaml
  2. 4
    8
      irc/channel.go
  3. 1
    1
      irc/chanserv.go
  4. 1
    1
      irc/client.go
  5. 1
    1
      irc/client_lookup_set.go
  6. 6
    15
      irc/commands.go
  7. 23
    22
      irc/handlers.go
  8. 9
    5
      irc/modes.go
  9. 0
    1
      irc/modes/modes.go
  10. 12
    11
      irc/server.go
  11. 1
    0
      traditional.yaml

+ 1
- 0
default.yaml ファイルの表示

@@ -593,6 +593,7 @@ oper-classes:
593 593
             - "vhosts"
594 594
             - "sajoin"
595 595
             - "samode"
596
+            - "snomasks"
596 597
 
597 598
     # server admin: has full control of the ircd, including nickname and
598 599
     # channel registrations

+ 4
- 8
irc/channel.go ファイルの表示

@@ -439,7 +439,7 @@ func (channel *Channel) Names(client *Client, rb *ResponseBuffer) {
439 439
 	channel.stateMutex.RLock()
440 440
 	clientData, isJoined := channel.members[client]
441 441
 	channel.stateMutex.RUnlock()
442
-	isOper := client.HasMode(modes.Operator)
442
+	isOper := client.HasRoleCapabs("sajoin")
443 443
 	respectAuditorium := channel.flags.HasMode(modes.Auditorium) && !isOper &&
444 444
 		(!isJoined || clientData.modes.HighestChannelUserMode() == modes.Mode(0))
445 445
 	isMultiPrefix := rb.session.capabilities.Has(caps.MultiPrefix)
@@ -607,7 +607,7 @@ func (channel *Channel) hasClient(client *Client) bool {
607 607
 
608 608
 // <mode> <mode params>
609 609
 func (channel *Channel) modeStrings(client *Client) (result []string) {
610
-	hasPrivs := client.HasMode(modes.Operator)
610
+	hasPrivs := client.HasRoleCapabs("sajoin")
611 611
 
612 612
 	channel.stateMutex.RLock()
613 613
 	defer channel.stateMutex.RUnlock()
@@ -1245,12 +1245,12 @@ func (channel *Channel) SendTopic(client *Client, rb *ResponseBuffer, sendNoTopi
1245 1245
 
1246 1246
 // SetTopic sets the topic of this channel, if the client is allowed to do so.
1247 1247
 func (channel *Channel) SetTopic(client *Client, topic string, rb *ResponseBuffer) {
1248
-	if !(client.HasMode(modes.Operator) || channel.hasClient(client)) {
1248
+	if !channel.hasClient(client) {
1249 1249
 		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.Name(), client.t("You're not on that channel"))
1250 1250
 		return
1251 1251
 	}
1252 1252
 
1253
-	if channel.flags.HasMode(modes.OpOnlyTopic) && !channel.ClientIsAtLeast(client, modes.Halfop) {
1253
+	if channel.flags.HasMode(modes.OpOnlyTopic) && !(channel.ClientIsAtLeast(client, modes.Halfop) || client.HasRoleCapabs("samode")) {
1254 1254
 		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You're not a channel operator"))
1255 1255
 		return
1256 1256
 	}
@@ -1487,10 +1487,6 @@ func (channel *Channel) Quit(client *Client) {
1487 1487
 
1488 1488
 func (channel *Channel) Kick(client *Client, target *Client, comment string, rb *ResponseBuffer, hasPrivs bool) {
1489 1489
 	if !hasPrivs {
1490
-		if !(client.HasMode(modes.Operator) || channel.hasClient(client)) {
1491
-			rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.Name(), client.t("You're not on that channel"))
1492
-			return
1493
-		}
1494 1490
 		if !channel.ClientHasPrivsOver(client, target) {
1495 1491
 			rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You don't have enough channel privileges"))
1496 1492
 			return

+ 1
- 1
irc/chanserv.go ファイルの表示

@@ -860,7 +860,7 @@ func csHowToBanHandler(service *ircService, server *Server, client *Client, comm
860 860
 		return
861 861
 	}
862 862
 
863
-	if !(channel.ClientIsAtLeast(client, modes.Operator) || client.HasRoleCapabs("samode")) {
863
+	if !(channel.ClientIsAtLeast(client, modes.ChannelOperator) || client.HasRoleCapabs("samode")) {
864 864
 		service.Notice(rb, client.t("Insufficient privileges"))
865 865
 		return
866 866
 	}

+ 1
- 1
irc/client.go ファイルの表示

@@ -1512,7 +1512,7 @@ func (client *Client) destroy(session *Session) {
1512 1512
 	// decrement stats if we have no more sessions, even if the client will not be destroyed
1513 1513
 	if shouldDecrement {
1514 1514
 		invisible := client.HasMode(modes.Invisible)
1515
-		operator := client.HasMode(modes.LocalOperator) || client.HasMode(modes.Operator)
1515
+		operator := client.HasMode(modes.Operator)
1516 1516
 		client.server.stats.Remove(registered, invisible, operator)
1517 1517
 	}
1518 1518
 

+ 1
- 1
irc/client_lookup_set.go ファイルの表示

@@ -222,7 +222,7 @@ func (clients *ClientManager) SetNick(client *Client, session *Session, newNick
222 222
 		}
223 223
 		if numSessions == 1 {
224 224
 			invisible := currentClient.HasMode(modes.Invisible)
225
-			operator := currentClient.HasMode(modes.Operator) || currentClient.HasMode(modes.LocalOperator)
225
+			operator := currentClient.HasMode(modes.Operator)
226 226
 			client.server.stats.AddRegistered(invisible, operator)
227 227
 		}
228 228
 		session.autoreplayMissedSince = lastSeen

+ 6
- 15
irc/commands.go ファイルの表示

@@ -7,13 +7,11 @@ package irc
7 7
 
8 8
 import (
9 9
 	"github.com/goshuirc/irc-go/ircmsg"
10
-	"github.com/oragono/oragono/irc/modes"
11 10
 )
12 11
 
13 12
 // Command represents a command accepted from a client.
14 13
 type Command struct {
15 14
 	handler        func(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool
16
-	oper           bool
17 15
 	usablePreReg   bool
18 16
 	allowedInBatch bool // allowed in client-to-server batches
19 17
 	minParams      int
@@ -32,10 +30,6 @@ func (cmd *Command) Run(server *Server, client *Client, session *Session, msg ir
32 30
 			rb.Add(nil, server.name, ERR_NOTREGISTERED, "*", client.t("You need to register before you can use that command"))
33 31
 			return false
34 32
 		}
35
-		if cmd.oper && !client.HasMode(modes.Operator) {
36
-			rb.Add(nil, server.name, ERR_NOPRIVILEGES, client.Nick(), client.t("Permission Denied - You're not an IRC operator"))
37
-			return false
38
-		}
39 33
 		if len(cmd.capabs) > 0 && !client.HasRoleCapabs(cmd.capabs...) {
40 34
 			rb.Add(nil, server.name, ERR_NOPRIVILEGES, client.Nick(), client.t("Permission Denied"))
41 35
 			return false
@@ -115,7 +109,7 @@ func init() {
115 109
 		"DEBUG": {
116 110
 			handler:   debugHandler,
117 111
 			minParams: 1,
118
-			oper:      true,
112
+			capabs:    []string{"rehash"},
119 113
 		},
120 114
 		"DEFCON": {
121 115
 			handler: defconHandler,
@@ -124,12 +118,11 @@ func init() {
124 118
 		"DEOPER": {
125 119
 			handler:   deoperHandler,
126 120
 			minParams: 0,
127
-			oper:      true,
128 121
 		},
129 122
 		"DLINE": {
130 123
 			handler:   dlineHandler,
131 124
 			minParams: 1,
132
-			oper:      true,
125
+			capabs:    []string{"ban"},
133 126
 		},
134 127
 		"EXTJWT": {
135 128
 			handler:   extjwtHandler,
@@ -169,13 +162,12 @@ func init() {
169 162
 		"KILL": {
170 163
 			handler:   killHandler,
171 164
 			minParams: 1,
172
-			oper:      true,
173 165
 			capabs:    []string{"kill"},
174 166
 		},
175 167
 		"KLINE": {
176 168
 			handler:   klineHandler,
177 169
 			minParams: 1,
178
-			oper:      true,
170
+			capabs:    []string{"ban"},
179 171
 		},
180 172
 		"LANGUAGE": {
181 173
 			handler:      languageHandler,
@@ -278,7 +270,7 @@ func init() {
278 270
 		"SANICK": {
279 271
 			handler:   sanickHandler,
280 272
 			minParams: 2,
281
-			oper:      true,
273
+			capabs:    []string{"samode"},
282 274
 		},
283 275
 		"SAMODE": {
284 276
 			handler:   modeHandler,
@@ -308,7 +300,6 @@ func init() {
308 300
 		"REHASH": {
309 301
 			handler:   rehashHandler,
310 302
 			minParams: 0,
311
-			oper:      true,
312 303
 			capabs:    []string{"rehash"},
313 304
 		},
314 305
 		"TIME": {
@@ -327,7 +318,7 @@ func init() {
327 318
 		"UNDLINE": {
328 319
 			handler:   unDLineHandler,
329 320
 			minParams: 1,
330
-			oper:      true,
321
+			capabs:    []string{"ban"},
331 322
 		},
332 323
 		"UNINVITE": {
333 324
 			handler:   inviteHandler,
@@ -336,7 +327,7 @@ func init() {
336 327
 		"UNKLINE": {
337 328
 			handler:   unKLineHandler,
338 329
 			minParams: 1,
339
-			oper:      true,
330
+			capabs:    []string{"ban"},
340 331
 		},
341 332
 		"USER": {
342 333
 			handler:      userHandler,

+ 23
- 22
irc/handlers.go ファイルの表示

@@ -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)

+ 9
- 5
irc/modes.go ファイルの表示

@@ -37,14 +37,14 @@ func ApplyUserModeChanges(client *Client, changes modes.ModeChanges, force bool,
37 37
 		if change.Mode != modes.ServerNotice {
38 38
 			switch change.Op {
39 39
 			case modes.Add:
40
-				if (change.Mode == modes.Operator || change.Mode == modes.LocalOperator) && !(force && oper != nil) {
40
+				if (change.Mode == modes.Operator) && !(force && oper != nil) {
41 41
 					continue
42 42
 				}
43 43
 
44 44
 				if client.SetMode(change.Mode, true) {
45 45
 					if change.Mode == modes.Invisible {
46 46
 						client.server.stats.ChangeInvisible(1)
47
-					} else if change.Mode == modes.Operator || change.Mode == modes.LocalOperator {
47
+					} else if change.Mode == modes.Operator {
48 48
 						client.server.stats.ChangeOperators(1)
49 49
 					}
50 50
 					applied = append(applied, change)
@@ -55,7 +55,7 @@ func ApplyUserModeChanges(client *Client, changes modes.ModeChanges, force bool,
55 55
 				if client.SetMode(change.Mode, false) {
56 56
 					if change.Mode == modes.Invisible {
57 57
 						client.server.stats.ChangeInvisible(-1)
58
-					} else if change.Mode == modes.Operator || change.Mode == modes.LocalOperator {
58
+					} else if change.Mode == modes.Operator {
59 59
 						removedSnomasks = client.server.snomasks.String(client)
60 60
 						client.server.stats.ChangeOperators(-1)
61 61
 						applyOper(client, nil, nil)
@@ -91,8 +91,12 @@ func ApplyUserModeChanges(client *Client, changes modes.ModeChanges, force bool,
91 91
 				change.Arg = newArg
92 92
 			}
93 93
 			if change.Op == modes.Add {
94
-				client.server.snomasks.AddMasks(client, masks...)
95
-				applied = append(applied, change)
94
+				oper := client.Oper()
95
+				// #1176: require special operator privileges to subscribe to snomasks
96
+				if oper.HasRoleCapab("snomasks") || oper.HasRoleCapab("ban") {
97
+					client.server.snomasks.AddMasks(client, masks...)
98
+					applied = append(applied, change)
99
+				}
96 100
 			} else if change.Op == modes.Remove {
97 101
 				client.server.snomasks.RemoveMasks(client, masks...)
98 102
 				applied = append(applied, change)

+ 0
- 1
irc/modes/modes.go ファイルの表示

@@ -101,7 +101,6 @@ func (modes Modes) String() string {
101 101
 const (
102 102
 	Bot             Mode = 'B'
103 103
 	Invisible       Mode = 'i'
104
-	LocalOperator   Mode = 'O'
105 104
 	Operator        Mode = 'o'
106 105
 	Restricted      Mode = 'r'
107 106
 	RegisteredOnly  Mode = 'R'

+ 12
- 11
irc/server.go ファイルの表示

@@ -459,15 +459,13 @@ func (server *Server) MOTD(client *Client, rb *ResponseBuffer) {
459 459
 	rb.Add(nil, server.name, RPL_ENDOFMOTD, client.nick, client.t("End of MOTD command"))
460 460
 }
461 461
 
462
-// WhoisChannelsNames returns the common channel names between two users.
463
-func (client *Client) WhoisChannelsNames(target *Client, multiPrefix bool) []string {
462
+func (client *Client) whoisChannelsNames(target *Client, multiPrefix bool, hasPrivs bool) []string {
464 463
 	var chstrs []string
464
+	targetInvis := target.HasMode(modes.Invisible)
465 465
 	for _, channel := range target.Channels() {
466
-		// channel is secret and the target can't see it
467
-		if !client.HasMode(modes.Operator) {
468
-			if (target.HasMode(modes.Invisible) || channel.flags.HasMode(modes.Secret)) && !channel.hasClient(client) {
469
-				continue
470
-			}
466
+		if !hasPrivs && (targetInvis || channel.flags.HasMode(modes.Secret)) && !channel.hasClient(client) {
467
+			// client can't see *this* channel membership
468
+			continue
471 469
 		}
472 470
 		chstrs = append(chstrs, channel.ClientPrefixes(target, multiPrefix)+channel.name)
473 471
 	}
@@ -475,23 +473,26 @@ func (client *Client) WhoisChannelsNames(target *Client, multiPrefix bool) []str
475 473
 }
476 474
 
477 475
 func (client *Client) getWhoisOf(target *Client, hasPrivs bool, rb *ResponseBuffer) {
476
+	oper := client.Oper()
478 477
 	cnick := client.Nick()
479 478
 	targetInfo := target.Details()
480 479
 	rb.Add(nil, client.server.name, RPL_WHOISUSER, cnick, targetInfo.nick, targetInfo.username, targetInfo.hostname, "*", targetInfo.realname)
481 480
 	tnick := targetInfo.nick
482 481
 
483
-	whoischannels := client.WhoisChannelsNames(target, rb.session.capabilities.Has(caps.MultiPrefix))
482
+	whoischannels := client.whoisChannelsNames(target, rb.session.capabilities.Has(caps.MultiPrefix), oper.HasRoleCapab("sajoin"))
484 483
 	if whoischannels != nil {
485 484
 		rb.Add(nil, client.server.name, RPL_WHOISCHANNELS, cnick, tnick, strings.Join(whoischannels, " "))
486 485
 	}
487
-	if target.HasMode(modes.Operator) && operStatusVisible(client, target, hasPrivs) {
486
+	if target.HasMode(modes.Operator) && operStatusVisible(client, target, oper != nil) {
488 487
 		tOper := target.Oper()
489 488
 		if tOper != nil {
490 489
 			rb.Add(nil, client.server.name, RPL_WHOISOPERATOR, cnick, tnick, tOper.WhoisLine)
491 490
 		}
492 491
 	}
493
-	if client == target || hasPrivs {
492
+	if client == target || oper.HasRoleCapab("ban") {
494 493
 		rb.Add(nil, client.server.name, RPL_WHOISACTUALLY, cnick, tnick, fmt.Sprintf("%s@%s", targetInfo.username, target.RawHostname()), target.IPString(), client.t("Actual user@host, Actual IP"))
494
+	}
495
+	if client == target || oper.HasRoleCapab("samode") {
495 496
 		rb.Add(nil, client.server.name, RPL_WHOISMODES, cnick, tnick, fmt.Sprintf(client.t("is using modes +%s"), target.modes.String()))
496 497
 	}
497 498
 	if target.HasMode(modes.TLS) {
@@ -504,7 +505,7 @@ func (client *Client) getWhoisOf(target *Client, hasPrivs bool, rb *ResponseBuff
504 505
 		rb.Add(nil, client.server.name, RPL_WHOISBOT, cnick, tnick, fmt.Sprintf(ircfmt.Unescape(client.t("is a $bBot$b on %s")), client.server.Config().Network.Name))
505 506
 	}
506 507
 
507
-	if client == target || hasPrivs {
508
+	if client == target || oper.HasRoleCapab("ban") {
508 509
 		for _, session := range target.Sessions() {
509 510
 			if session.certfp != "" {
510 511
 				rb.Add(nil, client.server.name, RPL_WHOISCERTFP, cnick, tnick, fmt.Sprintf(client.t("has client certificate fingerprint %s"), session.certfp))

+ 1
- 0
traditional.yaml ファイルの表示

@@ -565,6 +565,7 @@ oper-classes:
565 565
             - "vhosts"
566 566
             - "sajoin"
567 567
             - "samode"
568
+            - "snomasks"
568 569
 
569 570
     # server admin: has full control of the ircd, including nickname and
570 571
     # channel registrations

読み込み中…
キャンセル
保存