-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sql: SHOW GRANTS includes inherited roles #104119
Conversation
It looks like your PR touches production code but doesn't add or edit any test code. Did you consider adding tests to your PR? 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
5a9e1da
to
1224785
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is looking good! i think we should add tests for each one of: SHOW GRANTS ON [TABLE|SCHEMA|DATABASE|TYPE|FUNCTION]
that demonstrate that they show the inherited privileges too
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @postamar)
pkg/sql/crdb_internal.go
line 8059 at r1 (raw file):
// This is defined as a table instead of a more straightforward view // because we want the query to run under the node user. const query = `
have you tried testing how this performs? i've crafted a query like this before and i think it had some bad issues
i'm thinking it would be better if we used the existing role-membership cache. because of how commonly we need to look up memberships, the way the cache works is that it actually loads everything in eagerly. so if we just iterate through each user using the forEachRole
helper, and then call planner.MemberOfWithAdminOption
for each one, it might actually perform better
pkg/sql/logictest/testdata/logic_test/pg_catalog
line 1639 at r1 (raw file):
---- classid objid objsubid refclassid refobjid refobjsubid deptype 4294967102 111 0 4294967105 110 14 a
what made all the OIDs change? is it from adding CrdbInternalInheritedRoleMembersTableID
? (that's fine if so, though it's unpleasant)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I completely forgot to do this.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @rafiss)
pkg/sql/crdb_internal.go
line 8059 at r1 (raw file):
Previously, rafiss (Rafi Shamim) wrote…
have you tried testing how this performs? i've crafted a query like this before and i think it had some bad issues
i'm thinking it would be better if we used the existing role-membership cache. because of how commonly we need to look up memberships, the way the cache works is that it actually loads everything in eagerly. so if we just iterate through each user using the
forEachRole
helper, and then callplanner.MemberOfWithAdminOption
for each one, it might actually perform better
Agreed, this seems better in every way.
pkg/sql/logictest/testdata/logic_test/pg_catalog
line 1639 at r1 (raw file):
Previously, rafiss (Rafi Shamim) wrote…
what made all the OIDs change? is it from adding
CrdbInternalInheritedRoleMembersTableID
? (that's fine if so, though it's unpleasant)
Yes indeed.
2ed81fb
to
7d94b00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @postamar)
pkg/sql/crdb_internal.go
line 8057 at r2 (raw file):
);`, populate: func(ctx context.Context, p *planner, _ catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) (retErr error) { explicit := make(map[username.SQLUsername]map[username.SQLUsername]bool)
could you add a comment for why we need explicit
(or perhaps a different name would make it more clear)
pkg/sql/crdb_internal.go
line 8058 at r2 (raw file):
populate: func(ctx context.Context, p *planner, _ catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) (retErr error) { explicit := make(map[username.SQLUsername]map[username.SQLUsername]bool) if err := forEachRoleMembership(ctx, p.InternalSQLTxn(), func(role, member username.SQLUsername, isAdmin bool) error {
this seems to work, but it won't use the cache. that could be fine, but if it's easy to do without changing any existing logic, i would still vote for using forEachRole and then calling MemberOfWithAdminOption for each one.
pkg/sql/delegate/show_role_grants.go
line 70 at r2 (raw file):
query := fmt.Sprintf(` WITH
could you add some commentary to explain in english why we need both u
and explicit
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @postamar)
pkg/sql/crdb_internal.go
line 8058 at r2 (raw file):
Previously, rafiss (Rafi Shamim) wrote…
this seems to work, but it won't use the cache. that could be fine, but if it's easy to do without changing any existing logic, i would still vote for using forEachRole and then calling MemberOfWithAdminOption for each one.
nvm, ignore this comment. i see now that we do use the cache below, and this is just for getting the explicit memberships.
Thanks for taking another look, I've added some commentary. Please do let me know if it needs to be reworded again, I've been focused on this issue for long enough that I've lost perspective somewhat. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the new commentary is extremely helpful. thanks!
we will need to backport this, since the field teams need it, so i'm adding some labels
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @postamar)
Thanks for the review!
|
Yes to both:
It seems safe to me. It is a behavior change, but it is backwards-compatible.
This is safe since vtables are always populated by just one node. Though if we find for some reason that it's not safe, for example, due to how the vtable is populated, then we would also need a 23.2 version gate. I don't think that concern applies here. |
Thanks!
My worry was more that because SHOW GRANTS ON ROLE delegates to a nested query which might be processed in a distributed fashion, the node that would populate the vtable might be a different node and therefore potentially unpatched. bors r+ |
hmm i suppose that's a fair concern. let's at least do some diligence: this should now be quite easy to test using the bors r- |
Canceled. |
We would have to have the SHOW GRANTS performed on a node with the new binary, which is easy enough, but how do we ensure that the query gets distributed in such a way that the vtable scan takes place on an old binary? Or do we just hope that the test never flaking means that the implementation is safe? |
Also, once we backport this patch to 23.1, such a test cannot fail, because it will pull the latest maintenance version of 23.1. |
yes i think in this case we can just use the flakiness as a signal. although one thing i would say is that since the behavior is backwards-compatible, i believe it's OK that in a mixed version state, you might see the old behavior. i just want to ensure there's no error/crash.
hm that's a good point. well, the test will still exist in the 23.1 branch though, which would run in a 22.2/23.1 mixed state |
I haven't gotten anywhere with disabling distsql (thanks anyway @mgartner ) so I'll just add the test and call it a day. |
Previously, SHOW GRANTS would only list explicitly-granted privileges. This commit changes its output to include privileges inherited by role membership. Consider for example: CREATE DATABASE d1; CREATE ROLE r1; CREATE USER u1; GRANT r1 TO u1; SET database = d1; CREATE TABLE t1 (id INT8); GRANT ALL ON TABLE t1 TO r1; We want `SHOW GRANTS ON TABLE t1 FOR u1` to list the ALL privilege that u1 inherits from r1. For this purpose this commit also adds a new `kv_inherited_role_members` virtual table in `crdb_internal` which is essentially a recursive self-join of `system.role_members` run by the node user. This commit also changes the output of `SHOW GRANTS ON ROLE` to list both explicit and implicit grantees: the former are the direct result of a `GRANT ... TO ...` statement, the latter comprise also all the roles which inherit the privileges following further role membership relationships. For this purpose it also uses the new virtual table and therefore the current user no longer requires SELECT privileges on the `system.role_members` table. Fixes cockroachdb#97299. Release note (sql change): SHOW GRANTS now lists not just privileges explicitly granted to each role, but also roles which inherit from those. SHOW GRANTS ON ROLE statements no longer require any privileges and also lists implicit grantees.
Thank you for updating your pull request. My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
bors r+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the extra testing!
Reviewed 15 of 19 files at r1, 5 of 7 files at r2, 1 of 2 files at r3, 2 of 2 files at r4, 1 of 1 files at r5, all commit messages.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @postamar)
Build failed: |
bors r+ |
Build succeeded: |
Encountered an error creating backports. Some common things that can go wrong:
You might need to create your backport manually using the backport tool. error creating merge commit from ab08f1d to blathers/backport-release-22.2-104119: POST https://api.github.com/repos/cockroachdb/cockroach/merges: 409 Merge conflict [] you may need to manually resolve merge conflicts with the backport tool. Backport to branch 22.2.x failed. See errors above. error creating merge commit from ab08f1d to blathers/backport-release-23.1-104119: POST https://api.github.com/repos/cockroachdb/cockroach/merges: 409 Merge conflict [] you may need to manually resolve merge conflicts with the backport tool. Backport to branch 23.1.x failed. See errors above. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
Previously, SHOW GRANTS would only list explicitly-granted privileges.
This commit changes its output to include privileges inherited by role
membership.
Consider for example:
We want
SHOW GRANTS ON TABLE t1 FOR u1
to list the ALL privilege thatu1 inherits from r1.
For this purpose this commit also adds a new
kv_inherited_role_members
virtual table in
crdb_internal
which is essentially a recursiveself-join of
system.role_members
run by the node user.This commit also changes the output of
SHOW GRANTS ON ROLE
to listboth explicit and implicit grantees: the former are the direct result of
a
GRANT ... TO ...
statement, the latter comprise also all the roleswhich inherit the privileges following further role membership
relationships. For this purpose it also uses the new virtual table and
therefore the current user no longer requires SELECT privileges on the
system.role_members
table.Fixes #97299.
Release note (sql change): SHOW GRANTS now lists not just privileges
explicitly granted to each role, but also roles which inherit from
those. SHOW GRANTS ON ROLE statements no longer require any privileges
and also lists implicit grantees.