Skip to content

Commit 16a8a36

Browse files
authored
Merge pull request #21681 from ahrtr/20260428_auth_refactor
[release-3.6] Refactor auth check for Put requests in TXN
2 parents 7d4b175 + c387fa5 commit 16a8a36

5 files changed

Lines changed: 464 additions & 461 deletions

File tree

server/etcdserver/apply/apply_auth.go

Lines changed: 91 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
2121
"go.etcd.io/etcd/pkg/v3/traceutil"
2222
"go.etcd.io/etcd/server/v3/auth"
23-
"go.etcd.io/etcd/server/v3/etcdserver/txn"
2423
"go.etcd.io/etcd/server/v3/lease"
2524
)
2625

@@ -63,25 +62,34 @@ func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest, applyFunc applyFunc) *
6362
}
6463

6564
func (aa *authApplierV3) Put(r *pb.PutRequest) (*pb.PutResponse, *traceutil.Trace, error) {
66-
if err := aa.as.IsPutPermitted(&aa.authInfo, r.Key); err != nil {
65+
if err := checkPutAuth(aa.as, &aa.authInfo, aa.lessor, r); err != nil {
6766
return nil, nil, err
6867
}
6968

70-
if err := aa.checkLeasePuts(lease.LeaseID(r.Lease)); err != nil {
69+
return aa.applierV3.Put(r)
70+
}
71+
72+
func checkPutAuth(as auth.AuthStore, ai *auth.AuthInfo, lessor lease.Lessor, r *pb.PutRequest) error {
73+
if err := as.IsPutPermitted(ai, r.Key); err != nil {
74+
return err
75+
}
76+
77+
if err := checkLeasePuts(as, ai, lessor, lease.LeaseID(r.Lease)); err != nil {
7178
// The specified lease is already attached with a key that cannot
7279
// be written by this user. It means the user cannot revoke the
7380
// lease so attaching the lease to the newly written key should
7481
// be forbidden.
75-
return nil, nil, err
82+
return err
7683
}
7784

7885
if r.PrevKv {
79-
err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, nil)
86+
err := as.IsRangePermitted(ai, r.Key, nil)
8087
if err != nil {
81-
return nil, nil, err
88+
return err
8289
}
8390
}
84-
return aa.applierV3.Put(r)
91+
92+
return nil
8593
}
8694

8795
func (aa *authApplierV3) Range(r *pb.RangeRequest) (*pb.RangeResponse, *traceutil.Trace, error) {
@@ -106,37 +114,105 @@ func (aa *authApplierV3) DeleteRange(r *pb.DeleteRangeRequest) (*pb.DeleteRangeR
106114
}
107115

108116
func (aa *authApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, *traceutil.Trace, error) {
109-
if err := txn.CheckTxnAuth(aa.as, &aa.authInfo, rt); err != nil {
117+
if err := CheckTxnAuth(aa.as, &aa.authInfo, rt); err != nil {
110118
return nil, nil, err
111119
}
112120
return aa.applierV3.Txn(rt)
113121
}
114122

123+
func CheckTxnAuth(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnRequest) error {
124+
return checkTxnPermission(as, ai, rt)
125+
}
126+
127+
func checkTxnPermission(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnRequest) error {
128+
for _, c := range rt.Compare {
129+
if err := as.IsRangePermitted(ai, c.Key, c.RangeEnd); err != nil {
130+
return err
131+
}
132+
}
133+
if err := checkTxnReqsPermission(as, ai, rt.Success); err != nil {
134+
return err
135+
}
136+
return checkTxnReqsPermission(as, ai, rt.Failure)
137+
}
138+
139+
func checkTxnReqsPermission(as auth.AuthStore, ai *auth.AuthInfo, reqs []*pb.RequestOp) error {
140+
for _, requ := range reqs {
141+
switch tv := requ.Request.(type) {
142+
case *pb.RequestOp_RequestRange:
143+
if tv.RequestRange == nil {
144+
continue
145+
}
146+
147+
if err := as.IsRangePermitted(ai, tv.RequestRange.Key, tv.RequestRange.RangeEnd); err != nil {
148+
return err
149+
}
150+
151+
case *pb.RequestOp_RequestPut:
152+
if tv.RequestPut == nil {
153+
continue
154+
}
155+
156+
if err := as.IsPutPermitted(ai, tv.RequestPut.Key); err != nil {
157+
return err
158+
}
159+
160+
case *pb.RequestOp_RequestDeleteRange:
161+
if tv.RequestDeleteRange == nil {
162+
continue
163+
}
164+
165+
if tv.RequestDeleteRange.PrevKv {
166+
err := as.IsRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
167+
if err != nil {
168+
return err
169+
}
170+
}
171+
172+
err := as.IsDeleteRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
173+
if err != nil {
174+
return err
175+
}
176+
case *pb.RequestOp_RequestTxn:
177+
if tv.RequestTxn == nil {
178+
continue
179+
}
180+
181+
err := checkTxnPermission(as, ai, tv.RequestTxn)
182+
if err != nil {
183+
return err
184+
}
185+
}
186+
}
187+
188+
return nil
189+
}
190+
115191
func (aa *authApplierV3) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
116-
if err := aa.checkLeasePuts(lease.LeaseID(lc.ID)); err != nil {
192+
if err := checkLeasePuts(aa.as, &aa.authInfo, aa.lessor, lease.LeaseID(lc.ID)); err != nil {
117193
return nil, err
118194
}
119195
return aa.applierV3.LeaseRevoke(lc)
120196
}
121197

122-
func (aa *authApplierV3) checkLeasePuts(leaseID lease.LeaseID) error {
123-
l := aa.lessor.Lookup(leaseID)
198+
func checkLeasePuts(as auth.AuthStore, ai *auth.AuthInfo, lessor lease.Lessor, leaseID lease.LeaseID) error {
199+
l := lessor.Lookup(leaseID)
124200
if l != nil {
125-
return aa.checkLeasePutsKeys(l)
201+
return checkLeasePutsKeys(as, ai, l)
126202
}
127203

128204
return nil
129205
}
130206

131-
func (aa *authApplierV3) checkLeasePutsKeys(l *lease.Lease) error {
207+
func checkLeasePutsKeys(as auth.AuthStore, ai *auth.AuthInfo, l *lease.Lease) error {
132208
// early return for most-common scenario of either disabled auth or admin user.
133209
// IsAdminPermitted also checks whether auth is enabled
134-
if err := aa.as.IsAdminPermitted(&aa.authInfo); err == nil {
210+
if err := as.IsAdminPermitted(ai); err == nil {
135211
return nil
136212
}
137213

138214
for _, key := range l.Keys() {
139-
if err := aa.as.IsPutPermitted(&aa.authInfo, []byte(key)); err != nil {
215+
if err := as.IsPutPermitted(ai, []byte(key)); err != nil {
140216
return err
141217
}
142218
}

0 commit comments

Comments
 (0)