mirror of
https://github.com/openvswitch/ovs
synced 2025-08-21 17:37:37 +00:00
Previously when an empty mutation was used to count the number of rows in a table, OVSDB would iterate over all rows twice. First to perform an RBAC check, and then to perform the no-operation. This change adds a short circuit to mutate operations with no conditions and an empty mutation set, returning immediately. One notable change in functionality is not performing the RBAC check in this condition, as no mutation actually takes place. Reported-by: Terry Wilson <twilson@redhat.com> Reported-at: https://issues.redhat.com/browse/FDP-359 Signed-off-by: Mike Pattrick <mkp@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
401 lines
16 KiB
Plaintext
401 lines
16 KiB
Plaintext
AT_BANNER([OVSDB -- ovsdb-server rbac])
|
|
|
|
AT_SETUP([ovsdb-server/rbac 2])
|
|
AT_KEYWORDS([ovsdb server rbac])
|
|
AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
|
|
|
|
RBAC_PKIDIR="$(pwd)"
|
|
RBAC_PKI="sh $abs_top_srcdir/utilities/ovs-pki.in --dir=$RBAC_PKIDIR/pki --log=$RBAC_PKIDIR/rbac-pki.log"
|
|
$RBAC_PKI init
|
|
$RBAC_PKI req+sign ovsdb-server switch
|
|
$RBAC_PKI -u req+sign client-1 switch
|
|
$RBAC_PKI -u req+sign client-2 switch
|
|
|
|
AT_DATA([schema],
|
|
[[{"name": "mydb",
|
|
"tables": {
|
|
"Root": {
|
|
"columns": {
|
|
"connections": {
|
|
"type": {
|
|
"key": {"type": "uuid", "refTable": "Connection"},
|
|
"min": 0,
|
|
"max": "unlimited"}}},
|
|
"isRoot": true},
|
|
"Connection": {
|
|
"columns": {
|
|
"target": {
|
|
"type": "string"},
|
|
"role": {
|
|
"type": "string"}}},
|
|
"RBAC_Role": {
|
|
"columns": {
|
|
"name": {"type": "string"},
|
|
"permissions": {
|
|
"type": {"key": {"type": "string"},
|
|
"value": {"type": "uuid",
|
|
"refTable": "RBAC_Permission",
|
|
"refType": "weak"},
|
|
"min": 0, "max": "unlimited"}}},
|
|
"isRoot": true},
|
|
"RBAC_Permission": {
|
|
"columns": {
|
|
"table": {"type": "string"},
|
|
"authorization": {"type": {"key": "string",
|
|
"min": 0,
|
|
"max": "unlimited"}},
|
|
"insert_delete": {"type": "boolean"},
|
|
"update" : {"type": {"key": "string",
|
|
"min": 0,
|
|
"max": "unlimited"}}},
|
|
"isRoot": true},
|
|
"fixed_colors": {
|
|
"columns": {
|
|
"name": {"type": "string"}, "value": {"type": "integer"}},
|
|
"indexes": [["name"]],
|
|
"isRoot": true},
|
|
"user_colors": {
|
|
"columns": {
|
|
"creator": {"type": "string"},
|
|
"name": {"type": "string"},
|
|
"value": {"type": "integer"}},
|
|
"indexes": [["name"]],
|
|
"isRoot": true},
|
|
"other_colors": {
|
|
"columns": {
|
|
"creator": {
|
|
"type": {"key": {"type": "string"},
|
|
"value": {"type": "string"},
|
|
"min": 0, "max": "unlimited"}},
|
|
"name": {"type": "string"},
|
|
"value": {"type": "integer"}},
|
|
"indexes": [["name"]],
|
|
"isRoot": true}
|
|
},
|
|
"version": "5.1.3",
|
|
"cksum": "12345678 9"
|
|
}
|
|
]])
|
|
|
|
AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
|
|
AT_CHECK(
|
|
[[ovsdb-tool transact db \
|
|
'["mydb",
|
|
{"op": "insert",
|
|
"table": "Root",
|
|
"row": {
|
|
"connections": ["set", [["named-uuid", "x"]]]}},
|
|
{"op": "insert",
|
|
"table": "Connection",
|
|
"uuid-name": "x",
|
|
"row": {"target": "pssl:0:127.0.0.1",
|
|
"role": "testrole"}},
|
|
{"op": "insert",
|
|
"table": "fixed_colors",
|
|
"row": {"name": "red",
|
|
"value": '16711680'}},
|
|
{"op": "insert",
|
|
"table": "RBAC_Role",
|
|
"row": {"name": "testrole",
|
|
"permissions": ["map", [["user_colors", ["named-uuid", "y"]],
|
|
["other_colors", ["named-uuid", "z"]]]]}},
|
|
{"op": "insert",
|
|
"table": "RBAC_Permission",
|
|
"uuid-name": "y",
|
|
"row": {"authorization": "creator",
|
|
"insert_delete": true,
|
|
"table": "user_colors",
|
|
"update": ["set", ["name", "value"]]}},
|
|
{"op": "insert",
|
|
"table": "RBAC_Permission",
|
|
"uuid-name": "z",
|
|
"row": {"authorization": "creator:chassis",
|
|
"insert_delete": true,
|
|
"table": "user_colors",
|
|
"update": ["set", ["name", "value"]]}}
|
|
]']], [0], [ignore], [ignore])
|
|
|
|
AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --remote=db:mydb,Root,connections \
|
|
--private-key=$RBAC_PKIDIR/ovsdb-server-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/ovsdb-server-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
db], [0], [ignore], [ignore])
|
|
PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
|
|
|
|
# Test 1:
|
|
# Attempt to insert a row into the "fixed_colors" table. This should
|
|
# fail as there are no permissions for role "testrole" for this table.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "insert",
|
|
"table": "fixed_colors",
|
|
"row": {"name": "chartreuse", "value": '8388352'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"details":"RBAC rules for client \"client-1\" role \"testrole\" prohibit row insertion into table \"fixed_colors\".","error":"permission error"}]]
|
|
], [ignore])
|
|
|
|
# Test 2:
|
|
# Attempt to insert a row into the "user_colors" table with a client ID that
|
|
# does not match the value in the column used for authorization. This should
|
|
# fail the authorization check for insertion.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "insert",
|
|
"table": "user_colors",
|
|
"row": {"creator": "client-2", "name": "chartreuse", "value": '8388352'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"details":"RBAC rules for client \"client-1\" role \"testrole\" prohibit row insertion into table \"user_colors\".","error":"permission error"}]]
|
|
], [ignore])
|
|
|
|
# Test 3:
|
|
# Attempt to insert a row into the "user_colors" table. This should
|
|
# succeed since role "testrole" has permissions for this table that
|
|
# allow row insertion.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "insert",
|
|
"table": "user_colors",
|
|
"row": {"creator": "client-1", "name": "chartreuse", "value": '8388352'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"uuid":["uuid","<0>"]}]]
|
|
], [ignore])
|
|
|
|
# Test 4:
|
|
# Attempt to update a column in the "user_colors" table. This should
|
|
# succeed since role "testrole" has permissions for this table that
|
|
# allow update of the "value" column when ID is equal to the value in
|
|
# the "creator" column.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "update",
|
|
"table": "user_colors",
|
|
"where": [["name", "==", "chartreuse"]],
|
|
"row": {"value": '8388353'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"count":1}]]
|
|
], [ignore])
|
|
|
|
# Test 5:
|
|
# Attempt to update a column in the "user_colors" table. Same as
|
|
# previous test, but with a different client ID. This should fail
|
|
# the RBAC authorization test because "client-2" does not match the
|
|
# "creator" column for this row.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-2-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-2-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "update",
|
|
"table": "user_colors",
|
|
"where": [["name", "==", "chartreuse"]],
|
|
"row": {"value": '8388354'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"details":"RBAC rules for client \"client-2\" role \"testrole\" prohibit modification of table \"user_colors\".","error":"permission error"}]]
|
|
], [ignore])
|
|
|
|
# Test 6:
|
|
# Attempt to mutate a column in the "user_colors" table. This should
|
|
# succeed since role "testrole" has permissions for this table that
|
|
# allow update of the "value" column when ID is equal to the value in
|
|
# the "creator" column.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "mutate",
|
|
"table": "user_colors",
|
|
"where": [["name", "==", "chartreuse"]],
|
|
"mutations": [["value", "+=", '10']]}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"count":1}]]
|
|
], [ignore])
|
|
|
|
# Test 7:
|
|
# Attempt to mutate a column in the "user_colors" table. Same as
|
|
# previous test, but with a different client ID. This should fail
|
|
# the RBAC authorization test because "client-2" does not match the
|
|
# "creator" column for this row.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-2-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-2-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "mutate",
|
|
"table": "user_colors",
|
|
"where": [["name", "==", "chartreuse"]],
|
|
"mutations": [["value", "+=", '10']]}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"details":"RBAC rules for client \"client-2\" role \"testrole\" prohibit mutate operation on table \"user_colors\".","error":"permission error"}]]
|
|
], [ignore])
|
|
|
|
# Test 8:
|
|
# Attempt to delete a row from the "user_colors" table. This should fail
|
|
# the RBAC authorization test because "client-2" does not match the
|
|
# "creator" column for this row.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-2-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-2-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "delete",
|
|
"table": "user_colors",
|
|
"where": [["name", "==", "chartreuse"]]}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"details":"RBAC rules for client \"client-2\" role \"testrole\" prohibit row deletion from table \"user_colors\".","error":"permission error"}]]
|
|
], [ignore])
|
|
|
|
# Test 9:
|
|
# Attempt to delete a row from the "user_colors" table. This should pass
|
|
# the RBAC authorization test because "client-1" does matches the
|
|
# "creator" column for this row.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "delete",
|
|
"table": "user_colors",
|
|
"where": [["name", "==", "chartreuse"]]}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"count":1}]]
|
|
], [ignore])
|
|
|
|
# Test 10:
|
|
# Attempt to insert a row into the "other_colors" table. This should
|
|
# succeed since role "testrole" has permissions for this table that
|
|
# allow row insertion.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "insert",
|
|
"table": "other_colors",
|
|
"row": {"creator": ["map",[["chassis", "client-1"]]], "name": "seafoam", "value": '7466680'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"uuid":["uuid","<0>"]}]]
|
|
], [ignore])
|
|
|
|
# Test 11:
|
|
# Attempt to update a column in the "user_colors" table. This should
|
|
# succeed since role "testrole" has permissions for this table that
|
|
# allow update of the "value" column when ID is equal to the value in
|
|
# the "creator" column.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "update",
|
|
"table": "other_colors",
|
|
"where": [["name", "==", "seafoam"]],
|
|
"row": {"value": '8388353'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"count":1}]]
|
|
], [ignore])
|
|
|
|
# Test 12:
|
|
# Attempt to update a column in the "other_colors" table. Same as
|
|
# previous test, but with a different client ID. This should fail
|
|
# the RBAC authorization test because "client-2" does not match the
|
|
# "creator" column for this row.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-2-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-2-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "update",
|
|
"table": "other_colors",
|
|
"where": [["name", "==", "seafoam"]],
|
|
"row": {"value": '8388354'}}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"details":"RBAC rules for client \"client-2\" role \"testrole\" prohibit modification of table \"other_colors\".","error":"permission error"}]]
|
|
], [ignore])
|
|
|
|
# Test 13:
|
|
# Attempt to delete a row from the "other_colors" table. This should fail
|
|
# the RBAC authorization test because "client-2" does not match the
|
|
# "creator" column for this row.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-2-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-2-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "delete",
|
|
"table": "other_colors",
|
|
"where": [["name", "==", "seafoam"]]}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"details":"RBAC rules for client \"client-2\" role \"testrole\" prohibit row deletion from table \"other_colors\".","error":"permission error"}]]
|
|
], [ignore])
|
|
|
|
# Test 14:
|
|
# Count the rows in other_colors. This should pass even though the RBAC
|
|
# authorization would fail because "client-2" does not match the
|
|
# "creator" column for this row. Because the RBAC check is bypassed when
|
|
# mutation is empty.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-2-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-2-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "mutate",
|
|
"table": "other_colors",
|
|
"where": [],
|
|
"mutations": []},
|
|
{"op": "mutate",
|
|
"table": "other_colors",
|
|
"where": [["name", "==", "seafoam"]],
|
|
"mutations": []}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"count":1},{"count":1}]]
|
|
], [ignore])
|
|
|
|
# Test 15:
|
|
# Attempt to delete a row from the "other_colors" table. This should pass
|
|
# the RBAC authorization test because "client-1" does matches the
|
|
# "creator" column for this row.
|
|
AT_CHECK([ovsdb-client transact ssl:127.0.0.1:$SSL_PORT \
|
|
--private-key=$RBAC_PKIDIR/client-1-privkey.pem \
|
|
--certificate=$RBAC_PKIDIR/client-1-cert.pem \
|
|
--ca-cert=$RBAC_PKIDIR/pki/switchca/cacert.pem \
|
|
['["mydb",
|
|
{"op": "delete",
|
|
"table": "other_colors",
|
|
"where": [["name", "==", "seafoam"]]}
|
|
]']], [0], [stdout], [ignore])
|
|
cat stdout >> output
|
|
AT_CHECK([uuidfilt stdout], [0], [[[{"count":1}]]
|
|
], [ignore])
|
|
|
|
OVSDB_SERVER_SHUTDOWN(["
|
|
/No status column present in the Connection table/d
|
|
"])
|
|
AT_CLEANUP
|