mirror of
https://github.com/minio/minio.git
synced 2025-04-08 21:55:44 -04:00
fix: parentUser mapped policy for OIDC creds (#12293)
missing parentUser for OIDC STS creds can lead to fail to authenticate, this PR attempts to fix the parentUser policy map for distributed setups.
This commit is contained in:
parent
9cd9f5a0b3
commit
397391c89f
84
cmd/iam.go
84
cmd/iam.go
@ -401,6 +401,22 @@ func (sys *IAMSys) LoadUser(objAPI ObjectLayer, accessKey string, userType IAMUs
|
|||||||
if err != nil && err != errNoSuchPolicy {
|
if err != nil && err != errNoSuchPolicy {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// We are on purpose not persisting the policy map for parent
|
||||||
|
// user, although this is a hack, it is a good enough hack
|
||||||
|
// at this point in time - we need to overhaul our OIDC
|
||||||
|
// usage with service accounts with a more cleaner implementation
|
||||||
|
//
|
||||||
|
// This mapping is necessary to ensure that valid credentials
|
||||||
|
// have necessary ParentUser present - this is mainly for only
|
||||||
|
// webIdentity based STS tokens.
|
||||||
|
cred, ok := sys.iamUsersMap[accessKey]
|
||||||
|
if ok {
|
||||||
|
if cred.IsTemp() && cred.ParentUser != "" && cred.ParentUser != globalActiveCred.AccessKey {
|
||||||
|
if _, ok := sys.iamUserPolicyMap[cred.ParentUser]; !ok {
|
||||||
|
sys.iamUserPolicyMap[cred.ParentUser] = sys.iamUserPolicyMap[accessKey]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// When etcd is set, we use watch APIs so this code is not needed.
|
// When etcd is set, we use watch APIs so this code is not needed.
|
||||||
return nil
|
return nil
|
||||||
@ -872,8 +888,14 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa
|
|||||||
sys.store.lock()
|
sys.store.lock()
|
||||||
defer sys.store.unlock()
|
defer sys.store.unlock()
|
||||||
|
|
||||||
|
if err := sys.store.saveMappedPolicy(context.Background(), accessKey, stsUser, false, mp, options{ttl: ttl}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sys.iamUserPolicyMap[accessKey] = mp
|
||||||
|
|
||||||
// We are on purpose not persisting the policy map for parent
|
// We are on purpose not persisting the policy map for parent
|
||||||
// user, although this is a hack, it is a good enoug hack
|
// user, although this is a hack, it is a good enough hack
|
||||||
// at this point in time - we need to overhaul our OIDC
|
// at this point in time - we need to overhaul our OIDC
|
||||||
// usage with service accounts with a more cleaner implementation
|
// usage with service accounts with a more cleaner implementation
|
||||||
//
|
//
|
||||||
@ -882,20 +904,9 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa
|
|||||||
// webIdentity based STS tokens.
|
// webIdentity based STS tokens.
|
||||||
if cred.IsTemp() && cred.ParentUser != "" && cred.ParentUser != globalActiveCred.AccessKey {
|
if cred.IsTemp() && cred.ParentUser != "" && cred.ParentUser != globalActiveCred.AccessKey {
|
||||||
if _, ok := sys.iamUserPolicyMap[cred.ParentUser]; !ok {
|
if _, ok := sys.iamUserPolicyMap[cred.ParentUser]; !ok {
|
||||||
if err := sys.store.saveMappedPolicy(context.Background(), accessKey, stsUser, false, mp, options{ttl: ttl}); err != nil {
|
|
||||||
sys.store.unlock()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sys.iamUserPolicyMap[cred.ParentUser] = mp
|
sys.iamUserPolicyMap[cred.ParentUser] = mp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sys.store.saveMappedPolicy(context.Background(), accessKey, stsUser, false, mp, options{ttl: ttl}); err != nil {
|
|
||||||
sys.store.unlock()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
sys.iamUserPolicyMap[accessKey] = mp
|
|
||||||
} else {
|
} else {
|
||||||
sys.store.lock()
|
sys.store.lock()
|
||||||
defer sys.store.unlock()
|
defer sys.store.unlock()
|
||||||
@ -1115,33 +1126,16 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, gro
|
|||||||
defer sys.store.unlock()
|
defer sys.store.unlock()
|
||||||
|
|
||||||
cr, found := sys.iamUsersMap[parentUser]
|
cr, found := sys.iamUsersMap[parentUser]
|
||||||
switch {
|
|
||||||
// User found
|
|
||||||
case found:
|
|
||||||
// Disallow service accounts to further create more service accounts.
|
// Disallow service accounts to further create more service accounts.
|
||||||
if cr.IsServiceAccount() {
|
if found && cr.IsServiceAccount() {
|
||||||
return auth.Credentials{}, errIAMActionNotAllowed
|
return auth.Credentials{}, errIAMActionNotAllowed
|
||||||
}
|
}
|
||||||
// Allow creating service accounts for root user
|
|
||||||
case parentUser == globalActiveCred.AccessKey:
|
policies, err := sys.policyDBGet(parentUser, false)
|
||||||
// For LDAP/OpenID users we would need this fallback
|
if err != nil {
|
||||||
case sys.usersSysType != MinIOUsersSysType:
|
return auth.Credentials{}, err
|
||||||
_, ok := sys.iamUserPolicyMap[parentUser]
|
|
||||||
if !ok {
|
|
||||||
var groupHasPolicy bool
|
|
||||||
for _, group := range groups {
|
|
||||||
_, ok = sys.iamGroupPolicyMap[group]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
groupHasPolicy = true
|
if len(policies) == 0 {
|
||||||
break
|
|
||||||
}
|
|
||||||
if !groupHasPolicy {
|
|
||||||
return auth.Credentials{}, errNoSuchUser
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return auth.Credentials{}, errNoSuchUser
|
return auth.Credentials{}, errNoSuchUser
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1157,7 +1151,6 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, gro
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
cred auth.Credentials
|
cred auth.Credentials
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(opts.accessKey) > 0 {
|
if len(opts.accessKey) > 0 {
|
||||||
@ -1894,29 +1887,22 @@ func (sys *IAMSys) policyDBGet(name string, isGroup bool) (policies []string, er
|
|||||||
return sys.iamGroupPolicyMap[name].toSlice(), nil
|
return sys.iamGroupPolicyMap[name].toSlice(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var u auth.Credentials
|
|
||||||
var ok bool
|
|
||||||
if sys.usersSysType == MinIOUsersSysType {
|
|
||||||
if name == globalActiveCred.AccessKey {
|
if name == globalActiveCred.AccessKey {
|
||||||
return []string{"consoleAdmin"}, nil
|
return []string{"consoleAdmin"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// When looking for a user's policies, we also check if the user
|
// When looking for a user's policies, we also check if the user
|
||||||
// and the groups they are member of are enabled.
|
// and the groups they are member of are enabled.
|
||||||
u, ok = sys.iamUsersMap[name]
|
var parentName string
|
||||||
if !ok {
|
u, ok := sys.iamUsersMap[name]
|
||||||
return nil, errNoSuchUser
|
if ok {
|
||||||
}
|
parentName = u.ParentUser
|
||||||
|
|
||||||
if !u.IsValid() {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mp, ok := sys.iamUserPolicyMap[name]
|
mp, ok := sys.iamUserPolicyMap[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
if u.ParentUser != "" {
|
if parentName != "" {
|
||||||
mp = sys.iamUserPolicyMap[u.ParentUser]
|
mp = sys.iamUserPolicyMap[parentName]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user