initialize IAM as soon as object layer is initialized (#10700)

Allow requests to come in for users as soon as object
layer and config are initialized, this allows users
to be authenticated sooner and would succeed automatically
on servers which are yet to fully initialize.
master
Harshavardhana 4 years ago committed by GitHub
parent c107728676
commit b07df5cae1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      cmd/admin-handlers-users.go
  2. 8
      cmd/gateway-main.go
  3. 126
      cmd/iam-etcd-store.go
  4. 95
      cmd/iam-object-store.go
  5. 201
      cmd/iam.go
  6. 3
      cmd/jwt.go
  7. 40
      cmd/peer-rest-server.go
  8. 21
      cmd/server-main.go
  9. 3
      cmd/signature-v4-utils.go

@ -36,7 +36,7 @@ func validateAdminUsersReq(ctx context.Context, w http.ResponseWriter, r *http.R
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return nil, cred return nil, cred
} }
@ -387,7 +387,7 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return
} }
@ -466,7 +466,7 @@ func (a adminAPIHandlers) ListServiceAccounts(w http.ResponseWriter, r *http.Req
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return
} }
@ -521,7 +521,7 @@ func (a adminAPIHandlers) DeleteServiceAccount(w http.ResponseWriter, r *http.Re
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return
} }
@ -580,7 +580,7 @@ func (a adminAPIHandlers) AccountUsageInfoHandler(w http.ResponseWriter, r *http
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerFn() objectAPI := newObjectLayerFn()
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { if objectAPI == nil || globalNotificationSys == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return return
} }

