1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package etcdserver
16
17 import (
18 "context"
19 "sync"
20
21 pb "go.etcd.io/etcd/api/v3/etcdserverpb"
22 "go.etcd.io/etcd/pkg/v3/traceutil"
23 "go.etcd.io/etcd/server/v3/auth"
24 "go.etcd.io/etcd/server/v3/etcdserver/api/membership"
25 "go.etcd.io/etcd/server/v3/lease"
26 "go.etcd.io/etcd/server/v3/mvcc"
27 )
28
29 type authApplierV3 struct {
30 applierV3
31 as auth.AuthStore
32 lessor lease.Lessor
33
34
35
36 mu sync.Mutex
37
38 authInfo auth.AuthInfo
39 }
40
41 func newAuthApplierV3(as auth.AuthStore, base applierV3, lessor lease.Lessor) *authApplierV3 {
42 return &authApplierV3{applierV3: base, as: as, lessor: lessor}
43 }
44
45 func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest, shouldApplyV3 membership.ShouldApplyV3) *applyResult {
46 aa.mu.Lock()
47 defer aa.mu.Unlock()
48 if r.Header != nil {
49
50
51 aa.authInfo.Username = r.Header.Username
52 aa.authInfo.Revision = r.Header.AuthRevision
53 }
54 if needAdminPermission(r) {
55 if err := aa.as.IsAdminPermitted(&aa.authInfo); err != nil {
56 aa.authInfo.Username = ""
57 aa.authInfo.Revision = 0
58 return &applyResult{err: err}
59 }
60 }
61 ret := aa.applierV3.Apply(r, shouldApplyV3)
62 aa.authInfo.Username = ""
63 aa.authInfo.Revision = 0
64 return ret
65 }
66
67 func (aa *authApplierV3) Put(ctx context.Context, txn mvcc.TxnWrite, r *pb.PutRequest) (*pb.PutResponse, *traceutil.Trace, error) {
68 if err := aa.as.IsPutPermitted(&aa.authInfo, r.Key); err != nil {
69 return nil, nil, err
70 }
71
72 if err := aa.checkLeasePuts(lease.LeaseID(r.Lease)); err != nil {
73
74
75
76
77 return nil, nil, err
78 }
79
80 if r.PrevKv {
81 err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, nil)
82 if err != nil {
83 return nil, nil, err
84 }
85 }
86 return aa.applierV3.Put(ctx, txn, r)
87 }
88
89 func (aa *authApplierV3) Range(ctx context.Context, txn mvcc.TxnRead, r *pb.RangeRequest) (*pb.RangeResponse, error) {
90 if err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
91 return nil, err
92 }
93 return aa.applierV3.Range(ctx, txn, r)
94 }
95
96 func (aa *authApplierV3) DeleteRange(txn mvcc.TxnWrite, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
97 if err := aa.as.IsDeleteRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
98 return nil, err
99 }
100 if r.PrevKv {
101 err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd)
102 if err != nil {
103 return nil, err
104 }
105 }
106
107 return aa.applierV3.DeleteRange(txn, r)
108 }
109
110 func checkTxnReqsPermission(as auth.AuthStore, ai *auth.AuthInfo, reqs []*pb.RequestOp) error {
111 for _, requ := range reqs {
112 switch tv := requ.Request.(type) {
113 case *pb.RequestOp_RequestRange:
114 if tv.RequestRange == nil {
115 continue
116 }
117
118 if err := as.IsRangePermitted(ai, tv.RequestRange.Key, tv.RequestRange.RangeEnd); err != nil {
119 return err
120 }
121
122 case *pb.RequestOp_RequestPut:
123 if tv.RequestPut == nil {
124 continue
125 }
126
127 if err := as.IsPutPermitted(ai, tv.RequestPut.Key); err != nil {
128 return err
129 }
130
131 case *pb.RequestOp_RequestDeleteRange:
132 if tv.RequestDeleteRange == nil {
133 continue
134 }
135
136 if tv.RequestDeleteRange.PrevKv {
137 err := as.IsRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
138 if err != nil {
139 return err
140 }
141 }
142
143 err := as.IsDeleteRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
144 if err != nil {
145 return err
146 }
147 }
148 }
149
150 return nil
151 }
152
153 func checkTxnAuth(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnRequest) error {
154 for _, c := range rt.Compare {
155 if err := as.IsRangePermitted(ai, c.Key, c.RangeEnd); err != nil {
156 return err
157 }
158 }
159 if err := checkTxnReqsPermission(as, ai, rt.Success); err != nil {
160 return err
161 }
162 return checkTxnReqsPermission(as, ai, rt.Failure)
163 }
164
165 func (aa *authApplierV3) Txn(ctx context.Context, rt *pb.TxnRequest) (*pb.TxnResponse, *traceutil.Trace, error) {
166 if err := checkTxnAuth(aa.as, &aa.authInfo, rt); err != nil {
167 return nil, nil, err
168 }
169 return aa.applierV3.Txn(ctx, rt)
170 }
171
172 func (aa *authApplierV3) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
173 if err := aa.checkLeasePuts(lease.LeaseID(lc.ID)); err != nil {
174 return nil, err
175 }
176 return aa.applierV3.LeaseRevoke(lc)
177 }
178
179 func (aa *authApplierV3) checkLeasePuts(leaseID lease.LeaseID) error {
180 l := aa.lessor.Lookup(leaseID)
181 if l != nil {
182 return aa.checkLeasePutsKeys(l)
183 }
184
185 return nil
186 }
187
188 func (aa *authApplierV3) checkLeasePutsKeys(l *lease.Lease) error {
189
190
191 if err := aa.as.IsAdminPermitted(&aa.authInfo); err == nil {
192 return nil
193 }
194
195 for _, key := range l.Keys() {
196 if err := aa.as.IsPutPermitted(&aa.authInfo, []byte(key)); err != nil {
197 return err
198 }
199 }
200 return nil
201 }
202
203 func (aa *authApplierV3) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
204 err := aa.as.IsAdminPermitted(&aa.authInfo)
205 if err != nil && r.Name != aa.authInfo.Username {
206 aa.authInfo.Username = ""
207 aa.authInfo.Revision = 0
208 return &pb.AuthUserGetResponse{}, err
209 }
210
211 return aa.applierV3.UserGet(r)
212 }
213
214 func (aa *authApplierV3) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
215 err := aa.as.IsAdminPermitted(&aa.authInfo)
216 if err != nil && !aa.as.HasRole(aa.authInfo.Username, r.Role) {
217 aa.authInfo.Username = ""
218 aa.authInfo.Revision = 0
219 return &pb.AuthRoleGetResponse{}, err
220 }
221
222 return aa.applierV3.RoleGet(r)
223 }
224
225 func needAdminPermission(r *pb.InternalRaftRequest) bool {
226 switch {
227 case r.AuthEnable != nil:
228 return true
229 case r.AuthDisable != nil:
230 return true
231 case r.AuthStatus != nil:
232 return true
233 case r.AuthUserAdd != nil:
234 return true
235 case r.AuthUserDelete != nil:
236 return true
237 case r.AuthUserChangePassword != nil:
238 return true
239 case r.AuthUserGrantRole != nil:
240 return true
241 case r.AuthUserRevokeRole != nil:
242 return true
243 case r.AuthRoleAdd != nil:
244 return true
245 case r.AuthRoleGrantPermission != nil:
246 return true
247 case r.AuthRoleRevokePermission != nil:
248 return true
249 case r.AuthRoleDelete != nil:
250 return true
251 case r.AuthUserList != nil:
252 return true
253 case r.AuthRoleList != nil:
254 return true
255 default:
256 return false
257 }
258 }
259
View as plain text