diff --git a/cmd/iam.go b/cmd/iam.go index 87bd0acea..55be1cddd 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -401,6 +401,22 @@ func (sys *IAMSys) LoadUser(objAPI ObjectLayer, accessKey string, userType IAMUs if err != nil && err != errNoSuchPolicy { 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. return nil @@ -872,8 +888,14 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa sys.store.lock() 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 - // 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 // 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. if cred.IsTemp() && cred.ParentUser != "" && cred.ParentUser != globalActiveCred.AccessKey { 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 } } - - 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 { sys.store.lock() defer sys.store.unlock() @@ -1115,33 +1126,16 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, gro defer sys.store.unlock() cr, found := sys.iamUsersMap[parentUser] - switch { - // User found - case found: - // Disallow service accounts to further create more service accounts. - if cr.IsServiceAccount() { - return auth.Credentials{}, errIAMActionNotAllowed - } - // Allow creating service accounts for root user - case parentUser == globalActiveCred.AccessKey: - // For LDAP/OpenID users we would need this fallback - case sys.usersSysType != MinIOUsersSysType: - _, ok := sys.iamUserPolicyMap[parentUser] - if !ok { - var groupHasPolicy bool - for _, group := range groups { - _, ok = sys.iamGroupPolicyMap[group] - if !ok { - continue - } - groupHasPolicy = true - break - } - if !groupHasPolicy { - return auth.Credentials{}, errNoSuchUser - } - } - default: + // Disallow service accounts to further create more service accounts. + if found && cr.IsServiceAccount() { + return auth.Credentials{}, errIAMActionNotAllowed + } + + policies, err := sys.policyDBGet(parentUser, false) + if err != nil { + return auth.Credentials{}, err + } + if len(policies) == 0 { return auth.Credentials{}, errNoSuchUser } @@ -1157,7 +1151,6 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, gro var ( cred auth.Credentials - err error ) 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 } - var u auth.Credentials - var ok bool - if sys.usersSysType == MinIOUsersSysType { - if name == globalActiveCred.AccessKey { - return []string{"consoleAdmin"}, nil - } + if name == globalActiveCred.AccessKey { + return []string{"consoleAdmin"}, nil + } - // When looking for a user's policies, we also check if the user - // and the groups they are member of are enabled. - u, ok = sys.iamUsersMap[name] - if !ok { - return nil, errNoSuchUser - } - - if !u.IsValid() { - return nil, nil - } + // When looking for a user's policies, we also check if the user + // and the groups they are member of are enabled. + var parentName string + u, ok := sys.iamUsersMap[name] + if ok { + parentName = u.ParentUser } mp, ok := sys.iamUserPolicyMap[name] if !ok { - if u.ParentUser != "" { - mp = sys.iamUserPolicyMap[u.ParentUser] + if parentName != "" { + mp = sys.iamUserPolicyMap[parentName] } }