Skip to content

Commit

Permalink
Merge #75628 #75747
Browse files Browse the repository at this point in the history
75628: sql: fix privileges reported for non-user-defined schemas r=RichardJCai a=rafiss

fixes #68917

They no longer inherit privileges from the parent database.

Release note (sql change): The privileges reported in
information_schema.schema_privileges for non-user-defined schemas no
longer are inferred from the privileges on the parent database. Instead,
virtual schemas (like pg_catalog and information_schema) always report the USAGE
privilege for the public role. The pg_temp schema always reports USAGE
and CREATE privileges for the public role.

75747: sql: added new table to crdb_internal and test for implemented property of pg_catalog tables r=Fenil-P a=Fenil-P

Release note: None

Co-authored-by: Rafi Shamim <[email protected]>
Co-authored-by: Fenil Patel <[email protected]>
  • Loading branch information
3 people committed Feb 1, 2022
3 parents ecab739 + 30c21a3 + 89ceb04 commit be1b6c4
Show file tree
Hide file tree
Showing 21 changed files with 2,987 additions and 2,739 deletions.
9 changes: 1 addition & 8 deletions pkg/ccl/backupccl/restore_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -1323,14 +1323,7 @@ func remapPublicSchemas(
db.AddSchemaToDatabase(tree.PublicSchema, descpb.DatabaseDescriptor_SchemaInfo{ID: id})
// Every database must be initialized with the public schema.
// Create the SchemaDescriptor.
// In postgres, the user "postgres" is the owner of the public schema in a
// newly created db. Postgres and Public have USAGE and CREATE privileges.
// In CockroachDB, root is our substitute for the postgres user.
publicSchemaPrivileges := descpb.NewBasePrivilegeDescriptor(security.AdminRoleName())
// By default, everyone has USAGE and CREATE on the public schema.
// Once https://github.com/cockroachdb/cockroach/issues/70266 is resolved,
// the public role will no longer have CREATE privilege.
publicSchemaPrivileges.Grant(security.PublicRoleName(), privilege.List{privilege.CREATE, privilege.USAGE}, false)
publicSchemaPrivileges := descpb.NewPublicSchemaPrivilegeDescriptor()
publicSchemaDesc := schemadesc.NewBuilder(&descpb.SchemaDescriptor{
ParentID: db.GetID(),
Name: tree.PublicSchema,
Expand Down
3 changes: 2 additions & 1 deletion pkg/cli/zip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ table_name NOT IN (
'cluster_transaction_statistics',
'statement_statistics',
'transaction_statistics',
'tenant_usage_details'
'tenant_usage_details',
'pg_catalog_table_is_implemented'
)
ORDER BY name ASC`)
assert.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/migration/migrations/public_schema_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func createPublicSchemaDescriptor(
ctx, d.DB, d.Codec, desc, tree.PublicSchema, security.AdminRoleName(), security.AdminRoleName(), true, /* allocateID */
)
// The public role has hardcoded privileges; see comment in
// maybeCreatePublicSchemaWithDescriptor.
// descpb.NewPublicSchemaPrivilegeDescriptor.
publicSchemaDesc.Privileges.Grant(
security.PublicRoleName(),
privilege.List{privilege.CREATE, privilege.USAGE},
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/catalog/catconstants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ const (
CrdbInternalDefaultPrivilegesTable
CrdbInternalActiveRangeFeedsTable
CrdbInternalTenantUsageDetailsViewID
CrdbInternalPgCatalogTableIsImplementedTableID
InformationSchemaID
InformationSchemaAdministrableRoleAuthorizationsID
InformationSchemaApplicableRolesID
Expand Down
33 changes: 29 additions & 4 deletions pkg/sql/catalog/descpb/privilege.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,24 +125,33 @@ func NewCustomSuperuserPrivilegeDescriptor(
}
}

// NewPublicSelectPrivilegeDescriptor is used to construct a privilege descriptor
// NewVirtualTablePrivilegeDescriptor is used to construct a privilege descriptor
// owned by the node user which has SELECT privilege for the public role. It is
// used for virtual tables.
func NewPublicSelectPrivilegeDescriptor() *PrivilegeDescriptor {
func NewVirtualTablePrivilegeDescriptor() *PrivilegeDescriptor {
return NewPrivilegeDescriptor(
security.PublicRoleName(), privilege.List{privilege.SELECT}, privilege.List{}, security.NodeUserName(),
)
}

// NewPublicUsagePrivilegeDescriptor is used to construct a privilege descriptor
// NewVirtualSchemaPrivilegeDescriptor is used to construct a privilege descriptor
// owned by the node user which has USAGE privilege for the public role. It is
// used for virtual schemas.
func NewPublicUsagePrivilegeDescriptor() *PrivilegeDescriptor {
func NewVirtualSchemaPrivilegeDescriptor() *PrivilegeDescriptor {
return NewPrivilegeDescriptor(
security.PublicRoleName(), privilege.List{privilege.USAGE}, privilege.List{}, security.NodeUserName(),
)
}

// NewTemporarySchemaPrivilegeDescriptor is used to construct a privilege
// descriptor owned by the admin user which has CREATE and USAGE privilege for
// the public role. It is used for temporary schemas.
func NewTemporarySchemaPrivilegeDescriptor() *PrivilegeDescriptor {
p := NewBasePrivilegeDescriptor(security.AdminRoleName())
p.Grant(security.PublicRoleName(), privilege.List{privilege.CREATE, privilege.USAGE}, false /* withGrantOption */)
return p
}

// NewPrivilegeDescriptor returns a privilege descriptor for the given
// user with the specified list of privileges.
func NewPrivilegeDescriptor(
Expand Down Expand Up @@ -183,6 +192,22 @@ func NewBaseDatabasePrivilegeDescriptor(owner security.SQLUsername) *PrivilegeDe
return p
}

// NewPublicSchemaPrivilegeDescriptor is used to construct a privilege
// descriptor owned by the admin user which has CREATE and USAGE privilege for
// the public role, and ALL privileges for superusers. It is used for the
// public schema.
func NewPublicSchemaPrivilegeDescriptor() *PrivilegeDescriptor {
// In postgres, the user "postgres" is the owner of the public schema in a
// newly created db. In CockroachDB, admin is our substitute for the postgres
// user.
p := NewBasePrivilegeDescriptor(security.AdminRoleName())
// By default, everyone has USAGE and CREATE on the public schema.
// Once https://github.com/cockroachdb/cockroach/issues/70266 is resolved,
// the public role will no longer have CREATE privileges.
p.Grant(security.PublicRoleName(), privilege.List{privilege.CREATE, privilege.USAGE}, false)
return p
}

// CheckGrantOptions returns false if the user tries to grant a privilege that
// it does not possess grant options for
func (p *PrivilegeDescriptor) CheckGrantOptions(
Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/catalog/schemadesc/public_schema_desc.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ var _ catalog.SchemaDescriptor = public{}
func (p public) GetParentID() descpb.ID { return descpb.InvalidID }
func (p public) GetID() descpb.ID { return keys.PublicSchemaID }
func (p public) GetName() string { return tree.PublicSchema }
func (p public) GetPrivileges() *descpb.PrivilegeDescriptor {
return descpb.NewPublicSchemaPrivilegeDescriptor()
}

type publicBase struct{}

Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/catalog/schemadesc/temporary_schema_desc.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ var _ catalog.SchemaDescriptor = temporary{}
func (p temporary) GetID() descpb.ID { return p.id }
func (p temporary) GetName() string { return p.name }
func (p temporary) GetParentID() descpb.ID { return p.parentID }
func (p temporary) GetPrivileges() *descpb.PrivilegeDescriptor {
return descpb.NewTemporarySchemaPrivilegeDescriptor()
}

type temporaryBase struct{}

Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/catalog/schemadesc/virtual_schema_desc.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (p virtual) GetID() descpb.ID { return p.id }
func (p virtual) GetName() string { return p.name }
func (p virtual) GetParentID() descpb.ID { return descpb.InvalidID }
func (p virtual) GetPrivileges() *descpb.PrivilegeDescriptor {
return descpb.NewPublicUsagePrivilegeDescriptor()
return descpb.NewVirtualSchemaPrivilegeDescriptor()
}

type virtualBase struct{}
Expand Down
Loading

0 comments on commit be1b6c4

Please sign in to comment.