diff --git a/auth/store.go b/auth/store.go index 84c34afde..1db89c03f 100644 --- a/auth/store.go +++ b/auth/store.go @@ -666,6 +666,11 @@ func (as *authStore) isOpPermitted(userName string, revision uint64, key, rangeE return ErrPermissionDenied } + // root role should have permission on all ranges + if hasRootRole(user) { + return nil + } + if as.isRangeOpPermitted(tx, userName, key, rangeEnd, permTyp) { return nil } diff --git a/clientv3/example_auth_test.go b/clientv3/example_auth_test.go index bd3a01676..f07e5095c 100644 --- a/clientv3/example_auth_test.go +++ b/clientv3/example_auth_test.go @@ -35,22 +35,32 @@ func ExampleAuth() { if _, err = cli.RoleAdd(context.TODO(), "root"); err != nil { log.Fatal(err) } - - if _, err = cli.RoleGrantPermission( - context.TODO(), - "root", // role name - "foo", // key - "zoo", // range end - clientv3.PermissionType(clientv3.PermReadWrite), - ); err != nil { - log.Fatal(err) - } 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) } + + if _, err = cli.RoleAdd(context.TODO(), "r"); err != nil { + log.Fatal(err) + } + + if _, err = cli.RoleGrantPermission( + context.TODO(), + "r", // role name + "foo", // key + "zoo", // range end + clientv3.PermissionType(clientv3.PermReadWrite), + ); err != nil { + log.Fatal(err) + } + if _, err = cli.UserAdd(context.TODO(), "u", "123"); err != nil { + log.Fatal(err) + } + if _, err = cli.UserGrantRole(context.TODO(), "u", "r"); err != nil { + log.Fatal(err) + } if _, err = cli.AuthEnable(context.TODO()); err != nil { log.Fatal(err) } @@ -58,7 +68,7 @@ func ExampleAuth() { cliAuth, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, - Username: "root", + Username: "u", Password: "123", }) if err != nil { @@ -77,16 +87,27 @@ func ExampleAuth() { Commit() fmt.Println(err) - // now check the permission - resp, err := cliAuth.RoleGet(context.TODO(), "root") + // now check the permission with the root account + rootCli, err := clientv3.New(clientv3.Config{ + Endpoints: endpoints, + DialTimeout: dialTimeout, + Username: "root", + Password: "123", + }) if err != nil { log.Fatal(err) } - fmt.Printf("root user permission: key %q, range end %q\n", resp.Perm[0].Key, resp.Perm[0].RangeEnd) + defer rootCli.Close() - if _, err = cliAuth.AuthDisable(context.TODO()); err != nil { + resp, err := rootCli.RoleGet(context.TODO(), "r") + if err != nil { + log.Fatal(err) + } + fmt.Printf("user u permission: key %q, range end %q\n", resp.Perm[0].Key, resp.Perm[0].RangeEnd) + + if _, err = rootCli.AuthDisable(context.TODO()); err != nil { log.Fatal(err) } // Output: etcdserver: permission denied - // root user permission: key "foo", range end "zoo" + // user u permission: key "foo", range end "zoo" } diff --git a/e2e/ctl_v3_auth_test.go b/e2e/ctl_v3_auth_test.go index 13f318c52..8acc9f3f0 100644 --- a/e2e/ctl_v3_auth_test.go +++ b/e2e/ctl_v3_auth_test.go @@ -111,11 +111,11 @@ func authCredWriteKeyTest(cx ctlCtx) { cx.user, cx.pass = "root", "root" authSetupTestUser(cx) - // confirm root role doesn't grant access to all keys - if err := ctlV3PutFailPerm(cx, "foo", "bar"); err != nil { + // confirm root role can access to all keys + if err := ctlV3Put(cx, "foo", "bar", ""); err != nil { 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) } @@ -126,17 +126,17 @@ func authCredWriteKeyTest(cx ctlCtx) { } // confirm put failed 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) } // try good user 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) } // 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) } @@ -147,7 +147,7 @@ func authCredWriteKeyTest(cx ctlCtx) { } // confirm put failed 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) } }