summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSlava Koyfman <slavak@users.noreply.github.com>2023-04-02 16:18:28 +0300
committerGitHub <noreply@github.com>2023-04-02 16:18:28 +0300
commitf38aa6bfb7a1bc7a3c5b18fadc513da1152bc7b5 (patch)
tree02902613299fe40dbfefc9c55527b5b52e34e1fd /src
parent1f76bb17ddcb2adc484bf82f1b839c45e264524f (diff)
downloadredis-f38aa6bfb7a1bc7a3c5b18fadc513da1152bc7b5.tar.gz
Disconnect pub-sub subscribers when revoking `allchannels` permission (#11992)
The existing logic for killing pub-sub clients did not handle the `allchannels` permission correctly. For example, if you: ACL SETUSER foo allchannels Have a client authenticate as the user `foo` and subscribe to a channel, and then: ACL SETUSER foo resetchannels The subscribed client would not be disconnected, though new clients under that user would be blocked from subscribing to any channels. This was caused by an incomplete optimization in `ACLKillPubsubClientsIfNeeded` checking whether the new channel permissions were a strict superset of the old ones.
Diffstat (limited to 'src')
-rw-r--r--src/acl.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/acl.c b/src/acl.c
index 8b571d86e..25a9a0a47 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -1891,6 +1891,13 @@ void ACLKillPubsubClientsIfNeeded(user *new, user *original) {
listRewind(original->selectors,&li);
while((ln = listNext(&li)) && match) {
aclSelector *s = (aclSelector *) listNodeValue(ln);
+ /* If any of the original selectors has the all-channels permission, but
+ * the new ones don't (this is checked earlier in this function), then the
+ * new list is not a strict superset of the original. */
+ if (s->flags & SELECTOR_FLAG_ALLCHANNELS) {
+ match = 0;
+ break;
+ }
listRewind(s->channels, &lpi);
while((lpn = listNext(&lpi)) && match) {
if (!listSearchKey(upcoming, listNodeValue(lpn))) {