|
@@ -484,10 +484,40 @@ func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, c
|
484
|
484
|
|
485
|
485
|
applied := make(ModeChanges, 0)
|
486
|
486
|
|
|
487
|
+ isListOp := func(change ModeChange) bool {
|
|
488
|
+ return (change.op == List) || (change.arg == "")
|
|
489
|
+ }
|
|
490
|
+
|
|
491
|
+ hasPrivs := func(change ModeChange) bool {
|
|
492
|
+ if isSamode {
|
|
493
|
+ return true
|
|
494
|
+ }
|
|
495
|
+ switch change.mode {
|
|
496
|
+ case ChannelFounder, ChannelAdmin, ChannelOperator, Halfop, Voice:
|
|
497
|
+ // Admins can't give other people Admin or remove it from others
|
|
498
|
+ if change.mode == ChannelAdmin {
|
|
499
|
+ return false
|
|
500
|
+ }
|
|
501
|
+ if change.op == List {
|
|
502
|
+ return true
|
|
503
|
+ }
|
|
504
|
+ cfarg, _ := CasefoldName(change.arg)
|
|
505
|
+ if change.op == Remove && cfarg == client.nickCasefolded {
|
|
506
|
+ // "There is no restriction, however, on anyone `deopping' themselves"
|
|
507
|
+ // <https://tools.ietf.org/html/rfc2812#section-3.1.5>
|
|
508
|
+ return true
|
|
509
|
+ }
|
|
510
|
+ return channel.ClientIsAtLeast(client, change.mode)
|
|
511
|
+ case BanMask:
|
|
512
|
+ // #163: allow unprivileged users to list ban masks
|
|
513
|
+ return clientIsOp || isListOp(change)
|
|
514
|
+ default:
|
|
515
|
+ return clientIsOp
|
|
516
|
+ }
|
|
517
|
+ }
|
|
518
|
+
|
487
|
519
|
for _, change := range changes {
|
488
|
|
- // chan priv modes are checked specially so ignore them
|
489
|
|
- // means regular users can't view ban/except lists... but I'm not worried about that
|
490
|
|
- if !isSamode && ChannelModePrefixes[change.mode] == "" && !clientIsOp {
|
|
520
|
+ if !hasPrivs(change) {
|
491
|
521
|
if !alreadySentPrivError {
|
492
|
522
|
alreadySentPrivError = true
|
493
|
523
|
client.Send(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, "You're not a channel operator")
|
|
@@ -497,15 +527,13 @@ func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, c
|
497
|
527
|
|
498
|
528
|
switch change.mode {
|
499
|
529
|
case BanMask, ExceptMask, InviteMask:
|
500
|
|
- mask := change.arg
|
501
|
|
-
|
502
|
|
- if (change.op == List) || (mask == "") {
|
|
530
|
+ if isListOp(change) {
|
503
|
531
|
channel.ShowMaskList(client, change.mode)
|
504
|
532
|
continue
|
505
|
533
|
}
|
506
|
534
|
|
507
|
535
|
// confirm mask looks valid
|
508
|
|
- mask, err := Casefold(mask)
|
|
536
|
+ mask, err := Casefold(change.arg)
|
509
|
537
|
if err != nil {
|
510
|
538
|
continue
|
511
|
539
|
}
|
|
@@ -566,31 +594,6 @@ func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, c
|
566
|
594
|
if change.op == List {
|
567
|
595
|
continue
|
568
|
596
|
}
|
569
|
|
- // make sure client has privs to edit the given prefix
|
570
|
|
- hasPrivs := isSamode
|
571
|
|
-
|
572
|
|
- // Admins can't give other people Admin or remove it from others,
|
573
|
|
- // standard for that channel mode, we worry about this later
|
574
|
|
- if !hasPrivs && change.mode != ChannelAdmin {
|
575
|
|
- hasPrivs = channel.ClientIsAtLeast(client, change.mode)
|
576
|
|
- }
|
577
|
|
-
|
578
|
|
- casefoldedName, err := CasefoldName(change.arg)
|
579
|
|
- if err != nil {
|
580
|
|
- continue
|
581
|
|
- }
|
582
|
|
-
|
583
|
|
- if !hasPrivs {
|
584
|
|
- if change.op == Remove && casefoldedName == client.nickCasefolded {
|
585
|
|
- // success!
|
586
|
|
- } else {
|
587
|
|
- if !alreadySentPrivError {
|
588
|
|
- alreadySentPrivError = true
|
589
|
|
- client.Send(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, "You're not a channel operator")
|
590
|
|
- }
|
591
|
|
- continue
|
592
|
|
- }
|
593
|
|
- }
|
594
|
597
|
|
595
|
598
|
change := channel.applyModeMemberNoMutex(client, change.mode, change.op, change.arg)
|
596
|
599
|
if change != nil {
|