@ -300,14 +300,14 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
} }
newObject = NewGatewayLayerWithLocker(newObject) newObject = NewGatewayLayerWithLocker(newObject)
// Calls all New() for all sub-systems.
newAllSubsystems()
// Once endpoints are finalized, initialize the new object api in safe mode. // Once endpoints are finalized, initialize the new object api in safe mode.
globalObjLayerMutex.Lock() globalObjLayerMutex.Lock()
globalObjectAPI = newObject globalObjectAPI = newObject
globalObjLayerMutex.Unlock() globalObjLayerMutex.Unlock()
// Calls all New() for all sub-systems.
newAllSubsystems()
if gatewayName == NASBackendGateway { if gatewayName == NASBackendGateway {
buckets, err := newObject.ListBuckets(GlobalContext) buckets, err := newObject.ListBuckets(GlobalContext)
if err != nil { if err != nil {
@ -326,6 +326,8 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
if enableIAMOps { if enableIAMOps {
// Initialize users credentials and policies in background. // Initialize users credentials and policies in background.
globalIAMSys.InitStore(newObject)
go globalIAMSys.Init(GlobalContext, newObject) go globalIAMSys.Init(GlobalContext, newObject)
} }

@ -76,13 +76,11 @@ func etcdKvsToSetPolicyDB(prefix string, kvs []*mvccpb.KeyValue) set.StringSet {
type IAMEtcdStore struct { type IAMEtcdStore struct {
sync.RWMutex sync.RWMutex
ctx context.Context
client *etcd.Client client *etcd.Client
} }
func newIAMEtcdStore(ctx context.Context) *IAMEtcdStore { func newIAMEtcdStore() *IAMEtcdStore {
return &IAMEtcdStore{client: globalEtcdClient, ctx: ctx} return &IAMEtcdStore{client: globalEtcdClient}
} }
func (ies *IAMEtcdStore) lock() { func (ies *IAMEtcdStore) lock() {
@ -101,7 +99,7 @@ func (ies *IAMEtcdStore) runlock() {
ies.RUnlock() ies.RUnlock()
} }
func (ies *IAMEtcdStore) saveIAMConfig(item interface{}, path string) error { func (ies *IAMEtcdStore) saveIAMConfig(ctx context.Context, item interface{}, path string) error {
data, err := json.Marshal(item) data, err := json.Marshal(item)
if err != nil { if err != nil {
return err return err
@ -112,11 +110,11 @@ func (ies *IAMEtcdStore) saveIAMConfig(item interface{}, path string) error {
return err return err
} }
} }
return saveKeyEtcd(ies.ctx, ies.client, path, data) return saveKeyEtcd(ctx, ies.client, path, data)
} }
func (ies *IAMEtcdStore) loadIAMConfig(item interface{}, path string) error { func (ies *IAMEtcdStore) loadIAMConfig(ctx context.Context, item interface{}, path string) error {
pdata, err := readKeyEtcd(ies.ctx, ies.client, path) pdata, err := readKeyEtcd(ctx, ies.client, path)
if err != nil { if err != nil {
return err return err
} }
@ -131,8 +129,8 @@ func (ies *IAMEtcdStore) loadIAMConfig(item interface{}, path string) error {
return json.Unmarshal(pdata, item) return json.Unmarshal(pdata, item)
} }
func (ies *IAMEtcdStore) deleteIAMConfig(path string) error { func (ies *IAMEtcdStore) deleteIAMConfig(ctx context.Context, path string) error {
return deleteKeyEtcd(ies.ctx, ies.client, path) return deleteKeyEtcd(ctx, ies.client, path)
} }
func (ies *IAMEtcdStore) migrateUsersConfigToV1(ctx context.Context, isSTS bool) error { func (ies *IAMEtcdStore) migrateUsersConfigToV1(ctx context.Context, isSTS bool) error {
@ -154,7 +152,7 @@ func (ies *IAMEtcdStore) migrateUsersConfigToV1(ctx context.Context, isSTS bool)
// 1. check if there is a policy file in the old loc. // 1. check if there is a policy file in the old loc.
oldPolicyPath := pathJoin(basePrefix, user, iamPolicyFile) oldPolicyPath := pathJoin(basePrefix, user, iamPolicyFile)
var policyName string var policyName string
err := ies.loadIAMConfig(&policyName, oldPolicyPath) err := ies.loadIAMConfig(ctx, &policyName, oldPolicyPath)
if err != nil { if err != nil {
switch err { switch err {
case errConfigNotFound: case errConfigNotFound:
@ -172,7 +170,7 @@ func (ies *IAMEtcdStore) migrateUsersConfigToV1(ctx context.Context, isSTS bool)
userType = stsUser userType = stsUser
} }
path := getMappedPolicyPath(user, userType, false) path := getMappedPolicyPath(user, userType, false)
if err := ies.saveIAMConfig(mp, path); err != nil { if err := ies.saveIAMConfig(ctx, mp, path); err != nil {
return err return err
} }
@ -184,7 +182,7 @@ func (ies *IAMEtcdStore) migrateUsersConfigToV1(ctx context.Context, isSTS bool)
// 4. check if user identity has old format. // 4. check if user identity has old format.
identityPath := pathJoin(basePrefix, user, iamIdentityFile) identityPath := pathJoin(basePrefix, user, iamIdentityFile)
var cred auth.Credentials var cred auth.Credentials
if err := ies.loadIAMConfig(&cred, identityPath); err != nil { if err := ies.loadIAMConfig(ctx, &cred, identityPath); err != nil {
switch err { switch err {
case errConfigNotFound: case errConfigNotFound:
// This case should not happen. // This case should not happen.
@ -207,7 +205,7 @@ func (ies *IAMEtcdStore) migrateUsersConfigToV1(ctx context.Context, isSTS bool)
// into new format and save it. // into new format and save it.
cred.AccessKey = user cred.AccessKey = user
u := newUserIdentity(cred) u := newUserIdentity(cred)
if err := ies.saveIAMConfig(u, identityPath); err != nil { if err := ies.saveIAMConfig(ctx, u, identityPath); err != nil {
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return err return err
} }
@ -221,7 +219,7 @@ func (ies *IAMEtcdStore) migrateUsersConfigToV1(ctx context.Context, isSTS bool)
func (ies *IAMEtcdStore) migrateToV1(ctx context.Context) error { func (ies *IAMEtcdStore) migrateToV1(ctx context.Context) error {
var iamFmt iamFormat var iamFmt iamFormat
path := getIAMFormatFilePath() path := getIAMFormatFilePath()
if err := ies.loadIAMConfig(&iamFmt, path); err != nil { if err := ies.loadIAMConfig(ctx, &iamFmt, path); err != nil {
switch err { switch err {
case errConfigNotFound: case errConfigNotFound:
// Need to migrate to V1. // Need to migrate to V1.
@ -250,7 +248,7 @@ func (ies *IAMEtcdStore) migrateToV1(ctx context.Context) error {
return err return err
} }
// Save iam version file. // Save iam version file.
if err := ies.saveIAMConfig(newIAMFormatVersion1(), path); err != nil { if err := ies.saveIAMConfig(ctx, newIAMFormatVersion1(), path); err != nil {
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return err return err
} }
@ -262,9 +260,9 @@ func (ies *IAMEtcdStore) migrateBackendFormat(ctx context.Context) error {
return ies.migrateToV1(ctx) return ies.migrateToV1(ctx)
} }
func (ies *IAMEtcdStore) loadPolicyDoc(policy string, m map[string]iampolicy.Policy) error { func (ies *IAMEtcdStore) loadPolicyDoc(ctx context.Context, policy string, m map[string]iampolicy.Policy) error {
var p iampolicy.Policy var p iampolicy.Policy
err := ies.loadIAMConfig(&p, getPolicyDocPath(policy)) err := ies.loadIAMConfig(ctx, &p, getPolicyDocPath(policy))
if err != nil { if err != nil {
return err return err
} }
@ -284,7 +282,7 @@ func (ies *IAMEtcdStore) loadPolicyDocs(ctx context.Context, m map[string]iampol
// Reload config and policies for all policys. // Reload config and policies for all policys.
for _, policyName := range policies.ToSlice() { for _, policyName := range policies.ToSlice() {
err = ies.loadPolicyDoc(policyName, m) err = ies.loadPolicyDoc(ctx, policyName, m)
if err != nil { if err != nil {
return err return err
} }
@ -292,9 +290,9 @@ func (ies *IAMEtcdStore) loadPolicyDocs(ctx context.Context, m map[string]iampol
return nil return nil
} }
func (ies *IAMEtcdStore) loadUser(user string, userType IAMUserType, m map[string]auth.Credentials) error { func (ies *IAMEtcdStore) loadUser(ctx context.Context, user string, userType IAMUserType, m map[string]auth.Credentials) error {
var u UserIdentity var u UserIdentity
err := ies.loadIAMConfig(&u, getUserIdentityPath(user, userType)) err := ies.loadIAMConfig(ctx, &u, getUserIdentityPath(user, userType))
if err != nil { if err != nil {
if err == errConfigNotFound { if err == errConfigNotFound {
return errNoSuchUser return errNoSuchUser
@ -304,8 +302,8 @@ func (ies *IAMEtcdStore) loadUser(user string, userType IAMUserType, m map[strin
if u.Credentials.IsExpired() { if u.Credentials.IsExpired() {
// Delete expired identity. // Delete expired identity.
deleteKeyEtcd(ies.ctx, ies.client, getUserIdentityPath(user, userType)) deleteKeyEtcd(ctx, ies.client, getUserIdentityPath(user, userType))
deleteKeyEtcd(ies.ctx, ies.client, getMappedPolicyPath(user, userType, false)) deleteKeyEtcd(ctx, ies.client, getMappedPolicyPath(user, userType, false))
return nil return nil
} }
@ -320,7 +318,7 @@ func (ies *IAMEtcdStore) loadUser(user string, userType IAMUserType, m map[strin
jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.MapClaims(m)) jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.MapClaims(m))
if token, err := jwt.SignedString([]byte(globalActiveCred.SecretKey)); err == nil { if token, err := jwt.SignedString([]byte(globalActiveCred.SecretKey)); err == nil {
u.Credentials.SessionToken = token u.Credentials.SessionToken = token
err := ies.saveIAMConfig(&u, getUserIdentityPath(user, userType)) err := ies.saveIAMConfig(ctx, &u, getUserIdentityPath(user, userType))
if err != nil { if err != nil {
return err return err
} }
@ -348,9 +346,10 @@ func (ies *IAMEtcdStore) loadUsers(ctx context.Context, userType IAMUserType, m
basePrefix = iamConfigUsersPrefix basePrefix = iamConfigUsersPrefix
} }
ctx, cancel := context.WithTimeout(ctx, defaultContextTimeout) cctx, cancel := context.WithTimeout(ctx, defaultContextTimeout)
defer cancel() defer cancel()
r, err := ies.client.Get(ctx, basePrefix, etcd.WithPrefix(), etcd.WithKeysOnly())
r, err := ies.client.Get(cctx, basePrefix, etcd.WithPrefix(), etcd.WithKeysOnly())
if err != nil { if err != nil {
return err return err
} }
@ -359,16 +358,16 @@ func (ies *IAMEtcdStore) loadUsers(ctx context.Context, userType IAMUserType, m
// Reload config for all users. // Reload config for all users.
for _, user := range users.ToSlice() { for _, user := range users.ToSlice() {
if err = ies.loadUser(user, userType, m); err != nil { if err = ies.loadUser(ctx, user, userType, m); err != nil {
return err return err
} }
} }
return nil return nil
} }
func (ies *IAMEtcdStore) loadGroup(group string, m map[string]GroupInfo) error { func (ies *IAMEtcdStore) loadGroup(ctx context.Context, group string, m map[string]GroupInfo) error {
var gi GroupInfo var gi GroupInfo
err := ies.loadIAMConfig(&gi, getGroupInfoPath(group)) err := ies.loadIAMConfig(ctx, &gi, getGroupInfoPath(group))
if err != nil { if err != nil {
if err == errConfigNotFound { if err == errConfigNotFound {
return errNoSuchGroup return errNoSuchGroup
@ -381,9 +380,10 @@ func (ies *IAMEtcdStore) loadGroup(group string, m map[string]GroupInfo) error {
} }
func (ies *IAMEtcdStore) loadGroups(ctx context.Context, m map[string]GroupInfo) error { func (ies *IAMEtcdStore) loadGroups(ctx context.Context, m map[string]GroupInfo) error {
ctx, cancel := context.WithTimeout(ctx, defaultContextTimeout) cctx, cancel := context.WithTimeout(ctx, defaultContextTimeout)
defer cancel() defer cancel()
r, err := ies.client.Get(ctx, iamConfigGroupsPrefix, etcd.WithPrefix(), etcd.WithKeysOnly())
r, err := ies.client.Get(cctx, iamConfigGroupsPrefix, etcd.WithPrefix(), etcd.WithKeysOnly())
if err != nil { if err != nil {
return err return err
} }
@ -392,7 +392,7 @@ func (ies *IAMEtcdStore) loadGroups(ctx context.Context, m map[string]GroupInfo)
// Reload config for all groups. // Reload config for all groups.
for _, group := range groups.ToSlice() { for _, group := range groups.ToSlice() {
if err = ies.loadGroup(group, m); err != nil { if err = ies.loadGroup(ctx, group, m); err != nil {
return err return err
} }
} }
@ -400,9 +400,9 @@ func (ies *IAMEtcdStore) loadGroups(ctx context.Context, m map[string]GroupInfo)
} }
func (ies *IAMEtcdStore) loadMappedPolicy(name string, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error { func (ies *IAMEtcdStore) loadMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error {
var p MappedPolicy var p MappedPolicy
err := ies.loadIAMConfig(&p, getMappedPolicyPath(name, userType, isGroup)) err := ies.loadIAMConfig(ctx, &p, getMappedPolicyPath(name, userType, isGroup))
if err != nil { if err != nil {
if err == errConfigNotFound { if err == errConfigNotFound {
return errNoSuchPolicy return errNoSuchPolicy
@ -415,7 +415,7 @@ func (ies *IAMEtcdStore) loadMappedPolicy(name string, userType IAMUserType, isG
} }
func (ies *IAMEtcdStore) loadMappedPolicies(ctx context.Context, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error { func (ies *IAMEtcdStore) loadMappedPolicies(ctx context.Context, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error {
ctx, cancel := context.WithTimeout(ctx, defaultContextTimeout) cctx, cancel := context.WithTimeout(ctx, defaultContextTimeout)
defer cancel() defer cancel()
var basePrefix string var basePrefix string
if isGroup { if isGroup {
@ -430,7 +430,8 @@ func (ies *IAMEtcdStore) loadMappedPolicies(ctx context.Context, userType IAMUse
basePrefix = iamConfigPolicyDBUsersPrefix basePrefix = iamConfigPolicyDBUsersPrefix
} }
} }
r, err := ies.client.Get(ctx, basePrefix, etcd.WithPrefix(), etcd.WithKeysOnly())
r, err := ies.client.Get(cctx, basePrefix, etcd.WithPrefix(), etcd.WithKeysOnly())
if err != nil { if err != nil {
return err return err
} }
@ -439,7 +440,7 @@ func (ies *IAMEtcdStore) loadMappedPolicies(ctx context.Context, userType IAMUse
// Reload config and policies for all users. // Reload config and policies for all users.
for _, user := range users.ToSlice() { for _, user := range users.ToSlice() {
if err = ies.loadMappedPolicy(user, userType, isGroup, m); err != nil { if err = ies.loadMappedPolicy(ctx, user, userType, isGroup, m); err != nil {
return err return err
} }
} }
@ -531,7 +532,7 @@ func (ies *IAMEtcdStore) loadAll(ctx context.Context, sys *IAMSys) error {
if v.IsServiceAccount() { if v.IsServiceAccount() {
for _, accessKey := range expiredEntries { for _, accessKey := range expiredEntries {
if v.ParentUser == accessKey { if v.ParentUser == accessKey {
_ = ies.deleteUserIdentity(v.AccessKey, srvAccUser) _ = ies.deleteUserIdentity(ctx, v.AccessKey, srvAccUser)
delete(sys.iamUsersMap, v.AccessKey) delete(sys.iamUsersMap, v.AccessKey)
} }
} }
@ -561,48 +562,48 @@ func (ies *IAMEtcdStore) loadAll(ctx context.Context, sys *IAMSys) error {
return nil return nil
} }
func (ies *IAMEtcdStore) savePolicyDoc(policyName string, p iampolicy.Policy) error { func (ies *IAMEtcdStore) savePolicyDoc(ctx context.Context, policyName string, p iampolicy.Policy) error {
return ies.saveIAMConfig(&p, getPolicyDocPath(policyName)) return ies.saveIAMConfig(ctx, &p, getPolicyDocPath(policyName))
} }
func (ies *IAMEtcdStore) saveMappedPolicy(name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error { func (ies *IAMEtcdStore) saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error {
return ies.saveIAMConfig(mp, getMappedPolicyPath(name, userType, isGroup)) return ies.saveIAMConfig(ctx, mp, getMappedPolicyPath(name, userType, isGroup))
} }
func (ies *IAMEtcdStore) saveUserIdentity(name string, userType IAMUserType, u UserIdentity) error { func (ies *IAMEtcdStore) saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity) error {
return ies.saveIAMConfig(u, getUserIdentityPath(name, userType)) return ies.saveIAMConfig(ctx, u, getUserIdentityPath(name, userType))
} }
func (ies *IAMEtcdStore) saveGroupInfo(name string, gi GroupInfo) error { func (ies *IAMEtcdStore) saveGroupInfo(ctx context.Context, name string, gi GroupInfo) error {
return ies.saveIAMConfig(gi, getGroupInfoPath(name)) return ies.saveIAMConfig(ctx, gi, getGroupInfoPath(name))
} }
func (ies *IAMEtcdStore) deletePolicyDoc(name string) error { func (ies *IAMEtcdStore) deletePolicyDoc(ctx context.Context, name string) error {
err := ies.deleteIAMConfig(getPolicyDocPath(name)) err := ies.deleteIAMConfig(ctx, getPolicyDocPath(name))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchPolicy err = errNoSuchPolicy
} }
return err return err
} }
func (ies *IAMEtcdStore) deleteMappedPolicy(name string, userType IAMUserType, isGroup bool) error { func (ies *IAMEtcdStore) deleteMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool) error {
err := ies.deleteIAMConfig(getMappedPolicyPath(name, userType, isGroup)) err := ies.deleteIAMConfig(ctx, getMappedPolicyPath(name, userType, isGroup))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchPolicy err = errNoSuchPolicy
} }
return err return err
} }
func (ies *IAMEtcdStore) deleteUserIdentity(name string, userType IAMUserType) error { func (ies *IAMEtcdStore) deleteUserIdentity(ctx context.Context, name string, userType IAMUserType) error {
err := ies.deleteIAMConfig(getUserIdentityPath(name, userType)) err := ies.deleteIAMConfig(ctx, getUserIdentityPath(name, userType))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchUser err = errNoSuchUser
} }
return err return err
} }
func (ies *IAMEtcdStore) deleteGroupInfo(name string) error { func (ies *IAMEtcdStore) deleteGroupInfo(ctx context.Context, name string) error {
err := ies.deleteIAMConfig(getGroupInfoPath(name)) err := ies.deleteIAMConfig(ctx, getGroupInfoPath(name))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchGroup err = errNoSuchGroup
} }
@ -657,43 +658,46 @@ func (ies *IAMEtcdStore) reloadFromEvent(sys *IAMSys, event *etcd.Event) {
policyDBSTSUsersPrefix := strings.HasPrefix(string(event.Kv.Key), iamConfigPolicyDBSTSUsersPrefix) policyDBSTSUsersPrefix := strings.HasPrefix(string(event.Kv.Key), iamConfigPolicyDBSTSUsersPrefix)
policyDBGroupsPrefix := strings.HasPrefix(string(event.Kv.Key), iamConfigPolicyDBGroupsPrefix) policyDBGroupsPrefix := strings.HasPrefix(string(event.Kv.Key), iamConfigPolicyDBGroupsPrefix)
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
switch { switch {
case eventCreate: case eventCreate:
switch { switch {
case usersPrefix: case usersPrefix:
accessKey := path.Dir(strings.TrimPrefix(string(event.Kv.Key), accessKey := path.Dir(strings.TrimPrefix(string(event.Kv.Key),
iamConfigUsersPrefix)) iamConfigUsersPrefix))
ies.loadUser(accessKey, regularUser, sys.iamUsersMap) ies.loadUser(ctx, accessKey, regularUser, sys.iamUsersMap)
case stsPrefix: case stsPrefix:
accessKey := path.Dir(strings.TrimPrefix(string(event.Kv.Key), accessKey := path.Dir(strings.TrimPrefix(string(event.Kv.Key),
iamConfigSTSPrefix)) iamConfigSTSPrefix))
ies.loadUser(accessKey, stsUser, sys.iamUsersMap) ies.loadUser(ctx, accessKey, stsUser, sys.iamUsersMap)
case groupsPrefix: case groupsPrefix:
group := path.Dir(strings.TrimPrefix(string(event.Kv.Key), group := path.Dir(strings.TrimPrefix(string(event.Kv.Key),
iamConfigGroupsPrefix)) iamConfigGroupsPrefix))
ies.loadGroup(group, sys.iamGroupsMap) ies.loadGroup(ctx, group, sys.iamGroupsMap)
gi := sys.iamGroupsMap[group] gi := sys.iamGroupsMap[group]
sys.removeGroupFromMembershipsMap(group) sys.removeGroupFromMembershipsMap(group)
sys.updateGroupMembershipsMap(group, &gi) sys.updateGroupMembershipsMap(group, &gi)
case policyPrefix: case policyPrefix:
policyName := path.Dir(strings.TrimPrefix(string(event.Kv.Key), policyName := path.Dir(strings.TrimPrefix(string(event.Kv.Key),
iamConfigPoliciesPrefix)) iamConfigPoliciesPrefix))
ies.loadPolicyDoc(policyName, sys.iamPolicyDocsMap) ies.loadPolicyDoc(ctx, policyName, sys.iamPolicyDocsMap)
case policyDBUsersPrefix: case policyDBUsersPrefix:
policyMapFile := strings.TrimPrefix(string(event.Kv.Key), policyMapFile := strings.TrimPrefix(string(event.Kv.Key),
iamConfigPolicyDBUsersPrefix) iamConfigPolicyDBUsersPrefix)
user := strings.TrimSuffix(policyMapFile, ".json") user := strings.TrimSuffix(policyMapFile, ".json")
ies.loadMappedPolicy(user, regularUser, false, sys.iamUserPolicyMap) ies.loadMappedPolicy(ctx, user, regularUser, false, sys.iamUserPolicyMap)
case policyDBSTSUsersPrefix: case policyDBSTSUsersPrefix:
policyMapFile := strings.TrimPrefix(string(event.Kv.Key), policyMapFile := strings.TrimPrefix(string(event.Kv.Key),
iamConfigPolicyDBSTSUsersPrefix) iamConfigPolicyDBSTSUsersPrefix)
user := strings.TrimSuffix(policyMapFile, ".json") user := strings.TrimSuffix(policyMapFile, ".json")
ies.loadMappedPolicy(user, stsUser, false, sys.iamUserPolicyMap) ies.loadMappedPolicy(ctx, user, stsUser, false, sys.iamUserPolicyMap)
case policyDBGroupsPrefix: case policyDBGroupsPrefix:
policyMapFile := strings.TrimPrefix(string(event.Kv.Key), policyMapFile := strings.TrimPrefix(string(event.Kv.Key),
iamConfigPolicyDBGroupsPrefix) iamConfigPolicyDBGroupsPrefix)
user := strings.TrimSuffix(policyMapFile, ".json") user := strings.TrimSuffix(policyMapFile, ".json")
ies.loadMappedPolicy(user, regularUser, true, sys.iamGroupPolicyMap) ies.loadMappedPolicy(ctx, user, regularUser, true, sys.iamGroupPolicyMap)
} }
case eventDelete: case eventDelete:
switch { switch {

@ -39,12 +39,11 @@ type IAMObjectStore struct {
// Protect assignment to objAPI // Protect assignment to objAPI
sync.RWMutex sync.RWMutex
ctx context.Context
objAPI ObjectLayer objAPI ObjectLayer
} }
func newIAMObjectStore(ctx context.Context, objAPI ObjectLayer) *IAMObjectStore { func newIAMObjectStore(objAPI ObjectLayer) *IAMObjectStore {
return &IAMObjectStore{ctx: ctx, objAPI: objAPI} return &IAMObjectStore{objAPI: objAPI}
} }
func (iamOS *IAMObjectStore) lock() { func (iamOS *IAMObjectStore) lock() {
@ -94,7 +93,7 @@ func (iamOS *IAMObjectStore) migrateUsersConfigToV1(ctx context.Context, isSTS b
// 1. check if there is policy file in old location. // 1. check if there is policy file in old location.
oldPolicyPath := pathJoin(basePrefix, user, iamPolicyFile) oldPolicyPath := pathJoin(basePrefix, user, iamPolicyFile)
var policyName string var policyName string
if err := iamOS.loadIAMConfig(&policyName, oldPolicyPath); err != nil { if err := iamOS.loadIAMConfig(ctx, &policyName, oldPolicyPath); err != nil {
switch err { switch err {
case errConfigNotFound: case errConfigNotFound:
// This case means it is already // This case means it is already
@ -115,19 +114,19 @@ func (iamOS *IAMObjectStore) migrateUsersConfigToV1(ctx context.Context, isSTS b
if isSTS { if isSTS {
userType = stsUser userType = stsUser
} }
if err := iamOS.saveMappedPolicy(user, userType, false, mp); err != nil { if err := iamOS.saveMappedPolicy(ctx, user, userType, false, mp); err != nil {
return err return err
} }
// 3. delete policy file from old // 3. delete policy file from old
// location. Ignore error. // location. Ignore error.
iamOS.deleteIAMConfig(oldPolicyPath) iamOS.deleteIAMConfig(ctx, oldPolicyPath)
} }
next: next:
// 4. check if user identity has old format. // 4. check if user identity has old format.
identityPath := pathJoin(basePrefix, user, iamIdentityFile) identityPath := pathJoin(basePrefix, user, iamIdentityFile)
var cred auth.Credentials var cred auth.Credentials
if err := iamOS.loadIAMConfig(&cred, identityPath); err != nil { if err := iamOS.loadIAMConfig(ctx, &cred, identityPath); err != nil {
switch err { switch err {
case errConfigNotFound: case errConfigNotFound:
// This should not happen. // This should not happen.
@ -150,7 +149,7 @@ func (iamOS *IAMObjectStore) migrateUsersConfigToV1(ctx context.Context, isSTS b
// into new format and save it. // into new format and save it.
cred.AccessKey = user cred.AccessKey = user
u := newUserIdentity(cred) u := newUserIdentity(cred)
if err := iamOS.saveIAMConfig(u, identityPath); err != nil { if err := iamOS.saveIAMConfig(ctx, u, identityPath); err != nil {
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return err return err
} }
@ -165,7 +164,7 @@ func (iamOS *IAMObjectStore) migrateUsersConfigToV1(ctx context.Context, isSTS b
func (iamOS *IAMObjectStore) migrateToV1(ctx context.Context) error { func (iamOS *IAMObjectStore) migrateToV1(ctx context.Context) error {
var iamFmt iamFormat var iamFmt iamFormat
path := getIAMFormatFilePath() path := getIAMFormatFilePath()
if err := iamOS.loadIAMConfig(&iamFmt, path); err != nil { if err := iamOS.loadIAMConfig(ctx, &iamFmt, path); err != nil {
switch err { switch err {
case errConfigNotFound: case errConfigNotFound:
// Need to migrate to V1. // Need to migrate to V1.
@ -193,7 +192,7 @@ func (iamOS *IAMObjectStore) migrateToV1(ctx context.Context) error {
return err return err
} }
// Save iam format to version 1. // Save iam format to version 1.
if err := iamOS.saveIAMConfig(newIAMFormatVersion1(), path); err != nil { if err := iamOS.saveIAMConfig(ctx, newIAMFormatVersion1(), path); err != nil {
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return err return err
} }
@ -205,7 +204,7 @@ func (iamOS *IAMObjectStore) migrateBackendFormat(ctx context.Context) error {
return iamOS.migrateToV1(ctx) return iamOS.migrateToV1(ctx)
} }
func (iamOS *IAMObjectStore) saveIAMConfig(item interface{}, path string) error { func (iamOS *IAMObjectStore) saveIAMConfig(ctx context.Context, item interface{}, path string) error {
data, err := json.Marshal(item) data, err := json.Marshal(item)
if err != nil { if err != nil {
return err return err
@ -216,11 +215,11 @@ func (iamOS *IAMObjectStore) saveIAMConfig(item interface{}, path string) error
return err return err
} }
} }
return saveConfig(GlobalContext, iamOS.objAPI, path, data) return saveConfig(ctx, iamOS.objAPI, path, data)
} }
func (iamOS *IAMObjectStore) loadIAMConfig(item interface{}, path string) error { func (iamOS *IAMObjectStore) loadIAMConfig(ctx context.Context, item interface{}, path string) error {
data, err := readConfig(iamOS.ctx, iamOS.objAPI, path) data, err := readConfig(ctx, iamOS.objAPI, path)
if err != nil { if err != nil {
return err return err
} }
@ -233,13 +232,13 @@ func (iamOS *IAMObjectStore) loadIAMConfig(item interface{}, path string) error
return json.Unmarshal(data, item) return json.Unmarshal(data, item)
} }
func (iamOS *IAMObjectStore) deleteIAMConfig(path string) error { func (iamOS *IAMObjectStore) deleteIAMConfig(ctx context.Context, path string) error {
return deleteConfig(iamOS.ctx, iamOS.objAPI, path) return deleteConfig(ctx, iamOS.objAPI, path)
} }
func (iamOS *IAMObjectStore) loadPolicyDoc(policy string, m map[string]iampolicy.Policy) error { func (iamOS *IAMObjectStore) loadPolicyDoc(ctx context.Context, policy string, m map[string]iampolicy.Policy) error {
var p iampolicy.Policy var p iampolicy.Policy
err := iamOS.loadIAMConfig(&p, getPolicyDocPath(policy)) err := iamOS.loadIAMConfig(ctx, &p, getPolicyDocPath(policy))
if err != nil { if err != nil {
if err == errConfigNotFound { if err == errConfigNotFound {
return errNoSuchPolicy return errNoSuchPolicy
@ -257,16 +256,16 @@ func (iamOS *IAMObjectStore) loadPolicyDocs(ctx context.Context, m map[string]ia
} }
policyName := item.Item policyName := item.Item
if err := iamOS.loadPolicyDoc(policyName, m); err != nil && err != errNoSuchPolicy { if err := iamOS.loadPolicyDoc(ctx, policyName, m); err != nil && err != errNoSuchPolicy {
return err return err
} }
} }
return nil return nil
} }
func (iamOS *IAMObjectStore) loadUser(user string, userType IAMUserType, m map[string]auth.Credentials) error { func (iamOS *IAMObjectStore) loadUser(ctx context.Context, user string, userType IAMUserType, m map[string]auth.Credentials) error {
var u UserIdentity var u UserIdentity
err := iamOS.loadIAMConfig(&u, getUserIdentityPath(user, userType)) err := iamOS.loadIAMConfig(ctx, &u, getUserIdentityPath(user, userType))
if err != nil { if err != nil {
if err == errConfigNotFound { if err == errConfigNotFound {
return errNoSuchUser return errNoSuchUser
@ -276,8 +275,8 @@ func (iamOS *IAMObjectStore) loadUser(user string, userType IAMUserType, m map[s
if u.Credentials.IsExpired() { if u.Credentials.IsExpired() {
// Delete expired identity - ignoring errors here. // Delete expired identity - ignoring errors here.
iamOS.deleteIAMConfig(getUserIdentityPath(user, userType)) iamOS.deleteIAMConfig(ctx, getUserIdentityPath(user, userType))
iamOS.deleteIAMConfig(getMappedPolicyPath(user, userType, false)) iamOS.deleteIAMConfig(ctx, getMappedPolicyPath(user, userType, false))
return nil return nil
} }
@ -292,7 +291,7 @@ func (iamOS *IAMObjectStore) loadUser(user string, userType IAMUserType, m map[s
jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.MapClaims(m)) jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.MapClaims(m))
if token, err := jwt.SignedString([]byte(globalActiveCred.SecretKey)); err == nil { if token, err := jwt.SignedString([]byte(globalActiveCred.SecretKey)); err == nil {
u.Credentials.SessionToken = token u.Credentials.SessionToken = token
err := iamOS.saveIAMConfig(&u, getUserIdentityPath(user, userType)) err := iamOS.saveIAMConfig(ctx, &u, getUserIdentityPath(user, userType))
if err != nil { if err != nil {
return err return err
} }
@ -326,16 +325,16 @@ func (iamOS *IAMObjectStore) loadUsers(ctx context.Context, userType IAMUserType
} }
userName := item.Item userName := item.Item
if err := iamOS.loadUser(userName, userType, m); err != nil && err != errNoSuchUser { if err := iamOS.loadUser(ctx, userName, userType, m); err != nil && err != errNoSuchUser {
return err return err
} }
} }
return nil return nil
} }
func (iamOS *IAMObjectStore) loadGroup(group string, m map[string]GroupInfo) error { func (iamOS *IAMObjectStore) loadGroup(ctx context.Context, group string, m map[string]GroupInfo) error {
var g GroupInfo var g GroupInfo
err := iamOS.loadIAMConfig(&g, getGroupInfoPath(group)) err := iamOS.loadIAMConfig(ctx, &g, getGroupInfoPath(group))
if err != nil { if err != nil {
if err == errConfigNotFound { if err == errConfigNotFound {
return errNoSuchGroup return errNoSuchGroup
@ -353,18 +352,18 @@ func (iamOS *IAMObjectStore) loadGroups(ctx context.Context, m map[string]GroupI
} }
group := item.Item group := item.Item
if err := iamOS.loadGroup(group, m); err != nil && err != errNoSuchGroup { if err := iamOS.loadGroup(ctx, group, m); err != nil && err != errNoSuchGroup {
return err return err
} }
} }
return nil return nil
} }
func (iamOS *IAMObjectStore) loadMappedPolicy(name string, userType IAMUserType, isGroup bool, func (iamOS *IAMObjectStore) loadMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool,
m map[string]MappedPolicy) error { m map[string]MappedPolicy) error {
var p MappedPolicy var p MappedPolicy
err := iamOS.loadIAMConfig(&p, getMappedPolicyPath(name, userType, isGroup)) err := iamOS.loadIAMConfig(ctx, &p, getMappedPolicyPath(name, userType, isGroup))
if err != nil { if err != nil {
if err == errConfigNotFound { if err == errConfigNotFound {
return errNoSuchPolicy return errNoSuchPolicy
@ -396,7 +395,7 @@ func (iamOS *IAMObjectStore) loadMappedPolicies(ctx context.Context, userType IA
policyFile := item.Item policyFile := item.Item
userOrGroupName := strings.TrimSuffix(policyFile, ".json") userOrGroupName := strings.TrimSuffix(policyFile, ".json")
if err := iamOS.loadMappedPolicy(userOrGroupName, userType, isGroup, m); err != nil && err != errNoSuchPolicy { if err := iamOS.loadMappedPolicy(ctx, userOrGroupName, userType, isGroup, m); err != nil && err != errNoSuchPolicy {
return err return err
} }
} }
@ -489,7 +488,7 @@ func (iamOS *IAMObjectStore) loadAll(ctx context.Context, sys *IAMSys) error {
if v.IsServiceAccount() { if v.IsServiceAccount() {
for _, accessKey := range expiredEntries { for _, accessKey := range expiredEntries {
if v.ParentUser == accessKey { if v.ParentUser == accessKey {
_ = iamOS.deleteUserIdentity(v.AccessKey, srvAccUser) _ = iamOS.deleteUserIdentity(ctx, v.AccessKey, srvAccUser)
delete(sys.iamUsersMap, v.AccessKey) delete(sys.iamUsersMap, v.AccessKey)
} }
} }
@ -510,48 +509,48 @@ func (iamOS *IAMObjectStore) loadAll(ctx context.Context, sys *IAMSys) error {
return nil return nil
} }
func (iamOS *IAMObjectStore) savePolicyDoc(policyName string, p iampolicy.Policy) error { func (iamOS *IAMObjectStore) savePolicyDoc(ctx context.Context, policyName string, p iampolicy.Policy) error {
return iamOS.saveIAMConfig(&p, getPolicyDocPath(policyName)) return iamOS.saveIAMConfig(ctx, &p, getPolicyDocPath(policyName))
} }
func (iamOS *IAMObjectStore) saveMappedPolicy(name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error { func (iamOS *IAMObjectStore) saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error {
return iamOS.saveIAMConfig(mp, getMappedPolicyPath(name, userType, isGroup)) return iamOS.saveIAMConfig(ctx, mp, getMappedPolicyPath(name, userType, isGroup))
} }
func (iamOS *IAMObjectStore) saveUserIdentity(name string, userType IAMUserType, u UserIdentity) error { func (iamOS *IAMObjectStore) saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity) error {
return iamOS.saveIAMConfig(u, getUserIdentityPath(name, userType)) return iamOS.saveIAMConfig(ctx, u, getUserIdentityPath(name, userType))
} }
func (iamOS *IAMObjectStore) saveGroupInfo(name string, gi GroupInfo) error { func (iamOS *IAMObjectStore) saveGroupInfo(ctx context.Context, name string, gi GroupInfo) error {
return iamOS.saveIAMConfig(gi, getGroupInfoPath(name)) return iamOS.saveIAMConfig(ctx, gi, getGroupInfoPath(name))
} }
func (iamOS *IAMObjectStore) deletePolicyDoc(name string) error { func (iamOS *IAMObjectStore) deletePolicyDoc(ctx context.Context, name string) error {
err := iamOS.deleteIAMConfig(getPolicyDocPath(name)) err := iamOS.deleteIAMConfig(ctx, getPolicyDocPath(name))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchPolicy err = errNoSuchPolicy
} }
return err return err
} }
func (iamOS *IAMObjectStore) deleteMappedPolicy(name string, userType IAMUserType, isGroup bool) error { func (iamOS *IAMObjectStore) deleteMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool) error {
err := iamOS.deleteIAMConfig(getMappedPolicyPath(name, userType, isGroup)) err := iamOS.deleteIAMConfig(ctx, getMappedPolicyPath(name, userType, isGroup))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchPolicy err = errNoSuchPolicy
} }
return err return err
} }
func (iamOS *IAMObjectStore) deleteUserIdentity(name string, userType IAMUserType) error { func (iamOS *IAMObjectStore) deleteUserIdentity(ctx context.Context, name string, userType IAMUserType) error {
err := iamOS.deleteIAMConfig(getUserIdentityPath(name, userType)) err := iamOS.deleteIAMConfig(ctx, getUserIdentityPath(name, userType))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchUser err = errNoSuchUser
} }
return err return err
} }
func (iamOS *IAMObjectStore) deleteGroupInfo(name string) error { func (iamOS *IAMObjectStore) deleteGroupInfo(ctx context.Context, name string) error {
err := iamOS.deleteIAMConfig(getGroupInfoPath(name)) err := iamOS.deleteIAMConfig(ctx, getGroupInfoPath(name))
if err == errConfigNotFound { if err == errConfigNotFound {
err = errNoSuchGroup err = errNoSuchGroup
} }

@ -240,33 +240,33 @@ type IAMStorageAPI interface {
migrateBackendFormat(context.Context) error migrateBackendFormat(context.Context) error
loadPolicyDoc(policy string, m map[string]iampolicy.Policy) error loadPolicyDoc(ctx context.Context, policy string, m map[string]iampolicy.Policy) error
loadPolicyDocs(ctx context.Context, m map[string]iampolicy.Policy) error loadPolicyDocs(ctx context.Context, m map[string]iampolicy.Policy) error
loadUser(user string, userType IAMUserType, m map[string]auth.Credentials) error loadUser(ctx context.Context, user string, userType IAMUserType, m map[string]auth.Credentials) error
loadUsers(ctx context.Context, userType IAMUserType, m map[string]auth.Credentials) error loadUsers(ctx context.Context, userType IAMUserType, m map[string]auth.Credentials) error
loadGroup(group string, m map[string]GroupInfo) error loadGroup(ctx context.Context, group string, m map[string]GroupInfo) error
loadGroups(ctx context.Context, m map[string]GroupInfo) error loadGroups(ctx context.Context, m map[string]GroupInfo) error
loadMappedPolicy(name string, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error loadMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error
loadMappedPolicies(ctx context.Context, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error loadMappedPolicies(ctx context.Context, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error
loadAll(context.Context, *IAMSys) error loadAll(context.Context, *IAMSys) error
saveIAMConfig(item interface{}, path string) error saveIAMConfig(ctx context.Context, item interface{}, path string) error
loadIAMConfig(item interface{}, path string) error loadIAMConfig(ctx context.Context, item interface{}, path string) error
deleteIAMConfig(path string) error deleteIAMConfig(ctx context.Context, path string) error
savePolicyDoc(policyName string, p iampolicy.Policy) error savePolicyDoc(ctx context.Context, policyName string, p iampolicy.Policy) error
saveMappedPolicy(name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error
saveUserIdentity(name string, userType IAMUserType, u UserIdentity) error saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity) error
saveGroupInfo(group string, gi GroupInfo) error saveGroupInfo(ctx context.Context, group string, gi GroupInfo) error
deletePolicyDoc(policyName string) error deletePolicyDoc(ctx context.Context, policyName string) error
deleteMappedPolicy(name string, userType IAMUserType, isGroup bool) error deleteMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool) error
deleteUserIdentity(name string, userType IAMUserType) error deleteUserIdentity(ctx context.Context, name string, userType IAMUserType) error
deleteGroupInfo(name string) error deleteGroupInfo(ctx context.Context, name string) error
watch(context.Context, *IAMSys) watch(context.Context, *IAMSys)
} }
@ -289,7 +289,7 @@ func (sys *IAMSys) LoadGroup(objAPI ObjectLayer, group string) error {
sys.store.lock() sys.store.lock()
defer sys.store.unlock() defer sys.store.unlock()
err := sys.store.loadGroup(group, sys.iamGroupsMap) err := sys.store.loadGroup(context.Background(), group, sys.iamGroupsMap)
if err != nil && err != errNoSuchGroup { if err != nil && err != errNoSuchGroup {
return err return err
} }
@ -326,7 +326,7 @@ func (sys *IAMSys) LoadPolicy(objAPI ObjectLayer, policyName string) error {
defer sys.store.unlock() defer sys.store.unlock()
if globalEtcdClient == nil { if globalEtcdClient == nil {
return sys.store.loadPolicyDoc(policyName, sys.iamPolicyDocsMap) return sys.store.loadPolicyDoc(context.Background(), policyName, sys.iamPolicyDocsMap)
} }
// 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.
@ -346,9 +346,9 @@ func (sys *IAMSys) LoadPolicyMapping(objAPI ObjectLayer, userOrGroup string, isG
if globalEtcdClient == nil { if globalEtcdClient == nil {
var err error var err error
if isGroup { if isGroup {
err = sys.store.loadMappedPolicy(userOrGroup, regularUser, isGroup, sys.iamGroupPolicyMap) err = sys.store.loadMappedPolicy(context.Background(), userOrGroup, regularUser, isGroup, sys.iamGroupPolicyMap)
} else { } else {
err = sys.store.loadMappedPolicy(userOrGroup, regularUser, isGroup, sys.iamUserPolicyMap) err = sys.store.loadMappedPolicy(context.Background(), userOrGroup, regularUser, isGroup, sys.iamUserPolicyMap)
} }
// Ignore policy not mapped error // Ignore policy not mapped error
@ -370,11 +370,11 @@ func (sys *IAMSys) LoadUser(objAPI ObjectLayer, accessKey string, userType IAMUs
defer sys.store.unlock() defer sys.store.unlock()
if globalEtcdClient == nil { if globalEtcdClient == nil {
err := sys.store.loadUser(accessKey, userType, sys.iamUsersMap) err := sys.store.loadUser(context.Background(), accessKey, userType, sys.iamUsersMap)
if err != nil { if err != nil {
return err return err
} }
err = sys.store.loadMappedPolicy(accessKey, userType, false, sys.iamUserPolicyMap) err = sys.store.loadMappedPolicy(context.Background(), accessKey, userType, false, sys.iamUserPolicyMap)
// Ignore policy not mapped error // Ignore policy not mapped error
if err != nil && err != errNoSuchPolicy { if err != nil && err != errNoSuchPolicy {
return err return err
@ -386,7 +386,7 @@ func (sys *IAMSys) LoadUser(objAPI ObjectLayer, accessKey string, userType IAMUs
// LoadServiceAccount - reloads a specific service account from backend disks or etcd. // LoadServiceAccount - reloads a specific service account from backend disks or etcd.
func (sys *IAMSys) LoadServiceAccount(accessKey string) error { func (sys *IAMSys) LoadServiceAccount(accessKey string) error {
if sys == nil || sys.store == nil { if sys == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -394,7 +394,7 @@ func (sys *IAMSys) LoadServiceAccount(accessKey string) error {
defer sys.store.unlock() defer sys.store.unlock()
if globalEtcdClient == nil { if globalEtcdClient == nil {
err := sys.store.loadUser(accessKey, srvAccUser, sys.iamUsersMap) err := sys.store.loadUser(context.Background(), accessKey, srvAccUser, sys.iamUsersMap)
if err != nil { if err != nil {
return err return err
} }
@ -408,23 +408,21 @@ func (sys *IAMSys) doIAMConfigMigration(ctx context.Context) error {
return sys.store.migrateBackendFormat(ctx) return sys.store.migrateBackendFormat(ctx)
} }
// Init - initializes config system by reading entries from config/iam // InitStore initializes IAM stores
func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer) { func (sys *IAMSys) InitStore(objAPI ObjectLayer) {
if objAPI == nil {
logger.LogIf(ctx, errServerNotInitialized)
return
}
if globalEtcdClient == nil { if globalEtcdClient == nil {
sys.store = newIAMObjectStore(ctx, objAPI) sys.store = newIAMObjectStore(objAPI)
} else { } else {
sys.store = newIAMEtcdStore(ctx) sys.store = newIAMEtcdStore()
} }
if globalLDAPConfig.Enabled { if globalLDAPConfig.Enabled {
sys.EnableLDAPSys() sys.EnableLDAPSys()
} }
}
// Init - initializes config system by reading entries from config/iam
func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer) {
retryCtx, cancel := context.WithCancel(ctx) retryCtx, cancel := context.WithCancel(ctx)
// Indicate to our routine to exit cleanly upon return. // Indicate to our routine to exit cleanly upon return.
@ -507,8 +505,7 @@ func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer) {
// DeletePolicy - deletes a canned policy from backend or etcd. // DeletePolicy - deletes a canned policy from backend or etcd.
func (sys *IAMSys) DeletePolicy(policyName string) error { func (sys *IAMSys) DeletePolicy(policyName string) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -519,7 +516,7 @@ func (sys *IAMSys) DeletePolicy(policyName string) error {
sys.store.lock() sys.store.lock()
defer sys.store.unlock() defer sys.store.unlock()
err := sys.store.deletePolicyDoc(policyName) err := sys.store.deletePolicyDoc(context.Background(), policyName)
if err == errNoSuchPolicy { if err == errNoSuchPolicy {
// Ignore error if policy is already deleted. // Ignore error if policy is already deleted.
err = nil err = nil
@ -560,8 +557,7 @@ func (sys *IAMSys) DeletePolicy(policyName string) error {
// InfoPolicy - expands the canned policy into its JSON structure. // InfoPolicy - expands the canned policy into its JSON structure.
func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) { func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return iampolicy.Policy{}, errServerNotInitialized return iampolicy.Policy{}, errServerNotInitialized
} }
@ -578,8 +574,7 @@ func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) {
// ListPolicies - lists all canned policies. // ListPolicies - lists all canned policies.
func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) { func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -600,8 +595,7 @@ func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) {
// SetPolicy - sets a new name policy. // SetPolicy - sets a new name policy.
func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error { func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -612,7 +606,7 @@ func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error {
sys.store.lock() sys.store.lock()
defer sys.store.unlock() defer sys.store.unlock()
if err := sys.store.savePolicyDoc(policyName, p); err != nil { if err := sys.store.savePolicyDoc(context.Background(), policyName, p); err != nil {
return err return err
} }
@ -622,8 +616,7 @@ func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error {
// DeleteUser - delete user (only for long-term users not STS users). // DeleteUser - delete user (only for long-term users not STS users).
func (sys *IAMSys) DeleteUser(accessKey string) error { func (sys *IAMSys) DeleteUser(accessKey string) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -652,15 +645,15 @@ func (sys *IAMSys) DeleteUser(accessKey string) error {
for _, u := range sys.iamUsersMap { for _, u := range sys.iamUsersMap {
if u.IsServiceAccount() { if u.IsServiceAccount() {
if u.ParentUser == accessKey { if u.ParentUser == accessKey {
_ = sys.store.deleteUserIdentity(u.AccessKey, srvAccUser) _ = sys.store.deleteUserIdentity(context.Background(), u.AccessKey, srvAccUser)
delete(sys.iamUsersMap, u.AccessKey) delete(sys.iamUsersMap, u.AccessKey)
} }
} }
} }
// It is ok to ignore deletion error on the mapped policy // It is ok to ignore deletion error on the mapped policy
sys.store.deleteMappedPolicy(accessKey, regularUser, false) sys.store.deleteMappedPolicy(context.Background(), accessKey, regularUser, false)
err := sys.store.deleteUserIdentity(accessKey, regularUser) err := sys.store.deleteUserIdentity(context.Background(), accessKey, regularUser)
if err == errNoSuchUser { if err == errNoSuchUser {
// ignore if user is already deleted. // ignore if user is already deleted.
err = nil err = nil
@ -692,8 +685,7 @@ func (sys *IAMSys) currentPolicies(policyName string) string {
// SetTempUser - set temporary user credentials, these credentials have an expiry. // SetTempUser - set temporary user credentials, these credentials have an expiry.
func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyName string) error { func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyName string) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -724,7 +716,7 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa
return nil return nil
} }
if err := sys.store.saveMappedPolicy(accessKey, stsUser, false, mp); err != nil { if err := sys.store.saveMappedPolicy(context.Background(), accessKey, stsUser, false, mp); err != nil {
return err return err
} }
@ -732,7 +724,7 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa
} }
u := newUserIdentity(cred) u := newUserIdentity(cred)
if err := sys.store.saveUserIdentity(accessKey, stsUser, u); err != nil { if err := sys.store.saveUserIdentity(context.Background(), accessKey, stsUser, u); err != nil {
return err return err
} }
@ -742,8 +734,7 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa
// ListUsers - list all users. // ListUsers - list all users.
func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) { func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -779,8 +770,7 @@ func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) {
// IsTempUser - returns if given key is a temporary user. // IsTempUser - returns if given key is a temporary user.
func (sys *IAMSys) IsTempUser(name string) (bool, error) { func (sys *IAMSys) IsTempUser(name string) (bool, error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return false, errServerNotInitialized return false, errServerNotInitialized
} }
@ -797,8 +787,7 @@ func (sys *IAMSys) IsTempUser(name string) (bool, error) {
// IsServiceAccount - returns if given key is a service account // IsServiceAccount - returns if given key is a service account
func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) { func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return false, "", errServerNotInitialized return false, "", errServerNotInitialized
} }
@ -819,8 +808,7 @@ func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) {
// GetUserInfo - get info on a user. // GetUserInfo - get info on a user.
func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) { func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return u, errServerNotInitialized return u, errServerNotInitialized
} }
@ -865,8 +853,8 @@ func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) {
// SetUserStatus - sets current user status, supports disabled or enabled. // SetUserStatus - sets current user status, supports disabled or enabled.
func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus) error { func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus) error {
objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if sys == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -901,7 +889,7 @@ func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus)
}(), }(),
}) })
if err := sys.store.saveUserIdentity(accessKey, regularUser, uinfo); err != nil { if err := sys.store.saveUserIdentity(context.Background(), accessKey, regularUser, uinfo); err != nil {
return err return err
} }
@ -911,8 +899,8 @@ func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus)
// NewServiceAccount - create a new service account // NewServiceAccount - create a new service account
func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, sessionPolicy *iampolicy.Policy) (auth.Credentials, error) { func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, sessionPolicy *iampolicy.Policy) (auth.Credentials, error) {
objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if sys == nil {
return auth.Credentials{}, errServerNotInitialized return auth.Credentials{}, errServerNotInitialized
} }
@ -967,7 +955,7 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, ses
u := newUserIdentity(cred) u := newUserIdentity(cred)
if err := sys.store.saveUserIdentity(u.Credentials.AccessKey, srvAccUser, u); err != nil { if err := sys.store.saveUserIdentity(context.Background(), u.Credentials.AccessKey, srvAccUser, u); err != nil {
return auth.Credentials{}, err return auth.Credentials{}, err
} }
@ -978,8 +966,8 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, ses
// ListServiceAccounts - lists all services accounts associated to a specific user // ListServiceAccounts - lists all services accounts associated to a specific user
func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([]string, error) { func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([]string, error) {
objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if sys == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -1003,8 +991,8 @@ func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([
// GetServiceAccountParent - gets information about a service account // GetServiceAccountParent - gets information about a service account
func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string) (string, error) { func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string) (string, error) {
objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if sys == nil {
return "", errServerNotInitialized return "", errServerNotInitialized
} }
@ -1020,8 +1008,8 @@ func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string
// DeleteServiceAccount - delete a service account // DeleteServiceAccount - delete a service account
func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) error { func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) error {
objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if sys == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1034,7 +1022,7 @@ func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) e
} }
// It is ok to ignore deletion error on the mapped policy // It is ok to ignore deletion error on the mapped policy
err := sys.store.deleteUserIdentity(accessKey, srvAccUser) err := sys.store.deleteUserIdentity(context.Background(), accessKey, srvAccUser)
if err != nil { if err != nil {
// ignore if user is already deleted. // ignore if user is already deleted.
if err == errNoSuchUser { if err == errNoSuchUser {
@ -1049,8 +1037,8 @@ func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) e
// SetUser - set user credentials and policy. // SetUser - set user credentials and policy.
func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error { func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error {
objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if sys == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1072,7 +1060,7 @@ func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error {
return errIAMActionNotAllowed return errIAMActionNotAllowed
} }
if err := sys.store.saveUserIdentity(accessKey, regularUser, u); err != nil { if err := sys.store.saveUserIdentity(context.Background(), accessKey, regularUser, u); err != nil {
return err return err
} }
@ -1087,8 +1075,8 @@ func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error {
// SetUserSecretKey - sets user secret key // SetUserSecretKey - sets user secret key
func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error { func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error {
objectAPI := newObjectLayerFn()
if objectAPI == nil || sys == nil || sys.store == nil { if sys == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1106,7 +1094,7 @@ func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error {
cred.SecretKey = secretKey cred.SecretKey = secretKey
u := newUserIdentity(cred) u := newUserIdentity(cred)
if err := sys.store.saveUserIdentity(accessKey, regularUser, u); err != nil { if err := sys.store.saveUserIdentity(context.Background(), accessKey, regularUser, u); err != nil {
return err return err
} }
@ -1116,8 +1104,7 @@ func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error {
// GetUser - get user credentials // GetUser - get user credentials
func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) { func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return cred, false return cred, false
} }
@ -1128,34 +1115,37 @@ func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) {
sys.store.lock() sys.store.lock()
// If user is already found proceed. // If user is already found proceed.
if _, found := sys.iamUsersMap[accessKey]; !found { if _, found := sys.iamUsersMap[accessKey]; !found {
sys.store.loadUser(accessKey, regularUser, sys.iamUsersMap) sys.store.loadUser(context.Background(), accessKey, regularUser, sys.iamUsersMap)
if _, found = sys.iamUsersMap[accessKey]; found { if _, found = sys.iamUsersMap[accessKey]; found {
// found user, load its mapped policies // found user, load its mapped policies
sys.store.loadMappedPolicy(accessKey, regularUser, false, sys.iamUserPolicyMap) sys.store.loadMappedPolicy(context.Background(), accessKey, regularUser, false, sys.iamUserPolicyMap)
} else { } else {
sys.store.loadUser(accessKey, srvAccUser, sys.iamUsersMap) sys.store.loadUser(context.Background(), accessKey, srvAccUser, sys.iamUsersMap)
if svc, found := sys.iamUsersMap[accessKey]; found { if svc, found := sys.iamUsersMap[accessKey]; found {
// Found service account, load its parent user and its mapped policies. // Found service account, load its parent user and its mapped policies.
if sys.usersSysType == MinIOUsersSysType { if sys.usersSysType == MinIOUsersSysType {
sys.store.loadUser(svc.ParentUser, regularUser, sys.iamUsersMap) sys.store.loadUser(context.Background(), svc.ParentUser, regularUser, sys.iamUsersMap)
} }
sys.store.loadMappedPolicy(svc.ParentUser, regularUser, false, sys.iamUserPolicyMap) sys.store.loadMappedPolicy(context.Background(), svc.ParentUser, regularUser, false, sys.iamUserPolicyMap)
} else { } else {
// None found fall back to STS users. // None found fall back to STS users.
sys.store.loadUser(accessKey, stsUser, sys.iamUsersMap) sys.store.loadUser(context.Background(), accessKey, stsUser, sys.iamUsersMap)
if _, found = sys.iamUsersMap[accessKey]; found { if _, found = sys.iamUsersMap[accessKey]; found {
// STS user found, load its mapped policy. // STS user found, load its mapped policy.
sys.store.loadMappedPolicy(accessKey, stsUser, false, sys.iamUserPolicyMap) sys.store.loadMappedPolicy(context.Background(), accessKey, stsUser, false, sys.iamUserPolicyMap)
} }
} }
} }
} }
// Load associated policies if any. // Load associated policies if any.
for _, policy := range sys.iamUserPolicyMap[accessKey].toSlice() { for _, policy := range sys.iamUserPolicyMap[accessKey].toSlice() {
if _, found := sys.iamPolicyDocsMap[policy]; !found { if _, found := sys.iamPolicyDocsMap[policy]; !found {
sys.store.loadPolicyDoc(policy, sys.iamPolicyDocsMap) sys.store.loadPolicyDoc(context.Background(), policy, sys.iamPolicyDocsMap)
} }
} }
sys.buildUserGroupMemberships()
sys.store.unlock() sys.store.unlock()
} }
@ -1180,8 +1170,7 @@ func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) {
// AddUsersToGroup - adds users to a group, creating the group if // AddUsersToGroup - adds users to a group, creating the group if
// needed. No error if user(s) already are in the group. // needed. No error if user(s) already are in the group.
func (sys *IAMSys) AddUsersToGroup(group string, members []string) error { func (sys *IAMSys) AddUsersToGroup(group string, members []string) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1218,7 +1207,7 @@ func (sys *IAMSys) AddUsersToGroup(group string, members []string) error {
gi.Members = uniqMembers gi.Members = uniqMembers
} }
if err := sys.store.saveGroupInfo(group, gi); err != nil { if err := sys.store.saveGroupInfo(context.Background(), group, gi); err != nil {
return err return err
} }
@ -1241,8 +1230,7 @@ func (sys *IAMSys) AddUsersToGroup(group string, members []string) error {
// RemoveUsersFromGroup - remove users from group. If no users are // RemoveUsersFromGroup - remove users from group. If no users are
// given, and the group is empty, deletes the group as well. // given, and the group is empty, deletes the group as well.
func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error { func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1283,10 +1271,10 @@ func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
// Remove the group from storage. First delete the // Remove the group from storage. First delete the
// mapped policy. No-mapped-policy case is ignored. // mapped policy. No-mapped-policy case is ignored.
if err := sys.store.deleteMappedPolicy(group, regularUser, true); err != nil && err != errNoSuchPolicy { if err := sys.store.deleteMappedPolicy(context.Background(), group, regularUser, true); err != nil && err != errNoSuchPolicy {
return err return err
} }
if err := sys.store.deleteGroupInfo(group); err != nil && err != errNoSuchGroup { if err := sys.store.deleteGroupInfo(context.Background(), group); err != nil && err != errNoSuchGroup {
return err return err
} }
@ -1301,7 +1289,7 @@ func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
d := set.CreateStringSet(members...) d := set.CreateStringSet(members...)
gi.Members = s.Difference(d).ToSlice() gi.Members = s.Difference(d).ToSlice()
err := sys.store.saveGroupInfo(group, gi) err := sys.store.saveGroupInfo(context.Background(), group, gi)
if err != nil { if err != nil {
return err return err
} }
@ -1322,8 +1310,7 @@ func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
// SetGroupStatus - enable/disabled a group // SetGroupStatus - enable/disabled a group
func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error { func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1349,7 +1336,7 @@ func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error {
gi.Status = statusDisabled gi.Status = statusDisabled
} }
if err := sys.store.saveGroupInfo(group, gi); err != nil { if err := sys.store.saveGroupInfo(context.Background(), group, gi); err != nil {
return err return err
} }
sys.iamGroupsMap[group] = gi sys.iamGroupsMap[group] = gi
@ -1358,8 +1345,7 @@ func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error {
// GetGroupDescription - builds up group description // GetGroupDescription - builds up group description
func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err error) { func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return gd, errServerNotInitialized return gd, errServerNotInitialized
} }
@ -1399,8 +1385,7 @@ func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err e
// ListGroups - lists groups. // ListGroups - lists groups.
func (sys *IAMSys) ListGroups() (r []string, err error) { func (sys *IAMSys) ListGroups() (r []string, err error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return r, errServerNotInitialized return r, errServerNotInitialized
} }
@ -1423,8 +1408,7 @@ func (sys *IAMSys) ListGroups() (r []string, err error) {
// PolicyDBSet - sets a policy for a user or group in the PolicyDB. // PolicyDBSet - sets a policy for a user or group in the PolicyDB.
func (sys *IAMSys) PolicyDBSet(name, policy string, isGroup bool) error { func (sys *IAMSys) PolicyDBSet(name, policy string, isGroup bool) error {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return errServerNotInitialized return errServerNotInitialized
} }
@ -1455,7 +1439,7 @@ func (sys *IAMSys) policyDBSet(name, policyName string, userType IAMUserType, is
// Handle policy mapping removal // Handle policy mapping removal
if policyName == "" { if policyName == "" {
if err := sys.store.deleteMappedPolicy(name, userType, isGroup); err != nil && err != errNoSuchPolicy { if err := sys.store.deleteMappedPolicy(context.Background(), name, userType, isGroup); err != nil && err != errNoSuchPolicy {
return err return err
} }
if !isGroup { if !isGroup {
@ -1475,7 +1459,7 @@ func (sys *IAMSys) policyDBSet(name, policyName string, userType IAMUserType, is
} }
// Handle policy mapping set/update // Handle policy mapping set/update
if err := sys.store.saveMappedPolicy(name, userType, isGroup, mp); err != nil { if err := sys.store.saveMappedPolicy(context.Background(), name, userType, isGroup, mp); err != nil {
return err return err
} }
if !isGroup { if !isGroup {
@ -1490,8 +1474,7 @@ func (sys *IAMSys) policyDBSet(name, policyName string, userType IAMUserType, is
// be a member of multiple groups, this function returns an array of // be a member of multiple groups, this function returns an array of
// applicable policies (each group is mapped to at most one policy). // applicable policies (each group is mapped to at most one policy).
func (sys *IAMSys) PolicyDBGet(name string, isGroup bool) ([]string, error) { func (sys *IAMSys) PolicyDBGet(name string, isGroup bool) ([]string, error) {
objectAPI := newObjectLayerFn() if sys == nil {
if objectAPI == nil || sys == nil || sys.store == nil {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }

@ -104,9 +104,6 @@ func webTokenCallback(claims *xjwt.MapClaims) ([]byte, error) {
if claims.AccessKey == globalActiveCred.AccessKey { if claims.AccessKey == globalActiveCred.AccessKey {
return []byte(globalActiveCred.SecretKey), nil return []byte(globalActiveCred.SecretKey), nil
} }
if globalIAMSys == nil {
return nil, errInvalidAccessKeyID
}
ok, err := globalIAMSys.IsTempUser(claims.AccessKey) ok, err := globalIAMSys.IsTempUser(claims.AccessKey)
if err != nil { if err != nil {
if err == errNoSuchUser { if err == errNoSuchUser {

@ -71,11 +71,6 @@ func (s *peerRESTServer) DeletePolicyHandler(w http.ResponseWriter, r *http.Requ
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
policyName := vars[peerRESTPolicy] policyName := vars[peerRESTPolicy]
if policyName == "" { if policyName == "" {
@ -104,11 +99,6 @@ func (s *peerRESTServer) LoadPolicyHandler(w http.ResponseWriter, r *http.Reques
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
policyName := vars[peerRESTPolicy] policyName := vars[peerRESTPolicy]
if policyName == "" { if policyName == "" {
@ -137,11 +127,6 @@ func (s *peerRESTServer) LoadPolicyMappingHandler(w http.ResponseWriter, r *http
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
userOrGroup := vars[peerRESTUserOrGroup] userOrGroup := vars[peerRESTUserOrGroup]
if userOrGroup == "" { if userOrGroup == "" {
@ -171,11 +156,6 @@ func (s *peerRESTServer) DeleteServiceAccountHandler(w http.ResponseWriter, r *h
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
accessKey := vars[peerRESTUser] accessKey := vars[peerRESTUser]
if accessKey == "" { if accessKey == "" {
@ -204,11 +184,6 @@ func (s *peerRESTServer) LoadServiceAccountHandler(w http.ResponseWriter, r *htt
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
accessKey := vars[peerRESTUser] accessKey := vars[peerRESTUser]
if accessKey == "" { if accessKey == "" {
@ -237,11 +212,6 @@ func (s *peerRESTServer) DeleteUserHandler(w http.ResponseWriter, r *http.Reques
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
accessKey := vars[peerRESTUser] accessKey := vars[peerRESTUser]
if accessKey == "" { if accessKey == "" {
@ -270,11 +240,6 @@ func (s *peerRESTServer) LoadUserHandler(w http.ResponseWriter, r *http.Request)
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
accessKey := vars[peerRESTUser] accessKey := vars[peerRESTUser]
if accessKey == "" { if accessKey == "" {
@ -314,11 +279,6 @@ func (s *peerRESTServer) LoadGroupHandler(w http.ResponseWriter, r *http.Request
return return
} }
if globalIAMSys == nil {
s.writeErrorResponse(w, errServerNotInitialized)
return
}
vars := mux.Vars(r) vars := mux.Vars(r)
group := vars[peerRESTGroup] group := vars[peerRESTGroup]
err := globalIAMSys.LoadGroup(objAPI, group) err := globalIAMSys.LoadGroup(objAPI, group)

@ -327,9 +327,12 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
return fmt.Errorf("Unable to initialize config system: %w", err) return fmt.Errorf("Unable to initialize config system: %w", err)
} }
// Any other config errors we simply print a message and proceed forward. // Any other config errors we simply print a message and proceed forward.
logger.LogIf(ctx, err) logger.LogIf(ctx, fmt.Errorf("Unable to initialize config, some features may be missing %w", err))
} }
// Initialize IAM store
globalIAMSys.InitStore(newObject)
// Populate existing buckets to the etcd backend // Populate existing buckets to the etcd backend
if globalDNSConfig != nil { if globalDNSConfig != nil {
// Background this operation. // Background this operation.
@ -385,6 +388,9 @@ func serverMain(ctx *cli.Context) {
// Initialize all help // Initialize all help
initHelp() initHelp()
// Initialize all sub-systems
newAllSubsystems()
var err error var err error
globalProxyEndpoints, err = GetProxyEndpoints(globalEndpoints) globalProxyEndpoints, err = GetProxyEndpoints(globalEndpoints)
logger.FatalIf(err, "Invalid command line arguments") logger.FatalIf(err, "Invalid command line arguments")
@ -427,9 +433,6 @@ func serverMain(ctx *cli.Context) {
globalReplicationState = newReplicationState() globalReplicationState = newReplicationState()
} }
// Initialize all sub-systems
newAllSubsystems()
// Configure server. // Configure server.
handler, err := configureServerHandler(globalEndpoints) handler, err := configureServerHandler(globalEndpoints)
if err != nil { if err != nil {
@ -476,11 +479,6 @@ func serverMain(ctx *cli.Context) {
logger.SetDeploymentID(globalDeploymentID) logger.SetDeploymentID(globalDeploymentID)
// Once endpoints are finalized, initialize the new object api in safe mode.
globalObjLayerMutex.Lock()
globalObjectAPI = newObject
globalObjLayerMutex.Unlock()
go initDataCrawler(GlobalContext, newObject) go initDataCrawler(GlobalContext, newObject)
// Enable background operations for erasure coding // Enable background operations for erasure coding
@ -503,6 +501,11 @@ func serverMain(ctx *cli.Context) {
} }
} }
// Once the config is fully loaded, initialize the new object layer.
globalObjLayerMutex.Lock()
globalObjectAPI = newObject
globalObjLayerMutex.Unlock()
// Initialize users credentials and policies in background right after config has initialized. // Initialize users credentials and policies in background right after config has initialized.
go globalIAMSys.Init(GlobalContext, newObject) go globalIAMSys.Init(GlobalContext, newObject)

@ -124,9 +124,6 @@ func checkKeyValid(accessKey string) (auth.Credentials, bool, APIErrorCode) {
var owner = true var owner = true
var cred = globalActiveCred var cred = globalActiveCred
if cred.AccessKey != accessKey { if cred.AccessKey != accessKey {
if globalIAMSys == nil {
return cred, false, ErrInvalidAccessKeyID
}
// Check if the access key is part of users credentials. // Check if the access key is part of users credentials.
var ok bool var ok bool
if cred, ok = globalIAMSys.GetUser(accessKey); !ok { if cred, ok = globalIAMSys.GetUser(accessKey); !ok {

Loading…
Cancel
Save