Skip to content

Commit 6b64383

Browse files
committed
sql: add setting to validate privs for secondary tenants
This patch adds a cluster setting, `sql.zone_configs.default_range_modifiable_by_non_root.enabled`, to help prevent virtual clusters from setting undesired zone configs. This settings determines if non-root users on these clusters should be restricted from modifying the `default` range. Other named ranges are not allowed to be modified as a secondary tenant. Epic: none Fixes: #142856 Release note: None
1 parent cf33d36 commit 6b64383

File tree

5 files changed

+60
-1
lines changed

5 files changed

+60
-1
lines changed

pkg/ccl/logictestccl/testdata/logic_test/multi_region_secondary_tenants_abstractions_allowed

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,26 @@ statement ok
6060
ALTER DATABASE test CONFIGURE ZONE USING num_replicas = 4, constraints = '{-region=us-east-1: 4}'
6161

6262
subtest end
63+
64+
subtest privileged_range
65+
66+
statement ok
67+
ALTER RANGE default CONFIGURE ZONE USING num_replicas = 10
68+
69+
user host-cluster-root
70+
71+
statement ok
72+
ALTER TENANT ALL SET CLUSTER SETTING sql.zone_configs.default_range_modifiable_by_non_root.enabled = false
73+
74+
user root
75+
76+
statement ok
77+
ALTER RANGE default CONFIGURE ZONE USING num_replicas = 10
78+
79+
statement ok
80+
SET ROLE admin
81+
82+
statement error pgcode 42501 only root users are allowed to modify the default range
83+
ALTER RANGE default CONFIGURE ZONE USING num_replicas = 10
84+
85+
subtest end

pkg/config/zonepb/zone.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ var MaxReplicasPerRegion = settings.RegisterIntSetting(
103103
settings.WithVisibility(settings.Reserved),
104104
settings.NonNegativeInt)
105105

106+
var DefaultRangeModifiableByNonRoot = settings.RegisterBoolSetting(
107+
settings.ApplicationLevel,
108+
"sql.zone_configs.default_range_modifiable_by_non_root.enabled",
109+
"if true, allows non-root users to modify zone config for the "+
110+
"default range",
111+
true,
112+
settings.WithVisibility(settings.Reserved))
113+
106114
// MultiRegionZoneConfigFieldsSet contain the items in
107115
// MultiRegionZoneConfigFields but in a set form for fast lookup.
108116
var MultiRegionZoneConfigFieldsSet = func() map[tree.Name]struct{} {

pkg/sql/schemachanger/scbuild/internal/scbuildstmt/named_range_zone_config.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,21 @@ func (rzo *namedRangeZoneConfigObj) getZoneConfigElemForDrop(
5959
func (rzo *namedRangeZoneConfigObj) checkPrivilegeForSetZoneConfig(
6060
b BuildCtx, _ tree.ZoneSpecifier,
6161
) error {
62+
// Only block privileges for non-root users if this is the default range
63+
// for a secondary tenant with
64+
// sql.zone_configs.default_range_modifiable_by_non_root.enabled set to
65+
// false; other ranges just need the REPAIRCLUSTER privilege.
66+
//
67+
// N.B. The default range has a rangeID of catid.InvalidDescID.
68+
if rzo.rangeID == catid.InvalidDescID && !b.Codec().ForSystemTenant() &&
69+
!zonepb.DefaultRangeModifiableByNonRoot.Get(&b.ClusterSettings().SV) {
70+
if !b.CurrentUser().IsRootUser() {
71+
return pgerror.New(
72+
pgcode.InsufficientPrivilege,
73+
"only root users are allowed to modify the default range",
74+
)
75+
}
76+
}
6277
return b.CheckGlobalPrivilege(privilege.REPAIRCLUSTER)
6378
}
6479

pkg/sql/schemachanger/scbuild/internal/scbuildstmt/zone_config_helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func evaluateZoneOptions(
381381
pgerror.Newf(pgcode.InvalidParameterValue, "unsupported NULL value for %q",
382382
tree.ErrString(name))
383383
}
384-
opt := zone.SupportedZoneConfigOptions[*name] // Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
384+
opt := zone.SupportedZoneConfigOptions[*name]
385385
if opt.CheckAllowed != nil {
386386
if err := opt.CheckAllowed(b, b.ClusterSettings(), datum); err != nil {
387387
return nil, nil, nil, err

pkg/sql/set_zone_config.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,19 @@ func checkPrivilegeForSetZoneConfig(ctx context.Context, p *planner, zs tree.Zon
173173
// an admin. Otherwise we require CREATE privileges on the database or table
174174
// in question.
175175
if zs.NamedZone != "" {
176+
// Only block privileges for non-root users if this is the default range
177+
// for a secondary tenant with
178+
// sql.zone_configs.default_range_modifiable_by_non_root.enabled set to
179+
// false; other ranges just need the REPAIRCLUSTER privilege.
180+
if zonepb.NamedZone(zs.NamedZone.String()) == zonepb.DefaultZoneName && !p.execCfg.Codec.ForSystemTenant() &&
181+
!zonepb.DefaultRangeModifiableByNonRoot.Get(&p.execCfg.Settings.SV) {
182+
if !p.EvalContext().SessionData().User().IsRootUser() {
183+
return pgerror.New(
184+
pgcode.InsufficientPrivilege,
185+
"only root users are allowed to modify the default range",
186+
)
187+
}
188+
}
176189
return p.CheckPrivilege(ctx, syntheticprivilege.GlobalPrivilegeObject, privilege.REPAIRCLUSTER)
177190
}
178191
if zs.Database != "" {

0 commit comments

Comments
 (0)