From 1e1f77a3ffb6ad9014d6cc03bc023016f190f13b Mon Sep 17 00:00:00 2001 From: Roman Tsisyk <roman@tsisyk.com> Date: Mon, 2 Feb 2015 17:57:24 +0300 Subject: [PATCH] Fix #696: Check global READ permissions for replication --- src/box/box.cc | 6 +++ test/lib/tarantool-python | 2 +- test/replication/cluster.result | 31 +++++++++++++++ test/replication/cluster.test.py | 67 ++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/src/box/box.cc b/src/box/box.cc index f8816e317b..98faad921d 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -344,6 +344,9 @@ box_on_cluster_join(const tt_uuid *server_uuid) void box_process_join(int fd, struct xrow_header *header) { + /* Check permissions */ + access_check_universe(PRIV_R); + assert(header->type == IPROTO_JOIN); struct tt_uuid server_uuid = uuid_nil; xrow_decode_join(header, &server_uuid); @@ -357,6 +360,9 @@ box_process_join(int fd, struct xrow_header *header) void box_process_subscribe(int fd, struct xrow_header *header) { + /* Check permissions */ + access_check_universe(PRIV_R); + /* process SUBSCRIBE request via replication relay */ replication_subscribe(fd, header); } diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python index 0ac9a67edf..cb93bc1111 160000 --- a/test/lib/tarantool-python +++ b/test/lib/tarantool-python @@ -1 +1 @@ -Subproject commit 0ac9a67edffc4147cb64e69b02ad4717b1586e6e +Subproject commit cb93bc11113a106d3b54b92fe15184ded658f393 diff --git a/test/replication/cluster.result b/test/replication/cluster.result index 230cd06a13..3e85cc24bd 100644 --- a/test/replication/cluster.result +++ b/test/replication/cluster.result @@ -1,3 +1,34 @@ +ok - cluster uuid +------------------------------------------------------------- + gh-696: Check global READ permissions for replication +------------------------------------------------------------- +ok - join without read permissions to universe +ok - subscribe without read permissions to universe +box.schema.user.grant('guest', 'read', 'universe') +--- +... +ok - join without write permissions to _cluster +box.schema.user.grant('guest', 'write', 'space', '_cluster') +--- +... +ok - join with granted permissions +box.schema.user.revoke('guest', 'read', 'universe') +--- +... +box.schema.user.revoke('guest', 'write', 'space', '_cluster') +--- +... +box.schema.user.grant('guest', 'replication') +--- +... +ok - join with granted role +box.schema.user.revoke('guest', 'replication') +--- +... +box.snapshot() +--- +- ok +... ------------------------------------------------------------- gh-434: Assertion if replace _cluster tuple ------------------------------------------------------------- diff --git a/test/replication/cluster.test.py b/test/replication/cluster.test.py index 794e15cc8e..37dcab8038 100644 --- a/test/replication/cluster.test.py +++ b/test/replication/cluster.test.py @@ -2,8 +2,75 @@ import os import sys import re import yaml +import uuid from lib.tarantool_server import TarantoolServer +## Get cluster uuid +cluster_uuid = '' +try: + cluster_uuid = yaml.load(server.admin("box.space._schema:get('cluster')", + silent = True))[0][1] + uuid.UUID('{' + cluster_uuid + '}') + print 'ok - cluster uuid' +except Exception as e: + print 'not ok - invalid cluster uuid', e + +print '-------------------------------------------------------------' +print ' gh-696: Check global READ permissions for replication' +print '-------------------------------------------------------------' + +# Generate replica cluster UUID +replica_uuid = str(uuid.uuid4()) + +## Universal read permission is required to perform JOIN/SUBSCRIBE +rows = list(server.sql.py_con.join(replica_uuid)) +print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \ + 'ok' or 'not ok', '-', 'join without read permissions to universe' +rows = list(server.sql.py_con.subscribe(cluster_uuid, replica_uuid)) +print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \ + 'ok' or 'not ok', '-', 'subscribe without read permissions to universe' + +## Write permission to space `_cluster` is required to perform JOIN +server.admin("box.schema.user.grant('guest', 'read', 'universe')") +server.sql.py_con.close() # re-connect with new permissions +rows = list(server.sql.py_con.join(replica_uuid)) +print len(rows) == 1 and rows[0].return_message.find('Write access') >= 0 and \ + 'ok' or 'not ok', '-', 'join without write permissions to _cluster' + +def check_join(msg): + ok = True + for resp in server.sql.py_con.join(replica_uuid): + if resp.completion_status != 0: + print 'not ok', '-', msg, resp.return_message + ok = False + + server.sql.py_con.close() # JOIN brokes protocol + if not ok: + return + tuples = server.sql.py_con.space('_cluster').select(replica_uuid, index = 1) + if len(tuples) == 0: + print 'not ok', '-', msg, 'missing entry in _cluster' + return + server_id = tuples[0][0] + print 'ok', '-', msg + return server_id + +## JOIN with permissions +server.admin("box.schema.user.grant('guest', 'write', 'space', '_cluster')") +server.sql.py_con.close() # re-connect with new permissions +server_id = check_join('join with granted permissions') +server.sql.py_con.space('_cluster').delete(server_id) + +# JOIN with granted role +server.admin("box.schema.user.revoke('guest', 'read', 'universe')") +server.admin("box.schema.user.revoke('guest', 'write', 'space', '_cluster')") +server.admin("box.schema.user.grant('guest', 'replication')") +server.sql.py_con.close() # re-connect with new permissions +server_id = check_join('join with granted role') +server.sql.py_con.space('_cluster').delete(server_id) +server.admin("box.schema.user.revoke('guest', 'replication')") +server.admin('box.snapshot()') + print '-------------------------------------------------------------' print 'gh-434: Assertion if replace _cluster tuple' print '-------------------------------------------------------------' -- GitLab