apply_auth.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2016 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package etcdserver
  15. import (
  16. "sync"
  17. "github.com/coreos/etcd/auth"
  18. pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
  19. )
  20. type authApplierV3 struct {
  21. applierV3
  22. as auth.AuthStore
  23. // mu serializes Apply so that user isn't corrupted and so that
  24. // serialized requests don't leak data from TOCTOU errors
  25. mu sync.Mutex
  26. authInfo auth.AuthInfo
  27. }
  28. func newAuthApplierV3(as auth.AuthStore, base applierV3) *authApplierV3 {
  29. return &authApplierV3{applierV3: base, as: as}
  30. }
  31. func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest) *applyResult {
  32. aa.mu.Lock()
  33. defer aa.mu.Unlock()
  34. if r.Header != nil {
  35. // backward-compatible with pre-3.0 releases when internalRaftRequest
  36. // does not have header field
  37. aa.authInfo.Username = r.Header.Username
  38. aa.authInfo.Revision = r.Header.AuthRevision
  39. }
  40. if needAdminPermission(r) {
  41. if err := aa.as.IsAdminPermitted(&aa.authInfo); err != nil {
  42. aa.authInfo.Username = ""
  43. aa.authInfo.Revision = 0
  44. return &applyResult{err: err}
  45. }
  46. }
  47. ret := aa.applierV3.Apply(r)
  48. aa.authInfo.Username = ""
  49. aa.authInfo.Revision = 0
  50. return ret
  51. }
  52. func (aa *authApplierV3) Put(txnID int64, r *pb.PutRequest) (*pb.PutResponse, error) {
  53. if err := aa.as.IsPutPermitted(&aa.authInfo, r.Key); err != nil {
  54. return nil, err
  55. }
  56. if r.PrevKv {
  57. err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, nil)
  58. if err != nil {
  59. return nil, err
  60. }
  61. }
  62. return aa.applierV3.Put(txnID, r)
  63. }
  64. func (aa *authApplierV3) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResponse, error) {
  65. if err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
  66. return nil, err
  67. }
  68. return aa.applierV3.Range(txnID, r)
  69. }
  70. func (aa *authApplierV3) DeleteRange(txnID int64, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
  71. if err := aa.as.IsDeleteRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
  72. return nil, err
  73. }
  74. if r.PrevKv {
  75. err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd)
  76. if err != nil {
  77. return nil, err
  78. }
  79. }
  80. return aa.applierV3.DeleteRange(txnID, r)
  81. }
  82. func checkTxnReqsPermission(as auth.AuthStore, ai *auth.AuthInfo, reqs []*pb.RequestOp) error {
  83. for _, requ := range reqs {
  84. switch tv := requ.Request.(type) {
  85. case *pb.RequestOp_RequestRange:
  86. if tv.RequestRange == nil {
  87. continue
  88. }
  89. if err := as.IsRangePermitted(ai, tv.RequestRange.Key, tv.RequestRange.RangeEnd); err != nil {
  90. return err
  91. }
  92. case *pb.RequestOp_RequestPut:
  93. if tv.RequestPut == nil {
  94. continue
  95. }
  96. if err := as.IsPutPermitted(ai, tv.RequestPut.Key); err != nil {
  97. return err
  98. }
  99. case *pb.RequestOp_RequestDeleteRange:
  100. if tv.RequestDeleteRange == nil {
  101. continue
  102. }
  103. if tv.RequestDeleteRange.PrevKv {
  104. err := as.IsRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
  105. if err != nil {
  106. return err
  107. }
  108. }
  109. err := as.IsDeleteRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
  110. if err != nil {
  111. return err
  112. }
  113. }
  114. }
  115. return nil
  116. }
  117. func checkTxnAuth(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnRequest) error {
  118. for _, c := range rt.Compare {
  119. if err := as.IsRangePermitted(ai, c.Key, nil); err != nil {
  120. return err
  121. }
  122. }
  123. if err := checkTxnReqsPermission(as, ai, rt.Success); err != nil {
  124. return err
  125. }
  126. if err := checkTxnReqsPermission(as, ai, rt.Failure); err != nil {
  127. return err
  128. }
  129. return nil
  130. }
  131. func (aa *authApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
  132. if err := checkTxnAuth(aa.as, &aa.authInfo, rt); err != nil {
  133. return nil, err
  134. }
  135. return aa.applierV3.Txn(rt)
  136. }
  137. func needAdminPermission(r *pb.InternalRaftRequest) bool {
  138. switch {
  139. case r.AuthEnable != nil:
  140. return true
  141. case r.AuthDisable != nil:
  142. return true
  143. case r.AuthUserAdd != nil:
  144. return true
  145. case r.AuthUserDelete != nil:
  146. return true
  147. case r.AuthUserChangePassword != nil:
  148. return true
  149. case r.AuthUserGrantRole != nil:
  150. return true
  151. case r.AuthUserGet != nil:
  152. return true
  153. case r.AuthUserRevokeRole != nil:
  154. return true
  155. case r.AuthRoleAdd != nil:
  156. return true
  157. case r.AuthRoleGrantPermission != nil:
  158. return true
  159. case r.AuthRoleGet != nil:
  160. return true
  161. case r.AuthRoleRevokePermission != nil:
  162. return true
  163. case r.AuthRoleDelete != nil:
  164. return true
  165. case r.AuthUserList != nil:
  166. return true
  167. case r.AuthRoleList != nil:
  168. return true
  169. default:
  170. return false
  171. }
  172. }