| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-03-28 09:48:01 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 	"path" | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2020-07-18 08:41:29 +08:00
										 |  |  | 	"unicode/utf8" | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 17:02:32 +08:00
										 |  |  | 	jsoniter "github.com/json-iterator/go" | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	"github.com/minio/minio/internal/config" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/kms" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // IAMObjectStore implements IAMStorageAPI
 | 
					
						
							|  |  |  | type IAMObjectStore struct { | 
					
						
							| 
									
										
										
										
											2021-11-04 10:47:49 +08:00
										 |  |  | 	// Protect access to storage within the current server.
 | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	sync.RWMutex | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 10:47:49 +08:00
										 |  |  | 	*iamCache | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	usersSysType UsersSysType | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	objAPI ObjectLayer | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 10:47:49 +08:00
										 |  |  | func newIAMObjectStore(objAPI ObjectLayer, usersSysType UsersSysType) *IAMObjectStore { | 
					
						
							|  |  |  | 	return &IAMObjectStore{ | 
					
						
							|  |  |  | 		iamCache:     newIamCache(), | 
					
						
							|  |  |  | 		objAPI:       objAPI, | 
					
						
							|  |  |  | 		usersSysType: usersSysType, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (iamOS *IAMObjectStore) rlock() *iamCache { | 
					
						
							|  |  |  | 	iamOS.RLock() | 
					
						
							|  |  |  | 	return iamOS.iamCache | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (iamOS *IAMObjectStore) runlock() { | 
					
						
							|  |  |  | 	iamOS.RUnlock() | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 10:47:49 +08:00
										 |  |  | func (iamOS *IAMObjectStore) lock() *iamCache { | 
					
						
							| 
									
										
										
										
											2020-04-08 05:26:39 +08:00
										 |  |  | 	iamOS.Lock() | 
					
						
							| 
									
										
										
										
											2021-11-04 10:47:49 +08:00
										 |  |  | 	return iamOS.iamCache | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-08 05:26:39 +08:00
										 |  |  | func (iamOS *IAMObjectStore) unlock() { | 
					
						
							|  |  |  | 	iamOS.Unlock() | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 10:47:49 +08:00
										 |  |  | func (iamOS *IAMObjectStore) getUsersSysType() UsersSysType { | 
					
						
							|  |  |  | 	return iamOS.usersSysType | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 23:45:30 +08:00
										 |  |  | func (iamOS *IAMObjectStore) saveIAMConfig(ctx context.Context, item interface{}, objPath string, opts ...options) error { | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | 	json := jsoniter.ConfigCompatibleWithStandardLibrary | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	data, err := json.Marshal(item) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-22 23:45:30 +08:00
										 |  |  | 	if GlobalKMS != nil { | 
					
						
							|  |  |  | 		data, err = config.EncryptBytes(GlobalKMS, data, kms.Context{ | 
					
						
							|  |  |  | 			minioMetaBucket: path.Join(minioMetaBucket, objPath), | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2019-11-02 06:53:16 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-22 23:45:30 +08:00
										 |  |  | 	return saveConfig(ctx, iamOS.objAPI, objPath, data) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadIAMConfigBytesWithMetadata(ctx context.Context, objPath string) ([]byte, ObjectInfo, error) { | 
					
						
							|  |  |  | 	data, meta, err := readConfigWithMetadata(ctx, iamOS.objAPI, objPath) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | 		return nil, meta, err | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-19 06:19:20 +08:00
										 |  |  | 	if !utf8.Valid(data) && GlobalKMS != nil { | 
					
						
							|  |  |  | 		data, err = config.DecryptBytes(GlobalKMS, data, kms.Context{ | 
					
						
							|  |  |  | 			minioMetaBucket: path.Join(minioMetaBucket, objPath), | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | 			return nil, meta, err | 
					
						
							| 
									
										
										
										
											2019-11-02 06:53:16 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | 	return data, meta, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (iamOS *IAMObjectStore) loadIAMConfig(ctx context.Context, item interface{}, objPath string) error { | 
					
						
							|  |  |  | 	data, _, err := iamOS.loadIAMConfigBytesWithMetadata(ctx, objPath) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | 	json := jsoniter.ConfigCompatibleWithStandardLibrary | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	return json.Unmarshal(data, item) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) deleteIAMConfig(ctx context.Context, path string) error { | 
					
						
							|  |  |  | 	return deleteConfig(ctx, iamOS.objAPI, path) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadPolicyDoc(ctx context.Context, policy string, m map[string]PolicyDoc) error { | 
					
						
							|  |  |  | 	data, objInfo, err := iamOS.loadIAMConfigBytesWithMetadata(ctx, getPolicyDocPath(policy)) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 		if err == errConfigNotFound { | 
					
						
							|  |  |  | 			return errNoSuchPolicy | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var p PolicyDoc | 
					
						
							|  |  |  | 	err = p.parseJSON(data) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if p.Version == 0 { | 
					
						
							|  |  |  | 		// This means that policy was in the old version (without any
 | 
					
						
							|  |  |  | 		// timestamp info). We fetch the mod time of the file and save
 | 
					
						
							|  |  |  | 		// that as create and update date.
 | 
					
						
							|  |  |  | 		p.CreateDate = objInfo.ModTime | 
					
						
							|  |  |  | 		p.UpdateDate = objInfo.ModTime | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	m[policy] = p | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadPolicyDocs(ctx context.Context, m map[string]PolicyDoc) error { | 
					
						
							| 
									
										
										
										
											2022-08-05 04:20:43 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(ctx) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 	for item := range listIAMConfigItems(ctx, iamOS.objAPI, iamConfigPoliciesPrefix) { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		if item.Err != nil { | 
					
						
							|  |  |  | 			return item.Err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 		policyName := path.Dir(item.Item) | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 		if err := iamOS.loadPolicyDoc(ctx, policyName, m); err != nil && err != errNoSuchPolicy { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-02 04:19:13 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadUser(ctx context.Context, user string, userType IAMUserType, m map[string]UserIdentity) error { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	var u UserIdentity | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 	err := iamOS.loadIAMConfig(ctx, &u, getUserIdentityPath(user, userType)) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 		if err == errConfigNotFound { | 
					
						
							|  |  |  | 			return errNoSuchUser | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if u.Credentials.IsExpired() { | 
					
						
							|  |  |  | 		// Delete expired identity - ignoring errors here.
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 		iamOS.deleteIAMConfig(ctx, getUserIdentityPath(user, userType)) | 
					
						
							|  |  |  | 		iamOS.deleteIAMConfig(ctx, getMappedPolicyPath(user, userType, false)) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if u.Credentials.AccessKey == "" { | 
					
						
							|  |  |  | 		u.Credentials.AccessKey = user | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-08-06 04:08:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-02 04:19:13 +08:00
										 |  |  | 	m[user] = u | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-02 04:19:13 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadUsers(ctx context.Context, userType IAMUserType, m map[string]UserIdentity) error { | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 	var basePrefix string | 
					
						
							|  |  |  | 	switch userType { | 
					
						
							| 
									
										
										
										
											2021-07-10 02:17:21 +08:00
										 |  |  | 	case svcUser: | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 		basePrefix = iamConfigServiceAccountsPrefix | 
					
						
							|  |  |  | 	case stsUser: | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		basePrefix = iamConfigSTSPrefix | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		basePrefix = iamConfigUsersPrefix | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 04:20:43 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(ctx) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 	for item := range listIAMConfigItems(ctx, iamOS.objAPI, basePrefix) { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		if item.Err != nil { | 
					
						
							|  |  |  | 			return item.Err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 		userName := path.Dir(item.Item) | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 		if err := iamOS.loadUser(ctx, userName, userType, m); err != nil && err != errNoSuchUser { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadGroup(ctx context.Context, group string, m map[string]GroupInfo) error { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	var g GroupInfo | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 	err := iamOS.loadIAMConfig(ctx, &g, getGroupInfoPath(group)) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 		if err == errConfigNotFound { | 
					
						
							|  |  |  | 			return errNoSuchGroup | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	m[group] = g | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-08 05:26:39 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadGroups(ctx context.Context, m map[string]GroupInfo) error { | 
					
						
							| 
									
										
										
										
											2022-08-05 04:20:43 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(ctx) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 	for item := range listIAMConfigItems(ctx, iamOS.objAPI, iamConfigGroupsPrefix) { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		if item.Err != nil { | 
					
						
							|  |  |  | 			return item.Err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 		group := path.Dir(item.Item) | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 		if err := iamOS.loadGroup(ctx, group, m); err != nil && err != errNoSuchGroup { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | 	m map[string]MappedPolicy, | 
					
						
							|  |  |  | ) error { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	var p MappedPolicy | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 	err := iamOS.loadIAMConfig(ctx, &p, getMappedPolicyPath(name, userType, isGroup)) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 		if err == errConfigNotFound { | 
					
						
							|  |  |  | 			return errNoSuchPolicy | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	m[name] = p | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-08 05:26:39 +08:00
										 |  |  | func (iamOS *IAMObjectStore) loadMappedPolicies(ctx context.Context, userType IAMUserType, isGroup bool, m map[string]MappedPolicy) error { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	var basePath string | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 	if isGroup { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		basePath = iamConfigPolicyDBGroupsPrefix | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		switch userType { | 
					
						
							| 
									
										
										
										
											2021-07-10 02:17:21 +08:00
										 |  |  | 		case svcUser: | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 			basePath = iamConfigPolicyDBServiceAccountsPrefix | 
					
						
							|  |  |  | 		case stsUser: | 
					
						
							|  |  |  | 			basePath = iamConfigPolicyDBSTSUsersPrefix | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			basePath = iamConfigPolicyDBUsersPrefix | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-08-05 04:20:43 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(ctx) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 	for item := range listIAMConfigItems(ctx, iamOS.objAPI, basePath) { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 		if item.Err != nil { | 
					
						
							|  |  |  | 			return item.Err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		policyFile := item.Item | 
					
						
							|  |  |  | 		userOrGroupName := strings.TrimSuffix(policyFile, ".json") | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 		if err := iamOS.loadMappedPolicy(ctx, userOrGroupName, userType, isGroup, m); err != nil && err != errNoSuchPolicy { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-28 09:48:01 +08:00
										 |  |  | var ( | 
					
						
							| 
									
										
										
										
											2022-04-16 03:12:45 +08:00
										 |  |  | 	usersListKey                   = "users/" | 
					
						
							|  |  |  | 	svcAccListKey                  = "service-accounts/" | 
					
						
							|  |  |  | 	groupsListKey                  = "groups/" | 
					
						
							|  |  |  | 	policiesListKey                = "policies/" | 
					
						
							|  |  |  | 	stsListKey                     = "sts/" | 
					
						
							|  |  |  | 	policyDBUsersListKey           = "policydb/users/" | 
					
						
							|  |  |  | 	policyDBSTSUsersListKey        = "policydb/sts-users/" | 
					
						
							|  |  |  | 	policyDBServiceAccountsListKey = "policydb/service-accounts/" | 
					
						
							|  |  |  | 	policyDBGroupsListKey          = "policydb/groups/" | 
					
						
							| 
									
										
										
										
											2022-03-28 09:48:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	allListKeys = []string{ | 
					
						
							|  |  |  | 		usersListKey, | 
					
						
							|  |  |  | 		svcAccListKey, | 
					
						
							|  |  |  | 		groupsListKey, | 
					
						
							|  |  |  | 		policiesListKey, | 
					
						
							|  |  |  | 		stsListKey, | 
					
						
							|  |  |  | 		policyDBUsersListKey, | 
					
						
							|  |  |  | 		policyDBSTSUsersListKey, | 
					
						
							|  |  |  | 		policyDBServiceAccountsListKey, | 
					
						
							|  |  |  | 		policyDBGroupsListKey, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (iamOS *IAMObjectStore) listAllIAMConfigItems(ctx context.Context) (map[string][]string, error) { | 
					
						
							|  |  |  | 	res := make(map[string][]string) | 
					
						
							| 
									
										
										
										
											2022-08-05 04:20:43 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(ctx) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2022-04-16 03:12:45 +08:00
										 |  |  | 	for item := range listIAMConfigItems(ctx, iamOS.objAPI, iamConfigPrefix+SlashSeparator) { | 
					
						
							| 
									
										
										
										
											2022-03-28 09:48:01 +08:00
										 |  |  | 		if item.Err != nil { | 
					
						
							|  |  |  | 			return nil, item.Err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		found := false | 
					
						
							|  |  |  | 		for _, listKey := range allListKeys { | 
					
						
							|  |  |  | 			if strings.HasPrefix(item.Item, listKey) { | 
					
						
							|  |  |  | 				found = true | 
					
						
							|  |  |  | 				name := strings.TrimPrefix(item.Item, listKey) | 
					
						
							|  |  |  | 				res[listKey] = append(res[listKey], name) | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-16 03:12:45 +08:00
										 |  |  | 		if !found && (item.Item != "format.json") { | 
					
						
							| 
									
										
										
										
											2022-03-28 09:48:01 +08:00
										 |  |  | 			logger.LogIf(ctx, fmt.Errorf("unknown type of IAM file listed: %v", item.Item)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return res, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Assumes cache is locked by caller.
 | 
					
						
							|  |  |  | func (iamOS *IAMObjectStore) loadAllFromObjStore(ctx context.Context, cache *iamCache) error { | 
					
						
							|  |  |  | 	listedConfigItems, err := iamOS.listAllIAMConfigItems(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Loads things in the same order as `LoadIAMCache()`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	policiesList := listedConfigItems[policiesListKey] | 
					
						
							|  |  |  | 	for _, item := range policiesList { | 
					
						
							|  |  |  | 		policyName := path.Dir(item) | 
					
						
							|  |  |  | 		if err := iamOS.loadPolicyDoc(ctx, policyName, cache.iamPolicyDocsMap); err != nil && err != errNoSuchPolicy { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	setDefaultCannedPolicies(cache.iamPolicyDocsMap) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if iamOS.usersSysType == MinIOUsersSysType { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		regUsersList := listedConfigItems[usersListKey] | 
					
						
							|  |  |  | 		for _, item := range regUsersList { | 
					
						
							|  |  |  | 			userName := path.Dir(item) | 
					
						
							|  |  |  | 			if err := iamOS.loadUser(ctx, userName, regUser, cache.iamUsersMap); err != nil && err != errNoSuchUser { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		groupsList := listedConfigItems[groupsListKey] | 
					
						
							|  |  |  | 		for _, item := range groupsList { | 
					
						
							|  |  |  | 			group := path.Dir(item) | 
					
						
							|  |  |  | 			if err := iamOS.loadGroup(ctx, group, cache.iamGroupsMap); err != nil && err != errNoSuchGroup { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	userPolicyMappingsList := listedConfigItems[policyDBUsersListKey] | 
					
						
							|  |  |  | 	for _, item := range userPolicyMappingsList { | 
					
						
							|  |  |  | 		userName := strings.TrimSuffix(item, ".json") | 
					
						
							|  |  |  | 		if err := iamOS.loadMappedPolicy(ctx, userName, regUser, false, cache.iamUserPolicyMap); err != nil && err != errNoSuchPolicy { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	groupPolicyMappingsList := listedConfigItems[policyDBGroupsListKey] | 
					
						
							|  |  |  | 	for _, item := range groupPolicyMappingsList { | 
					
						
							|  |  |  | 		groupName := strings.TrimSuffix(item, ".json") | 
					
						
							|  |  |  | 		if err := iamOS.loadMappedPolicy(ctx, groupName, regUser, true, cache.iamGroupPolicyMap); err != nil && err != errNoSuchPolicy { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	svcAccList := listedConfigItems[svcAccListKey] | 
					
						
							|  |  |  | 	for _, item := range svcAccList { | 
					
						
							|  |  |  | 		userName := path.Dir(item) | 
					
						
							|  |  |  | 		if err := iamOS.loadUser(ctx, userName, svcUser, cache.iamUsersMap); err != nil && err != errNoSuchUser { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	stsUsersList := listedConfigItems[stsListKey] | 
					
						
							|  |  |  | 	for _, item := range stsUsersList { | 
					
						
							|  |  |  | 		userName := path.Dir(item) | 
					
						
							|  |  |  | 		if err := iamOS.loadUser(ctx, userName, stsUser, cache.iamUsersMap); err != nil && err != errNoSuchUser { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	stsPolicyMappingsList := listedConfigItems[policyDBSTSUsersListKey] | 
					
						
							|  |  |  | 	for _, item := range stsPolicyMappingsList { | 
					
						
							|  |  |  | 		stsName := strings.TrimSuffix(item, ".json") | 
					
						
							|  |  |  | 		if err := iamOS.loadMappedPolicy(ctx, stsName, stsUser, false, cache.iamUserPolicyMap); err != nil && err != errNoSuchPolicy { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cache.buildUserGroupMemberships() | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-12 01:03:39 +08:00
										 |  |  | func (iamOS *IAMObjectStore) savePolicyDoc(ctx context.Context, policyName string, p PolicyDoc) error { | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | 	return iamOS.saveIAMConfig(ctx, &p, getPolicyDocPath(policyName)) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 05:06:05 +08:00
										 |  |  | func (iamOS *IAMObjectStore) saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy, opts ...options) error { | 
					
						
							|  |  |  | 	return iamOS.saveIAMConfig(ctx, mp, getMappedPolicyPath(name, userType, isGroup), opts...) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 05:06:05 +08:00
										 |  |  | func (iamOS *IAMObjectStore) saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity, opts ...options) error { | 
					
						
							|  |  |  | 	return iamOS.saveIAMConfig(ctx, u, getUserIdentityPath(name, userType), opts...) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) saveGroupInfo(ctx context.Context, name string, gi GroupInfo) error { | 
					
						
							|  |  |  | 	return iamOS.saveIAMConfig(ctx, gi, getGroupInfoPath(name)) | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) deletePolicyDoc(ctx context.Context, name string) error { | 
					
						
							|  |  |  | 	err := iamOS.deleteIAMConfig(ctx, getPolicyDocPath(name)) | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 	if err == errConfigNotFound { | 
					
						
							|  |  |  | 		err = errNoSuchPolicy | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) deleteMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool) error { | 
					
						
							|  |  |  | 	err := iamOS.deleteIAMConfig(ctx, getMappedPolicyPath(name, userType, isGroup)) | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 	if err == errConfigNotFound { | 
					
						
							|  |  |  | 		err = errNoSuchPolicy | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) deleteUserIdentity(ctx context.Context, name string, userType IAMUserType) error { | 
					
						
							|  |  |  | 	err := iamOS.deleteIAMConfig(ctx, getUserIdentityPath(name, userType)) | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 	if err == errConfigNotFound { | 
					
						
							|  |  |  | 		err = errNoSuchUser | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 00:54:40 +08:00
										 |  |  | func (iamOS *IAMObjectStore) deleteGroupInfo(ctx context.Context, name string) error { | 
					
						
							|  |  |  | 	err := iamOS.deleteIAMConfig(ctx, getGroupInfoPath(name)) | 
					
						
							| 
									
										
										
										
											2019-10-30 10:50:26 +08:00
										 |  |  | 	if err == errConfigNotFound { | 
					
						
							|  |  |  | 		err = errNoSuchGroup | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // helper type for listIAMConfigItems
 | 
					
						
							|  |  |  | type itemOrErr struct { | 
					
						
							|  |  |  | 	Item string | 
					
						
							|  |  |  | 	Err  error | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Lists files or dirs in the minioMetaBucket at the given path
 | 
					
						
							|  |  |  | // prefix. If dirs is true, only directories are listed, otherwise
 | 
					
						
							|  |  |  | // only objects are listed. All returned items have the pathPrefix
 | 
					
						
							|  |  |  | // removed from their names.
 | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | func listIAMConfigItems(ctx context.Context, objAPI ObjectLayer, pathPrefix string) <-chan itemOrErr { | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	ch := make(chan itemOrErr) | 
					
						
							| 
									
										
										
										
											2020-04-08 05:26:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2020-02-13 22:36:23 +08:00
										 |  |  | 		defer close(ch) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 		// Allocate new results channel to receive ObjectInfo.
 | 
					
						
							|  |  |  | 		objInfoCh := make(chan ObjectInfo) | 
					
						
							| 
									
										
										
										
											2020-02-13 22:36:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 		if err := objAPI.Walk(ctx, minioMetaBucket, pathPrefix, objInfoCh, ObjectOptions{}); err != nil { | 
					
						
							|  |  |  | 			select { | 
					
						
							|  |  |  | 			case ch <- itemOrErr{Err: err}: | 
					
						
							|  |  |  | 			case <-ctx.Done(): | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-12-20 01:36:37 +08:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for obj := range objInfoCh { | 
					
						
							|  |  |  | 			item := strings.TrimPrefix(obj.Name, pathPrefix) | 
					
						
							|  |  |  | 			item = strings.TrimSuffix(item, SlashSeparator) | 
					
						
							|  |  |  | 			select { | 
					
						
							|  |  |  | 			case ch <- itemOrErr{Item: item}: | 
					
						
							|  |  |  | 			case <-ctx.Done(): | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2020-04-08 05:26:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	return ch | 
					
						
							|  |  |  | } |