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.
This commit is contained in:
Harshavardhana 2020-10-19 09:54:40 -07:00 committed by GitHub
parent c107728676
commit b07df5cae1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 226 additions and 281 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -327,9 +327,12 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
return fmt.Errorf("Unable to initialize config system: %w", err)
}
// 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
if globalDNSConfig != nil {
// Background this operation.
@ -385,6 +388,9 @@ func serverMain(ctx *cli.Context) {
// Initialize all help
initHelp()
// Initialize all sub-systems
newAllSubsystems()
var err error
globalProxyEndpoints, err = GetProxyEndpoints(globalEndpoints)
logger.FatalIf(err, "Invalid command line arguments")
@ -427,9 +433,6 @@ func serverMain(ctx *cli.Context) {
globalReplicationState = newReplicationState()
}
// Initialize all sub-systems
newAllSubsystems()
// Configure server.
handler, err := configureServerHandler(globalEndpoints)
if err != nil {
@ -476,11 +479,6 @@ func serverMain(ctx *cli.Context) {
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)
// 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.
go globalIAMSys.Init(GlobalContext, newObject)

View File

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