From 975854f07fba840a78f22bb80e99b2335ef5fc04 Mon Sep 17 00:00:00 2001 From: Hitoshi Mitake Date: Wed, 29 Mar 2023 20:46:32 +0900 Subject: [PATCH] etcdserver: protect lease timetilive with auth Signed-off-by: Hitoshi Mitake Co-authored-by: Benjamin Wang --- server/etcdserver/v3_server.go | 51 +++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/server/etcdserver/v3_server.go b/server/etcdserver/v3_server.go index 6fcc1b4a3..5b60f3215 100644 --- a/server/etcdserver/v3_server.go +++ b/server/etcdserver/v3_server.go @@ -317,7 +317,32 @@ func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, e return -1, errors.ErrCanceled } -func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) { +func (s *EtcdServer) checkLeaseTimeToLive(ctx context.Context, leaseID lease.LeaseID) (error, uint64) { + rev := s.AuthStore().Revision() + if !s.AuthStore().IsAuthEnabled() { + return nil, rev + } + authInfo, err := s.AuthInfoFromCtx(ctx) + if err != nil { + return err, rev + } + if authInfo == nil { + return auth.ErrUserEmpty, rev + } + + l := s.lessor.Lookup(leaseID) + if l != nil { + for _, key := range l.Keys() { + if err := s.AuthStore().IsRangePermitted(authInfo, []byte(key), []byte{}); err != nil { + return err, 0 + } + } + } + + return nil, rev +} + +func (s *EtcdServer) leaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) { if s.isLeader() { if err := s.waitAppliedIndex(); err != nil { return nil, err @@ -367,6 +392,30 @@ func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveR return nil, errors.ErrCanceled } +func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) { + var rev uint64 + var err error + if r.Keys { + // check RBAC permission only if Keys is true + err, rev = s.checkLeaseTimeToLive(ctx, lease.LeaseID(r.ID)) + if err != nil { + return nil, err + } + } + + resp, err := s.leaseTimeToLive(ctx, r) + if err != nil { + return nil, err + } + + if r.Keys { + if s.AuthStore().IsAuthEnabled() && rev != s.AuthStore().Revision() { + return nil, auth.ErrAuthOldRevision + } + } + return resp, nil +} + func (s *EtcdServer) newHeader() *pb.ResponseHeader { return &pb.ResponseHeader{ ClusterId: uint64(s.cluster.ID()),