fix: heal service accounts for LDAP users in site replication (#15785)

This commit is contained in:
Harshavardhana 2022-10-04 10:41:47 -07:00 committed by GitHub
parent be0d2537b7
commit 538aeef27a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 37 deletions

View File

@ -135,7 +135,7 @@ func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) {
// Add ldap users which have mapped policies if in LDAP mode // Add ldap users which have mapped policies if in LDAP mode
// FIXME(vadmeste): move this to policy info in the future // FIXME(vadmeste): move this to policy info in the future
ldapUsers, err := globalIAMSys.ListLDAPUsers() ldapUsers, err := globalIAMSys.ListLDAPUsers(ctx)
if err != nil && err != errIAMActionNotAllowed { if err != nil && err != errIAMActionNotAllowed {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return return

View File

@ -774,7 +774,7 @@ func (sys *IAMSys) ListUsers(ctx context.Context) (map[string]madmin.UserInfo, e
} }
// ListLDAPUsers - list LDAP users which has // ListLDAPUsers - list LDAP users which has
func (sys *IAMSys) ListLDAPUsers() (map[string]madmin.UserInfo, error) { func (sys *IAMSys) ListLDAPUsers(ctx context.Context) (map[string]madmin.UserInfo, error) {
if !sys.Initialized() { if !sys.Initialized() {
return nil, errServerNotInitialized return nil, errServerNotInitialized
} }
@ -783,8 +783,8 @@ func (sys *IAMSys) ListLDAPUsers() (map[string]madmin.UserInfo, error) {
return nil, errIAMActionNotAllowed return nil, errIAMActionNotAllowed
} }
<-sys.configLoaded select {
case <-sys.configLoaded:
ldapUsers := make(map[string]madmin.UserInfo) ldapUsers := make(map[string]madmin.UserInfo)
for user, policy := range sys.store.GetUsersWithMappedPolicies() { for user, policy := range sys.store.GetUsersWithMappedPolicies() {
ldapUsers[user] = madmin.UserInfo{ ldapUsers[user] = madmin.UserInfo{
@ -793,6 +793,9 @@ func (sys *IAMSys) ListLDAPUsers() (map[string]madmin.UserInfo, error) {
} }
} }
return ldapUsers, nil return ldapUsers, nil
case <-ctx.Done():
return nil, ctx.Err()
}
} }
// IsTempUser - returns if given key is a temporary user. // IsTempUser - returns if given key is a temporary user.

View File

@ -3341,6 +3341,12 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
if usrErr != nil { if usrErr != nil {
return info, errSRBackendIssue(usrErr) return info, errSRBackendIssue(usrErr)
} }
globalIAMSys.store.rlock()
svcErr := globalIAMSys.store.loadMappedPolicies(ctx, svcUser, false, userPolicyMap)
globalIAMSys.store.runlock()
if svcErr != nil {
return info, errSRBackendIssue(svcErr)
}
} }
info.UserPolicies = make(map[string]madmin.SRPolicyMapping, len(userPolicyMap)) info.UserPolicies = make(map[string]madmin.SRPolicyMapping, len(userPolicyMap))
for user, mp := range userPolicyMap { for user, mp := range userPolicyMap {
@ -3357,33 +3363,42 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
info.UserInfoMap[opts.EntityValue] = ui info.UserInfoMap[opts.EntityValue] = ui
} }
} else { } else {
// get users/group info on local. userAccounts := make(map[string]UserIdentity)
userInfoMap, err := globalIAMSys.ListUsers(ctx) globalIAMSys.store.rlock()
if err != nil { uerr := globalIAMSys.store.loadUsers(ctx, regUser, userAccounts)
return info, errSRBackendIssue(err) globalIAMSys.store.runlock()
if uerr != nil {
return info, errSRBackendIssue(uerr)
} }
for user, ui := range userInfoMap {
info.UserInfoMap[user] = ui globalIAMSys.store.rlock()
svcAccts, err := globalIAMSys.ListServiceAccounts(ctx, user) serr := globalIAMSys.store.loadUsers(ctx, svcUser, userAccounts)
if err != nil { globalIAMSys.store.runlock()
return info, errSRBackendIssue(err) if serr != nil {
return info, errSRBackendIssue(serr)
} }
for _, svcAcct := range svcAccts {
// report all non-root user accounts for syncing globalIAMSys.store.rlock()
if svcAcct.ParentUser != "" && svcAcct.ParentUser != globalActiveCred.AccessKey { terr := globalIAMSys.store.loadUsers(ctx, stsUser, userAccounts)
info.UserInfoMap[svcAcct.AccessKey] = madmin.UserInfo{ globalIAMSys.store.runlock()
Status: madmin.AccountStatus(svcAcct.Status), if terr != nil {
return info, errSRBackendIssue(terr)
} }
for k, v := range userAccounts {
if k == siteReplicatorSvcAcc {
// skip the site replicate svc account as it is
// already replicated.
continue
} }
if v.Credentials.ParentUser != "" && v.Credentials.ParentUser == globalActiveCred.AccessKey {
// skip all root user service accounts.
continue
} }
tempAccts, err := globalIAMSys.ListTempAccounts(ctx, user)
if err != nil { info.UserInfoMap[k] = madmin.UserInfo{
return info, errSRBackendIssue(err) Status: madmin.AccountStatus(v.Credentials.Status),
}
for _, tempAcct := range tempAccts {
info.UserInfoMap[tempAcct.Credentials.AccessKey] = madmin.UserInfo{
Status: madmin.AccountStatus(tempAcct.Credentials.Status),
}
} }
} }
} }
@ -4387,7 +4402,6 @@ func (c *SiteReplicationSys) healIAMSystem(ctx context.Context, objAPI ObjectLay
for policy := range info.PolicyStats { for policy := range info.PolicyStats {
c.healPolicies(ctx, objAPI, policy, info) c.healPolicies(ctx, objAPI, policy, info)
} }
for user := range info.UserStats { for user := range info.UserStats {
c.healUsers(ctx, objAPI, user, info) c.healUsers(ctx, objAPI, user, info)
} }
@ -4581,7 +4595,8 @@ func (c *SiteReplicationSys) healGroupPolicies(ctx context.Context, objAPI Objec
return nil return nil
} }
// heal user accounts of local users that are present on this site, provided current cluster has the most recent update. // heal all users and their service accounts that are present on this site,
// provided current cluster has the most recent update.
func (c *SiteReplicationSys) healUsers(ctx context.Context, objAPI ObjectLayer, user string, info srStatusInfo) error { func (c *SiteReplicationSys) healUsers(ctx context.Context, objAPI ObjectLayer, user string, info srStatusInfo) error {
// create user if missing; fix user policy mapping if missing // create user if missing; fix user policy mapping if missing
us := info.UserStats[user] us := info.UserStats[user]
@ -4632,7 +4647,6 @@ func (c *SiteReplicationSys) healUsers(ctx context.Context, objAPI ObjectLayer,
continue continue
} }
creds := u.Credentials creds := u.Credentials
// heal only the user accounts that are local users
if creds.IsServiceAccount() { if creds.IsServiceAccount() {
claims, err := globalIAMSys.GetClaimsForSvcAcc(ctx, creds.AccessKey) claims, err := globalIAMSys.GetClaimsForSvcAcc(ctx, creds.AccessKey)
if err != nil { if err != nil {