@@ -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
6564func (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
8795func (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
108116func (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+
115191func (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