github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/privilege_test.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sqlbase 12 13 import ( 14 "testing" 15 16 "github.com/cockroachdb/cockroach/pkg/keys" 17 "github.com/cockroachdb/cockroach/pkg/security" 18 "github.com/cockroachdb/cockroach/pkg/sql/privilege" 19 "github.com/cockroachdb/cockroach/pkg/testutils" 20 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 21 ) 22 23 func TestPrivilege(t *testing.T) { 24 defer leaktest.AfterTest(t)() 25 descriptor := NewDefaultPrivilegeDescriptor() 26 27 testCases := []struct { 28 grantee string // User to grant/revoke privileges on. 29 grant, revoke privilege.List 30 show []UserPrivilegeString 31 }{ 32 {"", nil, nil, 33 []UserPrivilegeString{ 34 {AdminRole, []string{"ALL"}}, 35 {security.RootUser, []string{"ALL"}}, 36 }, 37 }, 38 {security.RootUser, privilege.List{privilege.ALL}, nil, 39 []UserPrivilegeString{ 40 {AdminRole, []string{"ALL"}}, 41 {security.RootUser, []string{"ALL"}}, 42 }, 43 }, 44 {security.RootUser, privilege.List{privilege.INSERT, privilege.DROP}, nil, 45 []UserPrivilegeString{ 46 {AdminRole, []string{"ALL"}}, 47 {security.RootUser, []string{"ALL"}}, 48 }, 49 }, 50 {"foo", privilege.List{privilege.INSERT, privilege.DROP}, nil, 51 []UserPrivilegeString{ 52 {AdminRole, []string{"ALL"}}, 53 {"foo", []string{"DROP", "INSERT"}}, 54 {security.RootUser, []string{"ALL"}}, 55 }, 56 }, 57 {"bar", nil, privilege.List{privilege.INSERT, privilege.ALL}, 58 []UserPrivilegeString{ 59 {AdminRole, []string{"ALL"}}, 60 {"foo", []string{"DROP", "INSERT"}}, 61 {security.RootUser, []string{"ALL"}}, 62 }, 63 }, 64 {"foo", privilege.List{privilege.ALL}, nil, 65 []UserPrivilegeString{ 66 {AdminRole, []string{"ALL"}}, 67 {"foo", []string{"ALL"}}, 68 {security.RootUser, []string{"ALL"}}, 69 }, 70 }, 71 {"foo", nil, privilege.List{privilege.SELECT, privilege.INSERT}, 72 []UserPrivilegeString{ 73 {AdminRole, []string{"ALL"}}, 74 {"foo", []string{"CREATE", "DELETE", "DROP", "GRANT", "UPDATE", "ZONECONFIG"}}, 75 {security.RootUser, []string{"ALL"}}, 76 }, 77 }, 78 {"foo", nil, privilege.List{privilege.ALL}, 79 []UserPrivilegeString{ 80 {AdminRole, []string{"ALL"}}, 81 {security.RootUser, []string{"ALL"}}, 82 }, 83 }, 84 // Validate checks that root still has ALL privileges, but we do not call it here. 85 {security.RootUser, nil, privilege.List{privilege.ALL}, 86 []UserPrivilegeString{ 87 {AdminRole, []string{"ALL"}}, 88 }, 89 }, 90 } 91 92 for tcNum, tc := range testCases { 93 if tc.grantee != "" { 94 if tc.grant != nil { 95 descriptor.Grant(tc.grantee, tc.grant) 96 } 97 if tc.revoke != nil { 98 descriptor.Revoke(tc.grantee, tc.revoke) 99 } 100 } 101 show := descriptor.Show() 102 if len(show) != len(tc.show) { 103 t.Fatalf("#%d: show output for descriptor %+v differs, got: %+v, expected %+v", 104 tcNum, descriptor, show, tc.show) 105 } 106 for i := 0; i < len(show); i++ { 107 if show[i].User != tc.show[i].User || show[i].PrivilegeString() != tc.show[i].PrivilegeString() { 108 t.Fatalf("#%d: show output for descriptor %+v differs, got: %+v, expected %+v", 109 tcNum, descriptor, show, tc.show) 110 } 111 } 112 } 113 } 114 115 func TestCheckPrivilege(t *testing.T) { 116 defer leaktest.AfterTest(t)() 117 118 testCases := []struct { 119 pd *PrivilegeDescriptor 120 user string 121 priv privilege.Kind 122 exp bool 123 }{ 124 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE}), 125 "foo", privilege.CREATE, true}, 126 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE}), 127 "bar", privilege.CREATE, false}, 128 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE}), 129 "bar", privilege.DROP, false}, 130 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE}), 131 "foo", privilege.DROP, false}, 132 {NewPrivilegeDescriptor("foo", privilege.List{privilege.ALL}), 133 "foo", privilege.CREATE, true}, 134 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE}), 135 "foo", privilege.ALL, false}, 136 {NewPrivilegeDescriptor("foo", privilege.List{privilege.ALL}), 137 "foo", privilege.ALL, true}, 138 {NewPrivilegeDescriptor("foo", privilege.List{}), 139 "foo", privilege.ALL, false}, 140 {NewPrivilegeDescriptor("foo", privilege.List{}), 141 "foo", privilege.CREATE, false}, 142 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE, privilege.DROP}), 143 "foo", privilege.UPDATE, false}, 144 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE, privilege.DROP}), 145 "foo", privilege.DROP, true}, 146 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE, privilege.ALL}), 147 "foo", privilege.DROP, true}, 148 } 149 150 for tcNum, tc := range testCases { 151 if found := tc.pd.CheckPrivilege(tc.user, tc.priv); found != tc.exp { 152 t.Errorf("#%d: CheckPrivilege(%s, %v) for descriptor %+v = %t, expected %t", 153 tcNum, tc.user, tc.priv, tc.pd, found, tc.exp) 154 } 155 } 156 } 157 158 func TestAnyPrivilege(t *testing.T) { 159 defer leaktest.AfterTest(t)() 160 161 testCases := []struct { 162 pd *PrivilegeDescriptor 163 user string 164 exp bool 165 }{ 166 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE}), 167 "foo", true}, 168 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE}), 169 "bar", false}, 170 {NewPrivilegeDescriptor("foo", privilege.List{privilege.ALL}), 171 "foo", true}, 172 {NewPrivilegeDescriptor("foo", privilege.List{}), 173 "foo", false}, 174 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE, privilege.DROP}), 175 "foo", true}, 176 {NewPrivilegeDescriptor("foo", privilege.List{privilege.CREATE, privilege.DROP}), 177 "bar", false}, 178 } 179 180 for tcNum, tc := range testCases { 181 if found := tc.pd.AnyPrivilege(tc.user); found != tc.exp { 182 t.Errorf("#%d: AnyPrivilege(%s) for descriptor %+v = %t, expected %t", 183 tcNum, tc.user, tc.pd, found, tc.exp) 184 } 185 } 186 } 187 188 // TestPrivilegeValidate exercises validation for non-system descriptors. 189 func TestPrivilegeValidate(t *testing.T) { 190 defer leaktest.AfterTest(t)() 191 id := ID(keys.MinUserDescID) 192 descriptor := NewDefaultPrivilegeDescriptor() 193 if err := descriptor.Validate(id); err != nil { 194 t.Fatal(err) 195 } 196 descriptor.Grant("foo", privilege.List{privilege.ALL}) 197 if err := descriptor.Validate(id); err != nil { 198 t.Fatal(err) 199 } 200 descriptor.Grant(security.RootUser, privilege.List{privilege.SELECT}) 201 if err := descriptor.Validate(id); err != nil { 202 t.Fatal(err) 203 } 204 descriptor.Revoke(security.RootUser, privilege.List{privilege.SELECT}) 205 if err := descriptor.Validate(id); err == nil { 206 t.Fatal("unexpected success") 207 } 208 // TODO(marc): validate fails here because we do not aggregate 209 // privileges into ALL when all are set. 210 descriptor.Grant(security.RootUser, privilege.List{privilege.SELECT}) 211 if err := descriptor.Validate(id); err == nil { 212 t.Fatal("unexpected success") 213 } 214 descriptor.Revoke(security.RootUser, privilege.List{privilege.ALL}) 215 if err := descriptor.Validate(id); err == nil { 216 t.Fatal("unexpected success") 217 } 218 } 219 220 // TestSystemPrivilegeValidate exercises validation for system config 221 // descriptors. We use a dummy system table installed for testing 222 // purposes. 223 func TestSystemPrivilegeValidate(t *testing.T) { 224 defer leaktest.AfterTest(t)() 225 226 id := ID(keys.MaxReservedDescID) 227 if _, exists := SystemAllowedPrivileges[id]; exists { 228 t.Fatalf("system object with maximum id %d already exists--is the reserved id space full?", id) 229 } 230 SystemAllowedPrivileges[id] = privilege.List{ 231 privilege.SELECT, 232 privilege.GRANT, 233 } 234 defer delete(SystemAllowedPrivileges, id) 235 236 rootWrongPrivilegesErr := "user root must have exactly SELECT, GRANT " + 237 "privileges on system object with ID=.*" 238 adminWrongPrivilegesErr := "user admin must have exactly SELECT, GRANT " + 239 "privileges on system object with ID=.*" 240 241 { 242 // Valid: root user has one of the allowable privilege sets. 243 descriptor := NewCustomSuperuserPrivilegeDescriptor( 244 privilege.List{privilege.SELECT, privilege.GRANT}, 245 ) 246 if err := descriptor.Validate(id); err != nil { 247 t.Fatal(err) 248 } 249 250 // Valid: foo has a subset of the allowed privileges. 251 descriptor.Grant("foo", privilege.List{privilege.SELECT}) 252 if err := descriptor.Validate(id); err != nil { 253 t.Fatal(err) 254 } 255 256 // Valid: foo has exactly the allowed privileges. 257 descriptor.Grant("foo", privilege.List{privilege.GRANT}) 258 if err := descriptor.Validate(id); err != nil { 259 t.Fatal(err) 260 } 261 } 262 263 { 264 // Valid: root has exactly the allowed privileges. 265 descriptor := NewCustomSuperuserPrivilegeDescriptor( 266 privilege.List{privilege.SELECT, privilege.GRANT}, 267 ) 268 269 // Valid: foo has a subset of the allowed privileges. 270 descriptor.Grant("foo", privilege.List{privilege.GRANT}) 271 if err := descriptor.Validate(id); err != nil { 272 t.Fatal(err) 273 } 274 275 // Valid: foo can have privileges revoked, including privileges it doesn't currently have. 276 descriptor.Revoke("foo", privilege.List{privilege.GRANT, privilege.UPDATE, privilege.ALL}) 277 if err := descriptor.Validate(id); err != nil { 278 t.Fatal(err) 279 } 280 281 // Invalid: root user has too many privileges. 282 descriptor.Grant(security.RootUser, privilege.List{privilege.UPDATE}) 283 if err := descriptor.Validate(id); !testutils.IsError(err, rootWrongPrivilegesErr) { 284 t.Fatalf("expected err=%s, got err=%v", rootWrongPrivilegesErr, err) 285 } 286 } 287 288 { 289 // Invalid: root has a non-allowable privilege set. 290 descriptor := NewCustomSuperuserPrivilegeDescriptor(privilege.List{privilege.UPDATE}) 291 if err := descriptor.Validate(id); !testutils.IsError(err, rootWrongPrivilegesErr) { 292 t.Fatalf("expected err=%s, got err=%v", rootWrongPrivilegesErr, err) 293 } 294 295 // Invalid: root's invalid privileges are revoked and replaced with allowable privileges, 296 // but admin is still wrong. 297 descriptor.Revoke(security.RootUser, privilege.List{privilege.UPDATE}) 298 descriptor.Grant(security.RootUser, privilege.List{privilege.SELECT, privilege.GRANT}) 299 if err := descriptor.Validate(id); !testutils.IsError(err, adminWrongPrivilegesErr) { 300 t.Fatalf("expected err=%s, got err=%v", adminWrongPrivilegesErr, err) 301 } 302 303 // Valid: admin's invalid privileges are revoked and replaced with allowable privileges. 304 descriptor.Revoke(AdminRole, privilege.List{privilege.UPDATE}) 305 descriptor.Grant(AdminRole, privilege.List{privilege.SELECT, privilege.GRANT}) 306 if err := descriptor.Validate(id); err != nil { 307 t.Fatal(err) 308 } 309 310 // Valid: foo has less privileges than root. 311 descriptor.Grant("foo", privilege.List{privilege.GRANT}) 312 if err := descriptor.Validate(id); err != nil { 313 t.Fatal(err) 314 } 315 } 316 } 317 318 func TestFixPrivileges(t *testing.T) { 319 defer leaktest.AfterTest(t)() 320 321 // Use a non-system ID. 322 userID := ID(keys.MinUserDescID) 323 userPrivs := privilege.List{privilege.ALL} 324 325 // And create an entry for a fake system table. 326 systemID := ID(keys.MaxReservedDescID) 327 if _, exists := SystemAllowedPrivileges[systemID]; exists { 328 t.Fatalf("system object with maximum id %d already exists--is the reserved id space full?", systemID) 329 } 330 systemPrivs := privilege.List{ 331 privilege.SELECT, 332 privilege.GRANT, 333 } 334 SystemAllowedPrivileges[systemID] = systemPrivs 335 defer delete(SystemAllowedPrivileges, systemID) 336 337 type userPrivileges map[string]privilege.List 338 339 testCases := []struct { 340 id ID 341 input userPrivileges 342 modified bool 343 output userPrivileges 344 }{ 345 { 346 // Empty privileges for system ID. 347 systemID, 348 userPrivileges{}, 349 true, 350 userPrivileges{ 351 security.RootUser: systemPrivs, 352 AdminRole: systemPrivs, 353 }, 354 }, 355 { 356 // Valid requirements for system ID. 357 systemID, 358 userPrivileges{ 359 security.RootUser: systemPrivs, 360 AdminRole: systemPrivs, 361 "foo": privilege.List{privilege.SELECT}, 362 "bar": privilege.List{privilege.GRANT}, 363 "baz": privilege.List{privilege.SELECT, privilege.GRANT}, 364 }, 365 false, 366 userPrivileges{ 367 security.RootUser: systemPrivs, 368 AdminRole: systemPrivs, 369 "foo": privilege.List{privilege.SELECT}, 370 "bar": privilege.List{privilege.GRANT}, 371 "baz": privilege.List{privilege.SELECT, privilege.GRANT}, 372 }, 373 }, 374 { 375 // Too many privileges for system ID. 376 systemID, 377 userPrivileges{ 378 security.RootUser: privilege.List{privilege.ALL}, 379 AdminRole: privilege.List{privilege.ALL}, 380 "foo": privilege.List{privilege.ALL}, 381 "bar": privilege.List{privilege.SELECT, privilege.UPDATE}, 382 }, 383 true, 384 userPrivileges{ 385 security.RootUser: systemPrivs, 386 AdminRole: systemPrivs, 387 "foo": privilege.List{}, 388 "bar": privilege.List{privilege.SELECT}, 389 }, 390 }, 391 { 392 // Empty privileges for non-system ID. 393 userID, 394 userPrivileges{}, 395 true, 396 userPrivileges{ 397 security.RootUser: userPrivs, 398 AdminRole: userPrivs, 399 }, 400 }, 401 { 402 // Valid requirements for non-system ID. 403 userID, 404 userPrivileges{ 405 security.RootUser: userPrivs, 406 AdminRole: userPrivs, 407 "foo": privilege.List{privilege.SELECT}, 408 "bar": privilege.List{privilege.GRANT}, 409 "baz": privilege.List{privilege.SELECT, privilege.GRANT}, 410 }, 411 false, 412 userPrivileges{ 413 security.RootUser: userPrivs, 414 AdminRole: userPrivs, 415 "foo": privilege.List{privilege.SELECT}, 416 "bar": privilege.List{privilege.GRANT}, 417 "baz": privilege.List{privilege.SELECT, privilege.GRANT}, 418 }, 419 }, 420 { 421 // All privileges are allowed for non-system ID, but we need super users. 422 userID, 423 userPrivileges{ 424 "foo": privilege.List{privilege.ALL}, 425 "bar": privilege.List{privilege.UPDATE}, 426 }, 427 true, 428 userPrivileges{ 429 security.RootUser: privilege.List{privilege.ALL}, 430 AdminRole: privilege.List{privilege.ALL}, 431 "foo": privilege.List{privilege.ALL}, 432 "bar": privilege.List{privilege.UPDATE}, 433 }, 434 }, 435 } 436 437 for num, testCase := range testCases { 438 desc := &PrivilegeDescriptor{} 439 for u, p := range testCase.input { 440 desc.Grant(u, p) 441 } 442 443 if a, e := desc.MaybeFixPrivileges(testCase.id), testCase.modified; a != e { 444 t.Errorf("#%d: expected modified=%t, got modified=%t", num, e, a) 445 continue 446 } 447 448 if a, e := len(desc.Users), len(testCase.output); a != e { 449 t.Errorf("#%d: expected %d users (%v), got %d (%v)", num, e, testCase.output, a, desc.Users) 450 continue 451 } 452 453 for u, p := range testCase.output { 454 outputUser, ok := desc.findUser(u) 455 if !ok { 456 t.Fatalf("#%d: expected user %s in output, but not found (%v)", num, u, desc.Users) 457 } 458 if a, e := privilege.ListFromBitField(outputUser.Privileges), p; a.ToBitField() != e.ToBitField() { 459 t.Errorf("#%d: user %s: expected privileges %v, got %v", num, u, e, a) 460 } 461 } 462 } 463 }