etcdserver: don't attempt to grant nil permission to a role
Prevent etcd from crashing when given a bad grant payload, e.g.: $ curl -d '{"name": "foo"}' http://localhost:2379/v3/auth/role/add {"header":{"cluster_id":"14841639068965178418", ... $ curl -d '{"name": "foo"}' http://localhost:2379/v3/auth/role/grant curl: (52) Empty reply from server
This commit is contained in:
@ -58,6 +58,7 @@ var (
|
|||||||
ErrGRPCRoleNotFound = status.New(codes.FailedPrecondition, "etcdserver: role name not found").Err()
|
ErrGRPCRoleNotFound = status.New(codes.FailedPrecondition, "etcdserver: role name not found").Err()
|
||||||
ErrGRPCRoleEmpty = status.New(codes.InvalidArgument, "etcdserver: role name is empty").Err()
|
ErrGRPCRoleEmpty = status.New(codes.InvalidArgument, "etcdserver: role name is empty").Err()
|
||||||
ErrGRPCAuthFailed = status.New(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password").Err()
|
ErrGRPCAuthFailed = status.New(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password").Err()
|
||||||
|
ErrGRPCPermissionNotGiven = status.New(codes.InvalidArgument, "etcdserver: permission not given").Err()
|
||||||
ErrGRPCPermissionDenied = status.New(codes.PermissionDenied, "etcdserver: permission denied").Err()
|
ErrGRPCPermissionDenied = status.New(codes.PermissionDenied, "etcdserver: permission denied").Err()
|
||||||
ErrGRPCRoleNotGranted = status.New(codes.FailedPrecondition, "etcdserver: role is not granted to the user").Err()
|
ErrGRPCRoleNotGranted = status.New(codes.FailedPrecondition, "etcdserver: role is not granted to the user").Err()
|
||||||
ErrGRPCPermissionNotGranted = status.New(codes.FailedPrecondition, "etcdserver: permission is not granted to the role").Err()
|
ErrGRPCPermissionNotGranted = status.New(codes.FailedPrecondition, "etcdserver: permission is not granted to the role").Err()
|
||||||
|
@ -56,6 +56,7 @@ var (
|
|||||||
ErrRoleAlreadyExist = errors.New("auth: role already exists")
|
ErrRoleAlreadyExist = errors.New("auth: role already exists")
|
||||||
ErrRoleNotFound = errors.New("auth: role not found")
|
ErrRoleNotFound = errors.New("auth: role not found")
|
||||||
ErrRoleEmpty = errors.New("auth: role name is empty")
|
ErrRoleEmpty = errors.New("auth: role name is empty")
|
||||||
|
ErrPermissionNotGiven = errors.New("auth: permission not given")
|
||||||
ErrAuthFailed = errors.New("auth: authentication failed, invalid user ID or password")
|
ErrAuthFailed = errors.New("auth: authentication failed, invalid user ID or password")
|
||||||
ErrNoPasswordUser = errors.New("auth: authentication failed, password was given for no password user")
|
ErrNoPasswordUser = errors.New("auth: authentication failed, password was given for no password user")
|
||||||
ErrPermissionDenied = errors.New("auth: permission denied")
|
ErrPermissionDenied = errors.New("auth: permission denied")
|
||||||
@ -786,6 +787,10 @@ func (perms permSlice) Swap(i, j int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
|
func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
|
||||||
|
if r.Perm == nil {
|
||||||
|
return nil, ErrPermissionNotGiven
|
||||||
|
}
|
||||||
|
|
||||||
tx := as.be.BatchTx()
|
tx := as.be.BatchTx()
|
||||||
tx.Lock()
|
tx.Lock()
|
||||||
defer tx.Unlock()
|
defer tx.Unlock()
|
||||||
|
@ -445,6 +445,22 @@ func TestRoleGrantPermission(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, perm, r.Perm[0])
|
assert.Equal(t, perm, r.Perm[0])
|
||||||
|
|
||||||
|
// trying to grant nil permissions returns an error (and doesn't change the actual permissions!)
|
||||||
|
_, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
|
||||||
|
Name: "role-test-1",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != ErrPermissionNotGiven {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err = as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, perm, r.Perm[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRootRoleGrantPermission(t *testing.T) {
|
func TestRootRoleGrantPermission(t *testing.T) {
|
||||||
|
@ -77,6 +77,7 @@ var toGRPCErrorMap = map[error]error{
|
|||||||
auth.ErrRoleNotFound: rpctypes.ErrGRPCRoleNotFound,
|
auth.ErrRoleNotFound: rpctypes.ErrGRPCRoleNotFound,
|
||||||
auth.ErrRoleEmpty: rpctypes.ErrGRPCRoleEmpty,
|
auth.ErrRoleEmpty: rpctypes.ErrGRPCRoleEmpty,
|
||||||
auth.ErrAuthFailed: rpctypes.ErrGRPCAuthFailed,
|
auth.ErrAuthFailed: rpctypes.ErrGRPCAuthFailed,
|
||||||
|
auth.ErrPermissionNotGiven: rpctypes.ErrGRPCPermissionNotGiven,
|
||||||
auth.ErrPermissionDenied: rpctypes.ErrGRPCPermissionDenied,
|
auth.ErrPermissionDenied: rpctypes.ErrGRPCPermissionDenied,
|
||||||
auth.ErrRoleNotGranted: rpctypes.ErrGRPCRoleNotGranted,
|
auth.ErrRoleNotGranted: rpctypes.ErrGRPCRoleNotGranted,
|
||||||
auth.ErrPermissionNotGranted: rpctypes.ErrGRPCPermissionNotGranted,
|
auth.ErrPermissionNotGranted: rpctypes.ErrGRPCPermissionNotGranted,
|
||||||
|
Reference in New Issue
Block a user