auth, e2e, clientv3: the root role should be granted access to every key

This commit changes the semantics of the root role. The role should be
able to access to every key.

Partially fixes https://github.com/coreos/etcd/issues/6355
This commit is contained in:
Hitoshi Mitake
2016-09-06 11:32:25 +09:00
committed by Gyu-Ho Lee
parent fcbada7798
commit ca91f898a2
3 changed files with 58 additions and 39 deletions

View File

@ -603,6 +603,11 @@ func (as *authStore) isOpPermitted(userName string, key, rangeEnd []byte, permTy
return false return false
} }
// root role should have permission on all ranges
if hasRootRole(user) {
return nil
}
if as.isRangeOpPermitted(tx, userName, key, rangeEnd, permTyp) { if as.isRangeOpPermitted(tx, userName, key, rangeEnd, permTyp) {
return true return true
} }

View File

@ -32,35 +32,63 @@ func ExampleAuth() {
} }
defer cli.Close() defer cli.Close()
authapi := clientv3.NewAuth(cli) if _, err = cli.RoleAdd(context.TODO(), "root"); err != nil {
log.Fatal(err)
if _, err = authapi.RoleAdd(context.TODO(), "root"); err != nil { }
if _, err = cli.UserAdd(context.TODO(), "root", "123"); err != nil {
log.Fatal(err)
}
if _, err = cli.UserGrantRole(context.TODO(), "root", "root"); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if _, err = authapi.RoleGrantPermission( if _, err = cli.RoleAdd(context.TODO(), "r"); err != nil {
log.Fatal(err)
}
if _, err = cli.RoleGrantPermission(
context.TODO(), context.TODO(),
"root", // role name "r", // role name
"foo", // key "foo", // key
"zoo", // range end "zoo", // range end
clientv3.PermissionType(clientv3.PermReadWrite), clientv3.PermissionType(clientv3.PermReadWrite),
); err != nil { ); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if _, err = cli.UserAdd(context.TODO(), "u", "123"); err != nil {
if _, err = authapi.UserAdd(context.TODO(), "root", "123"); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if _, err = cli.UserGrantRole(context.TODO(), "u", "r"); err != nil {
if _, err = authapi.UserGrantRole(context.TODO(), "root", "root"); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if _, err = cli.AuthEnable(context.TODO()); err != nil {
if _, err = authapi.AuthEnable(context.TODO()); err != nil {
log.Fatal(err) log.Fatal(err)
} }
cliAuth, err := clientv3.New(clientv3.Config{ cliAuth, err := clientv3.New(clientv3.Config{
Endpoints: endpoints,
DialTimeout: dialTimeout,
Username: "u",
Password: "123",
})
if err != nil {
log.Fatal(err)
}
defer cliAuth.Close()
if _, err = cliAuth.Put(context.TODO(), "foo1", "bar"); err != nil {
log.Fatal(err)
}
_, err = cliAuth.Txn(context.TODO()).
If(clientv3.Compare(clientv3.Value("zoo1"), ">", "abc")).
Then(clientv3.OpPut("zoo1", "XYZ")).
Else(clientv3.OpPut("zoo1", "ABC")).
Commit()
fmt.Println(err)
// now check the permission with the root account
rootCli, err := clientv3.New(clientv3.Config{
Endpoints: endpoints, Endpoints: endpoints,
DialTimeout: dialTimeout, DialTimeout: dialTimeout,
Username: "root", Username: "root",
@ -69,31 +97,17 @@ func ExampleAuth() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer cliAuth.Close() defer rootCli.Close()
kv := clientv3.NewKV(cliAuth) resp, err := rootCli.RoleGet(context.TODO(), "r")
if _, err = kv.Put(context.TODO(), "foo1", "bar"); err != nil {
log.Fatal(err)
}
_, err = kv.Txn(context.TODO()).
If(clientv3.Compare(clientv3.Value("zoo1"), ">", "abc")).
Then(clientv3.OpPut("zoo1", "XYZ")).
Else(clientv3.OpPut("zoo1", "ABC")).
Commit()
fmt.Println(err)
// now check the permission
authapi2 := clientv3.NewAuth(cliAuth)
resp, err := authapi2.RoleGet(context.TODO(), "root")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Printf("root user permission: key %q, range end %q\n", resp.Perm[0].Key, resp.Perm[0].RangeEnd) fmt.Printf("user u permission: key %q, range end %q\n", resp.Perm[0].Key, resp.Perm[0].RangeEnd)
if _, err = authapi2.AuthDisable(context.TODO()); err != nil { if _, err = rootCli.AuthDisable(context.TODO()); err != nil {
log.Fatal(err) log.Fatal(err)
} }
// Output: etcdserver: permission denied // Output: etcdserver: permission denied
// root user permission: key "foo", range end "zoo" // user u permission: key "foo", range end "zoo"
} }

View File

@ -75,11 +75,11 @@ func authCredWriteKeyTest(cx ctlCtx) {
cx.user, cx.pass = "root", "root" cx.user, cx.pass = "root", "root"
authSetupTestUser(cx) authSetupTestUser(cx)
// confirm root role doesn't grant access to all keys // confirm root role can access to all keys
if err := ctlV3PutFailPerm(cx, "foo", "bar"); err != nil { if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
cx.t.Fatal(err) cx.t.Fatal(err)
} }
if err := ctlV3GetFailPerm(cx, "foo"); err != nil { if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
cx.t.Fatal(err) cx.t.Fatal(err)
} }
@ -90,17 +90,17 @@ func authCredWriteKeyTest(cx ctlCtx) {
} }
// confirm put failed // confirm put failed
cx.user, cx.pass = "test-user", "pass" cx.user, cx.pass = "test-user", "pass"
if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "a"}}...); err != nil { if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
cx.t.Fatal(err) cx.t.Fatal(err)
} }
// try good user // try good user
cx.user, cx.pass = "test-user", "pass" cx.user, cx.pass = "test-user", "pass"
if err := ctlV3Put(cx, "foo", "bar", ""); err != nil { if err := ctlV3Put(cx, "foo", "bar2", ""); err != nil {
cx.t.Fatal(err) cx.t.Fatal(err)
} }
// confirm put succeeded // confirm put succeeded
if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil { if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar2"}}...); err != nil {
cx.t.Fatal(err) cx.t.Fatal(err)
} }
@ -111,7 +111,7 @@ func authCredWriteKeyTest(cx ctlCtx) {
} }
// confirm put failed // confirm put failed
cx.user, cx.pass = "test-user", "pass" cx.user, cx.pass = "test-user", "pass"
if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil { if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar2"}}...); err != nil {
cx.t.Fatal(err) cx.t.Fatal(err)
} }
} }