mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
fix: IAM import for LDAP should replace mappings (#19607)
Existing IAM import logic for LDAP creates new mappings when the normalized form of the mapping key differs from the existing mapping key in storage. This change effectively replaces the existing mapping key by first deleting it and then recreating with the normalized form of the mapping key. For e.g. if an older deployment had a policy mapped to a user DN - `UID=alice1,OU=people,OU=hwengg,DC=min,DC=io` instead of adding a mapping for the normalized form - `uid=alice1,ou=people,ou=hwengg,dc=min,dc=io` we should replace the existing mapping. This ensures that duplicates mappings won't remain after the import. Some additional cleanup cases are also covered. If there are multiple mappings for the name normalized key such as: `UID=alice1,OU=people,OU=hwengg,DC=min,DC=io` `uid=alice1,ou=people,ou=hwengg,DC=min,DC=io` `uid=alice1,ou=people,ou=hwengg,dc=min,dc=io` we check if the list of policies mapped to all these keys are exactly the same, and if so remove all of them and create a single mapping with the normalized key. However, if the policies mapped to such keys differ, the import operation returns an error as the server cannot automatically pick the "right" list of policies to map.
This commit is contained in:
committed by
GitHub
parent
1d03bea965
commit
3212d0c8cd
44
cmd/iam.go
44
cmd/iam.go
@@ -1559,6 +1559,37 @@ func (sys *IAMSys) NormalizeLDAPAccessKeypairs(ctx context.Context, accessKeyMap
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sys *IAMSys) getStoredLDAPPolicyMappingKeys(ctx context.Context, isGroup bool) set.StringSet {
|
||||
entityKeysInStorage := set.NewStringSet()
|
||||
if iamOS, ok := sys.store.IAMStorageAPI.(*IAMObjectStore); ok {
|
||||
// Load existing mapping keys from the cached listing for
|
||||
// `IAMObjectStore`.
|
||||
iamFilesListing := iamOS.cachedIAMListing.Load().(map[string][]string)
|
||||
listKey := policyDBSTSUsersListKey
|
||||
if isGroup {
|
||||
listKey = policyDBGroupsListKey
|
||||
}
|
||||
for _, item := range iamFilesListing[listKey] {
|
||||
stsUserName := strings.TrimSuffix(item, ".json")
|
||||
entityKeysInStorage.Add(stsUserName)
|
||||
}
|
||||
} else {
|
||||
// For non-iam object store, we copy the mapping keys from the cache.
|
||||
cache := sys.store.rlock()
|
||||
defer sys.store.runlock()
|
||||
cachedPolicyMap := cache.iamSTSPolicyMap
|
||||
if isGroup {
|
||||
cachedPolicyMap = cache.iamGroupPolicyMap
|
||||
}
|
||||
cachedPolicyMap.Range(func(k string, v MappedPolicy) bool {
|
||||
entityKeysInStorage.Add(k)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
return entityKeysInStorage
|
||||
}
|
||||
|
||||
// NormalizeLDAPMappingImport - validates the LDAP policy mappings. Keys in the
|
||||
// given map may not correspond to LDAP DNs - these keys are ignored.
|
||||
//
|
||||
@@ -1615,6 +1646,8 @@ func (sys *IAMSys) NormalizeLDAPMappingImport(ctx context.Context, isGroup bool,
|
||||
return fmt.Errorf("errors validating LDAP DN: %w", errors.Join(collectedErrors...))
|
||||
}
|
||||
|
||||
entityKeysInStorage := sys.getStoredLDAPPolicyMappingKeys(ctx, isGroup)
|
||||
|
||||
for normKey, origKeys := range normalizedDNKeysMap {
|
||||
if len(origKeys) > 1 {
|
||||
// If there are multiple DN keys that normalize to the same value,
|
||||
@@ -1639,6 +1672,12 @@ func (sys *IAMSys) NormalizeLDAPMappingImport(ctx context.Context, isGroup bool,
|
||||
// ones from the map.
|
||||
for i := 1; i < len(origKeys); i++ {
|
||||
delete(policyMap, origKeys[i])
|
||||
|
||||
// Remove the mapping from storage by setting the policy to "".
|
||||
if entityKeysInStorage.Contains(origKeys[i]) {
|
||||
// Ignore any deletion error.
|
||||
_, _ = sys.PolicyDBSet(ctx, origKeys[i], "", stsUser, isGroup)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1648,6 +1687,11 @@ func (sys *IAMSys) NormalizeLDAPMappingImport(ctx context.Context, isGroup bool,
|
||||
mappingValue := policyMap[origKeys[0]]
|
||||
delete(policyMap, origKeys[0])
|
||||
policyMap[normKey] = mappingValue
|
||||
// Remove the mapping from storage by setting the policy to "".
|
||||
if entityKeysInStorage.Contains(origKeys[0]) {
|
||||
// Ignore any deletion error.
|
||||
_, _ = sys.PolicyDBSet(ctx, origKeys[0], "", stsUser, isGroup)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user