mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #5613 from xiang90/rootrole
*: add admin permission checking
This commit is contained in:
commit
6e32e8501a
@ -111,6 +111,9 @@ type AuthStore interface {
|
||||
|
||||
// IsRangePermitted checks range permission of the user
|
||||
IsRangePermitted(header *pb.RequestHeader, key, rangeEnd string) bool
|
||||
|
||||
// IsAdminPermitted checks admin permission of the user
|
||||
IsAdminPermitted(username string) bool
|
||||
}
|
||||
|
||||
type authStore struct {
|
||||
@ -137,14 +140,7 @@ func (as *authStore) AuthEnable() error {
|
||||
return ErrRootUserNotExist
|
||||
}
|
||||
|
||||
rootRoleExist := false
|
||||
for _, r := range u.Roles {
|
||||
if r == rootRole {
|
||||
rootRoleExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !rootRoleExist {
|
||||
if !hasRootRole(u) {
|
||||
return ErrRootRoleNotExist
|
||||
}
|
||||
|
||||
@ -664,6 +660,23 @@ func (as *authStore) IsRangePermitted(header *pb.RequestHeader, key, rangeEnd st
|
||||
return as.isOpPermitted(header.Username, key, rangeEnd, false, true)
|
||||
}
|
||||
|
||||
func (as *authStore) IsAdminPermitted(username string) bool {
|
||||
if !as.isAuthEnabled() {
|
||||
return true
|
||||
}
|
||||
|
||||
tx := as.be.BatchTx()
|
||||
tx.Lock()
|
||||
defer tx.Unlock()
|
||||
|
||||
u := getUser(tx, username)
|
||||
if u == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return hasRootRole(u)
|
||||
}
|
||||
|
||||
func getUser(tx backend.BatchTx, username string) *authpb.User {
|
||||
_, vs := tx.UnsafeRange(authUsersBucketName, []byte(username), nil, 0)
|
||||
if len(vs) == 0 {
|
||||
@ -699,3 +712,12 @@ func NewAuthStore(be backend.Backend) *authStore {
|
||||
be: be,
|
||||
}
|
||||
}
|
||||
|
||||
func hasRootRole(u *authpb.User) bool {
|
||||
for _, r := range u.Roles {
|
||||
if r == rootRole {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -79,6 +79,13 @@ type applierV3backend struct {
|
||||
|
||||
func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) *applyResult {
|
||||
ar := &applyResult{}
|
||||
username := r.Header.Username
|
||||
|
||||
if needAdminPermission(r) && !s.AuthStore().IsAdminPermitted(username) {
|
||||
ar.err = auth.ErrPermissionDenied
|
||||
return ar
|
||||
}
|
||||
|
||||
switch {
|
||||
case r.Range != nil:
|
||||
if s.AuthStore().IsRangePermitted(r.Header, string(r.Range.Key), string(r.Range.RangeEnd)) {
|
||||
@ -104,6 +111,7 @@ func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) *applyResult {
|
||||
ar.resp, ar.err = s.applyV3.LeaseRevoke(r.LeaseRevoke)
|
||||
case r.Alarm != nil:
|
||||
ar.resp, ar.err = s.applyV3.Alarm(r.Alarm)
|
||||
|
||||
case r.AuthEnable != nil:
|
||||
ar.resp, ar.err = s.applyV3.AuthEnable()
|
||||
case r.AuthDisable != nil:
|
||||
@ -710,3 +718,36 @@ func compareInt64(a, b int64) int {
|
||||
func isGteRange(rangeEnd []byte) bool {
|
||||
return len(rangeEnd) == 1 && rangeEnd[0] == 0
|
||||
}
|
||||
|
||||
func needAdminPermission(r *pb.InternalRaftRequest) bool {
|
||||
switch {
|
||||
case r.AuthEnable != nil:
|
||||
return true
|
||||
case r.AuthDisable != nil:
|
||||
return true
|
||||
case r.AuthUserAdd != nil:
|
||||
return true
|
||||
case r.AuthUserDelete != nil:
|
||||
return true
|
||||
case r.AuthUserChangePassword != nil:
|
||||
return true
|
||||
case r.AuthUserGrantRole != nil:
|
||||
return true
|
||||
case r.AuthUserGet != nil:
|
||||
return true
|
||||
case r.AuthUserRevokeRole != nil:
|
||||
return true
|
||||
case r.AuthRoleAdd != nil:
|
||||
return true
|
||||
case r.AuthRoleGrantPermission != nil:
|
||||
return true
|
||||
case r.AuthRoleGet != nil:
|
||||
return true
|
||||
case r.AuthRoleRevokePermission != nil:
|
||||
return true
|
||||
case r.AuthRoleDelete != nil:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user