@@ -24,6 +24,7 @@ import (
24
24
25
25
"github.com/cockroachdb/apd/v3"
26
26
"github.com/cockroachdb/cockroach/pkg/base"
27
+ "github.com/cockroachdb/cockroach/pkg/clusterversion"
27
28
"github.com/cockroachdb/cockroach/pkg/config/zonepb"
28
29
"github.com/cockroachdb/cockroach/pkg/jobs"
29
30
"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
@@ -46,10 +47,12 @@ import (
46
47
"github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo"
47
48
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
48
49
"github.com/cockroachdb/cockroach/pkg/sql/parser"
50
+ "github.com/cockroachdb/cockroach/pkg/sql/privilege"
49
51
"github.com/cockroachdb/cockroach/pkg/sql/roleoption"
50
52
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
51
53
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
52
54
"github.com/cockroachdb/cockroach/pkg/sql/sqlutil"
55
+ "github.com/cockroachdb/cockroach/pkg/sql/syntheticprivilege"
53
56
"github.com/cockroachdb/cockroach/pkg/ts/catalog"
54
57
"github.com/cockroachdb/cockroach/pkg/util/contextutil"
55
58
"github.com/cockroachdb/cockroach/pkg/util/envutil"
@@ -1828,20 +1831,27 @@ func (s *adminServer) Settings(
1828
1831
// Non-root access cannot see the values in any case.
1829
1832
lookupPurpose = settings .LookupForReporting
1830
1833
1831
- hasView , err := s .hasRoleOption (ctx , user , roleoption .VIEWCLUSTERSETTING )
1832
- if err != nil {
1833
- return nil , err
1834
- }
1835
-
1836
- hasModify , err := s .hasRoleOption (ctx , user , roleoption .MODIFYCLUSTERSETTING )
1837
- if err != nil {
1838
- return nil , err
1834
+ hasView := false
1835
+ hasModify := false
1836
+ if s .st .Version .IsActive (ctx , clusterversion .SystemPrivilegesTable ) {
1837
+ hasView = s .checkHasSystemPrivilege (ctx , user , privilege .VIEWCLUSTERSETTING )
1838
+ hasModify = s .checkHasSystemPrivilege (ctx , user , privilege .MODIFYCLUSTERSETTING )
1839
1839
}
1840
-
1841
1840
if ! hasModify && ! hasView {
1842
- return nil , status .Errorf (
1843
- codes .PermissionDenied , "this operation requires either %s or %s role options" ,
1844
- roleoption .VIEWCLUSTERSETTING , roleoption .MODIFYCLUSTERSETTING )
1841
+ hasView , err := s .hasRoleOption (ctx , user , roleoption .VIEWCLUSTERSETTING )
1842
+ if err != nil {
1843
+ return nil , err
1844
+ }
1845
+
1846
+ hasModify , err := s .hasRoleOption (ctx , user , roleoption .MODIFYCLUSTERSETTING )
1847
+ if err != nil {
1848
+ return nil , err
1849
+ }
1850
+ if ! hasModify && ! hasView {
1851
+ return nil , status .Errorf (
1852
+ codes .PermissionDenied , "this operation requires either %s or %s system privileges" ,
1853
+ privilege .VIEWCLUSTERSETTING , privilege .MODIFYCLUSTERSETTING )
1854
+ }
1845
1855
}
1846
1856
}
1847
1857
@@ -3410,7 +3420,9 @@ func (s *adminServer) dialNode(
3410
3420
// adminPrivilegeChecker is a helper struct to check whether given usernames
3411
3421
// have admin privileges.
3412
3422
type adminPrivilegeChecker struct {
3413
- ie * sql.InternalExecutor
3423
+ ie * sql.InternalExecutor
3424
+ st * cluster.Settings
3425
+ makePlanner func (opName string ) (interface {}, func ())
3414
3426
}
3415
3427
3416
3428
// requireAdminUser's error return is a gRPC error.
@@ -3434,15 +3446,20 @@ func (c *adminPrivilegeChecker) requireViewActivityPermission(ctx context.Contex
3434
3446
return serverError (ctx , err )
3435
3447
}
3436
3448
if ! isAdmin {
3437
- hasViewActivity , err := c . hasRoleOption ( ctx , userName , roleoption . VIEWACTIVITY )
3438
- if err != nil {
3439
- return serverError (ctx , err )
3449
+ hasView := false
3450
+ if c . st . Version . IsActive ( ctx , clusterversion . SystemPrivilegesTable ) {
3451
+ hasView = c . checkHasSystemPrivilege (ctx , userName , privilege . VIEWACTIVITY )
3440
3452
}
3441
-
3442
- if ! hasViewActivity {
3443
- return status .Errorf (
3444
- codes .PermissionDenied , "this operation requires the %s role option" ,
3445
- roleoption .VIEWACTIVITY )
3453
+ if ! hasView {
3454
+ hasView , err := c .hasRoleOption (ctx , userName , roleoption .VIEWACTIVITY )
3455
+ if err != nil {
3456
+ return serverError (ctx , err )
3457
+ }
3458
+ if ! hasView {
3459
+ return status .Errorf (
3460
+ codes .PermissionDenied , "this operation requires the %s system privilege" ,
3461
+ roleoption .VIEWACTIVITY )
3462
+ }
3446
3463
}
3447
3464
}
3448
3465
return nil
@@ -3457,20 +3474,24 @@ func (c *adminPrivilegeChecker) requireViewActivityOrViewActivityRedactedPermiss
3457
3474
return serverError (ctx , err )
3458
3475
}
3459
3476
if ! isAdmin {
3460
- hasViewActivity , err := c .hasRoleOption (ctx , userName , roleoption .VIEWACTIVITY )
3461
- if err != nil {
3462
- return serverError (ctx , err )
3463
- }
3464
-
3465
- if ! hasViewActivity {
3466
- hasViewActivityRedacted , err := c .hasRoleOption (ctx , userName , roleoption .VIEWACTIVITYREDACTED )
3477
+ hasView := false
3478
+ hasViewRedacted := false
3479
+ if c .st .Version .IsActive (ctx , clusterversion .SystemPrivilegesTable ) {
3480
+ hasView = c .checkHasSystemPrivilege (ctx , userName , privilege .VIEWACTIVITY )
3481
+ hasViewRedacted = c .checkHasSystemPrivilege (ctx , userName , privilege .VIEWACTIVITYREDACTED )
3482
+ }
3483
+ if ! hasView && ! hasViewRedacted {
3484
+ hasView , err := c .hasRoleOption (ctx , userName , roleoption .VIEWACTIVITY )
3467
3485
if err != nil {
3468
3486
return serverError (ctx , err )
3469
3487
}
3470
-
3471
- if ! hasViewActivityRedacted {
3488
+ hasViewRedacted , err := c .hasRoleOption (ctx , userName , roleoption .VIEWACTIVITYREDACTED )
3489
+ if err != nil {
3490
+ return serverError (ctx , err )
3491
+ }
3492
+ if ! hasView && ! hasViewRedacted {
3472
3493
return status .Errorf (
3473
- codes .PermissionDenied , "this operation requires the %s or %s role options " ,
3494
+ codes .PermissionDenied , "this operation requires the %s or %s system privileges " ,
3474
3495
roleoption .VIEWACTIVITY , roleoption .VIEWACTIVITYREDACTED )
3475
3496
}
3476
3497
}
@@ -3490,14 +3511,24 @@ func (c *adminPrivilegeChecker) requireViewActivityAndNoViewActivityRedactedPerm
3490
3511
}
3491
3512
3492
3513
if ! isAdmin {
3493
- hasViewActivityRedacted , err := c . hasRoleOption ( ctx , userName , roleoption . VIEWACTIVITYREDACTED )
3494
- if err != nil {
3495
- return serverError (ctx , err )
3514
+ hasViewRedacted := false
3515
+ if c . st . Version . IsActive ( ctx , clusterversion . SystemPrivilegesTable ) {
3516
+ hasViewRedacted = c . checkHasSystemPrivilege (ctx , userName , privilege . VIEWACTIVITYREDACTED )
3496
3517
}
3497
- if hasViewActivityRedacted {
3518
+ if ! hasViewRedacted {
3519
+ hasViewRedacted , err := c .hasRoleOption (ctx , userName , roleoption .VIEWACTIVITYREDACTED )
3520
+ if err != nil {
3521
+ return serverError (ctx , err )
3522
+ }
3523
+ if hasViewRedacted {
3524
+ return status .Errorf (
3525
+ codes .PermissionDenied , "this operation requires %s role option and is not allowed for %s role option" ,
3526
+ roleoption .VIEWACTIVITY , roleoption .VIEWACTIVITYREDACTED )
3527
+ }
3528
+ } else {
3498
3529
return status .Errorf (
3499
- codes .PermissionDenied , "this operation requires %s role option and is not allowed for %s role option " ,
3500
- roleoption .VIEWACTIVITY , roleoption .VIEWACTIVITYREDACTED )
3530
+ codes .PermissionDenied , "this operation requires %s system privilege and is not allowed for %s system privilege " ,
3531
+ privilege .VIEWACTIVITY , privilege .VIEWACTIVITYREDACTED )
3501
3532
}
3502
3533
return c .requireViewActivityPermission (ctx )
3503
3534
}
@@ -3575,6 +3606,19 @@ func (c *adminPrivilegeChecker) hasRoleOption(
3575
3606
return bool (dbDatum ), nil
3576
3607
}
3577
3608
3609
+ // checkHasSystemPrivilege is a helper function which calls
3610
+ // CheckPrivilege and returns a true/false based on the returned
3611
+ // result.
3612
+ func (c * adminPrivilegeChecker ) checkHasSystemPrivilege (
3613
+ ctx context.Context , user username.SQLUsername , privilege privilege.Kind ,
3614
+ ) bool {
3615
+ planner , cleanup := c .makePlanner ("check-system-privilege" )
3616
+ defer cleanup ()
3617
+ aa := planner .(sql.AuthorizationAccessor )
3618
+ err := aa .CheckPrivilegeForUser (ctx , syntheticprivilege .GlobalPrivilegeObject , privilege , user )
3619
+ return err == nil
3620
+ }
3621
+
3578
3622
var errRequiresAdmin = status .Error (codes .PermissionDenied , "this operation requires admin privilege" )
3579
3623
3580
3624
func errRequiresRoleOption (option roleoption.Option ) error {
0 commit comments