diff --git a/cmd/admin-handlers-site-replication.go b/cmd/admin-handlers-site-replication.go index 74d58cdbd..8021b819a 100644 --- a/cmd/admin-handlers-site-replication.go +++ b/cmd/admin-handlers-site-replication.go @@ -178,6 +178,10 @@ func (a adminAPIHandlers) SRPeerReplicateIAMItem(w http.ResponseWriter, r *http. err = globalSiteReplicationSys.PeerPolicyMappingHandler(ctx, item.PolicyMapping) case madmin.SRIAMItemSTSAcc: err = globalSiteReplicationSys.PeerSTSAccHandler(ctx, item.STSCredential) + case madmin.SRIAMItemIAMUser: + err = globalSiteReplicationSys.PeerIAMUserChangeHandler(ctx, item.IAMUser) + case madmin.SRIAMItemGroupInfo: + err = globalSiteReplicationSys.PeerGroupInfoChangeHandler(ctx, item.GroupInfo) } if err != nil { logger.LogIf(ctx, err) diff --git a/cmd/admin-handlers-users.go b/cmd/admin-handlers-users.go index 4ba282c3d..6938aa581 100644 --- a/cmd/admin-handlers-users.go +++ b/cmd/admin-handlers-users.go @@ -62,6 +62,17 @@ func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) { writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } + + if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ + Type: madmin.SRIAMItemIAMUser, + IAMUser: &madmin.SRIAMUser{ + AccessKey: accessKey, + IsDeleteReq: true, + }, + }); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } } // ListUsers - GET /minio/admin/v3/list-users?bucket={bucket} @@ -220,11 +231,20 @@ func (a adminAPIHandlers) UpdateGroupMembers(w http.ResponseWriter, r *http.Requ } else { err = globalIAMSys.AddUsersToGroup(ctx, updReq.Group, updReq.Members) } - if err != nil { writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } + + if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ + Type: madmin.SRIAMItemGroupInfo, + GroupInfo: &madmin.SRGroupInfo{ + UpdateReq: updReq, + }, + }); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } } // GetGroup - /minio/admin/v3/group?group=mygroup1 @@ -427,6 +447,18 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } + + if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ + Type: madmin.SRIAMItemIAMUser, + IAMUser: &madmin.SRIAMUser{ + AccessKey: accessKey, + IsDeleteReq: false, + UserReq: &ureq, + }, + }); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } } // AddServiceAccount - PUT /minio/admin/v3/add-service-account @@ -585,14 +617,9 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque return } - // Call hook for cluster-replication. - // - // FIXME: This wont work in an OpenID situation as the parent credential - // may not be present on peer clusters to provide inherited policies. - // Also, we should not be replicating root user's service account - as - // they are not authenticated by a common external IDP, so we skip when - // opts.ldapUser == "". - if _, isLDAPAccount := opts.claims[ldapUserN]; isLDAPAccount { + // Call hook for cluster-replication if the service account is not for a + // root user. + if newCred.ParentUser != globalActiveCred.AccessKey { err = globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ Type: madmin.SRIAMItemSvcAcc, SvcAccChange: &madmin.SRSvcAccChange{ diff --git a/cmd/iam.go b/cmd/iam.go index caa9a7037..80f7e06dd 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -636,6 +636,7 @@ func (sys *IAMSys) SetTempUser(ctx context.Context, accessKey string, cred auth. } sys.notifyForUser(ctx, cred.AccessKey, true) + return nil } diff --git a/cmd/site-replication.go b/cmd/site-replication.go index d74d8357c..3597b6e57 100644 --- a/cmd/site-replication.go +++ b/cmd/site-replication.go @@ -28,6 +28,7 @@ import ( "fmt" "net/http" "net/url" + "reflect" "sort" "strings" "sync" @@ -551,13 +552,19 @@ func (c *SiteReplicationSys) PeerJoinReq(ctx context.Context, arg madmin.SRPeerJ // GetIDPSettings returns info about the configured identity provider. It is // used to validate that all peers have the same IDP. func (c *SiteReplicationSys) GetIDPSettings(ctx context.Context) madmin.IDPSettings { - return madmin.IDPSettings{ + s := madmin.IDPSettings{} + s.LDAP = madmin.LDAPSettings{ IsLDAPEnabled: globalLDAPConfig.Enabled, LDAPUserDNSearchBase: globalLDAPConfig.UserDNSearchBaseDN, LDAPUserDNSearchFilter: globalLDAPConfig.UserDNSearchFilter, LDAPGroupSearchBase: globalLDAPConfig.GroupSearchBaseDistName, LDAPGroupSearchFilter: globalLDAPConfig.GroupSearchFilter, } + s.OpenID = globalOpenIDConfig.GetSettings() + if s.OpenID.Enabled { + s.OpenID.Region = globalSite.Region + } + return s } func (c *SiteReplicationSys) validateIDPSettings(ctx context.Context, peers []PeerSiteInfo) (bool, error) { @@ -580,13 +587,8 @@ func (c *SiteReplicationSys) validateIDPSettings(ctx context.Context, peers []Pe s = append(s, is) } - for _, v := range s { - if !v.IsLDAPEnabled { - return false, nil - } - } for i := 1; i < len(s); i++ { - if s[i] != s[0] { + if !reflect.DeepEqual(s[i], s[0]) { return false, nil } } @@ -984,12 +986,8 @@ func (c *SiteReplicationSys) PeerBucketDeleteHandler(ctx context.Context, bucket // OpenID, such mappings are provided from the IDP directly and so are not // applicable here. // -// Only certain service accounts can be replicated: -// -// Service accounts created for STS credentials using an external IDP: such STS -// credentials would be valid on the peer clusters as they are assumed to be -// using the same external IDP. Service accounts when using internal IDP or for -// root user will not be replicated. +// Service accounts are replicated as long as they are not meant for the root +// user. // // STS accounts are replicated, but only if the session token is verifiable // using the local cluster's root credential. @@ -1031,6 +1029,44 @@ func (c *SiteReplicationSys) PeerAddPolicyHandler(ctx context.Context, policyNam return nil } +// PeerIAMUserChangeHandler - copies IAM user to local. +func (c *SiteReplicationSys) PeerIAMUserChangeHandler(ctx context.Context, change *madmin.SRIAMUser) error { + if change == nil { + return errSRInvalidRequest(errInvalidArgument) + } + var err error + if change.IsDeleteReq { + err = globalIAMSys.DeleteUser(ctx, change.AccessKey, true) + } else { + if change.UserReq == nil { + return errSRInvalidRequest(errInvalidArgument) + } + err = globalIAMSys.CreateUser(ctx, change.AccessKey, *change.UserReq) + } + if err != nil { + return wrapSRErr(err) + } + return nil +} + +// PeerGroupInfoChangeHandler - copies group changes to local. +func (c *SiteReplicationSys) PeerGroupInfoChangeHandler(ctx context.Context, change *madmin.SRGroupInfo) error { + if change == nil { + return errSRInvalidRequest(errInvalidArgument) + } + updReq := change.UpdateReq + var err error + if updReq.IsRemove { + err = globalIAMSys.RemoveUsersFromGroup(ctx, updReq.Group, updReq.Members) + } else { + err = globalIAMSys.AddUsersToGroup(ctx, updReq.Group, updReq.Members) + } + if err != nil { + return wrapSRErr(err) + } + return nil +} + // PeerSvcAccChangeHandler - copies service-account change to local. func (c *SiteReplicationSys) PeerSvcAccChangeHandler(ctx context.Context, change *madmin.SRSvcAccChange) error { if change == nil { @@ -1120,31 +1156,31 @@ func (c *SiteReplicationSys) PeerSTSAccHandler(ctx context.Context, stsCred *mad return fmt.Errorf("Expiry claim was not found: %v", mapClaims) } - // Extract the username and lookup DN and groups in LDAP. - ldapUser, ok := claims.Lookup(ldapUserN) - if !ok { - return fmt.Errorf("Could not find LDAP username in claims: %v", mapClaims) - } - - // Need to lookup the groups from LDAP. - ldapUserDN, ldapGroups, err := globalLDAPConfig.LookupUserDN(ldapUser) - if err != nil { - return fmt.Errorf("unable to query LDAP server for %s: %v", ldapUser, err) - } - cred := auth.Credentials{ AccessKey: stsCred.AccessKey, SecretKey: stsCred.SecretKey, Expiration: time.Unix(expiry, 0).UTC(), SessionToken: stsCred.SessionToken, + ParentUser: stsCred.ParentUser, Status: auth.AccountOn, - ParentUser: ldapUserDN, - Groups: ldapGroups, + } + + // Extract the username and lookup DN and groups in LDAP. + ldapUser, isLDAPSTS := claims.Lookup(ldapUserN) + switch { + case isLDAPSTS: + // Need to lookup the groups from LDAP. + _, ldapGroups, err := globalLDAPConfig.LookupUserDN(ldapUser) + if err != nil { + return fmt.Errorf("unable to query LDAP server for %s: %v", ldapUser, err) + } + + cred.Groups = ldapGroups } // Set these credentials to IAM. - if err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, ""); err != nil { - return fmt.Errorf("unable to save STS credential: %v", err) + if err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, stsCred.ParentPolicyMapping); err != nil { + return fmt.Errorf("unable to save STS credential and/or parent policy mapping: %v", err) } return nil @@ -1497,6 +1533,11 @@ func (c *SiteReplicationSys) syncLocalToPeers(ctx context.Context) error { return errSRBackendIssue(err) } for user, acc := range serviceAccounts { + if user == siteReplicatorSvcAcc { + // skip the site replicate svc account as it is + // already replicated. + continue + } claims, err := globalIAMSys.GetClaimsForSvcAcc(ctx, acc.AccessKey) if err != nil { return errSRBackendIssue(err) diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 830bd1c5a..95cba3880 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -278,6 +278,22 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) { return } + // Call hook for site replication. + if cred.ParentUser != globalActiveCred.AccessKey { + if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ + Type: madmin.SRIAMItemSTSAcc, + STSCredential: &madmin.SRSTSCredential{ + AccessKey: cred.AccessKey, + SecretKey: cred.SecretKey, + SessionToken: cred.SessionToken, + ParentUser: cred.ParentUser, + }, + }); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + } + assumeRoleResponse := &AssumeRoleResponse{ Result: AssumeRoleResult{ Credentials: cred, @@ -497,6 +513,21 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ return } + // Call hook for site replication. + if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ + Type: madmin.SRIAMItemSTSAcc, + STSCredential: &madmin.SRSTSCredential{ + AccessKey: cred.AccessKey, + SecretKey: cred.SecretKey, + SessionToken: cred.SessionToken, + ParentUser: cred.ParentUser, + ParentPolicyMapping: policyName, + }, + }); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + var encodedSuccessResponse []byte switch action { case clientGrants: @@ -653,13 +684,14 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * return } - // Call hook for cluster-replication. + // Call hook for site replication. if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ Type: madmin.SRIAMItemSTSAcc, STSCredential: &madmin.SRSTSCredential{ AccessKey: cred.AccessKey, SecretKey: cred.SecretKey, SessionToken: cred.SessionToken, + ParentUser: cred.ParentUser, }, }); err != nil { writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) @@ -805,12 +837,28 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h } tmpCredentials.ParentUser = parentUser - err = globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, certificate.Subject.CommonName) + policyName := certificate.Subject.CommonName + err = globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, policyName) if err != nil { writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err) return } + // Call hook for site replication. + if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{ + Type: madmin.SRIAMItemSTSAcc, + STSCredential: &madmin.SRSTSCredential{ + AccessKey: tmpCredentials.AccessKey, + SecretKey: tmpCredentials.SecretKey, + SessionToken: tmpCredentials.SessionToken, + ParentUser: tmpCredentials.ParentUser, + ParentPolicyMapping: policyName, + }, + }); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + response := new(AssumeRoleWithCertificateResponse) response.Result.Credentials = tmpCredentials response.Metadata.RequestID = w.Header().Get(xhttp.AmzRequestID) diff --git a/go.mod b/go.mod index ac93af9da..981182747 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/minio/csvparser v1.0.0 github.com/minio/highwayhash v1.0.2 github.com/minio/kes v0.14.0 - github.com/minio/madmin-go v1.2.3 + github.com/minio/madmin-go v1.2.4 github.com/minio/minio-go/v7 v7.0.20 github.com/minio/parquet-go v1.1.0 github.com/minio/pkg v1.1.11 diff --git a/go.sum b/go.sum index 80c5f641f..0ce500515 100644 --- a/go.sum +++ b/go.sum @@ -210,6 +210,7 @@ github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY github.com/bits-and-blooms/bloom/v3 v3.0.1 h1:Inlf0YXbgehxVjMPmCGv86iMCKMGPPrPSHtBF5yRHwA= github.com/bits-and-blooms/bloom/v3 v3.0.1/go.mod h1:MC8muvBzzPOFsrcdND/A7kU7kMhkqb9KI70JlZCP+C8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= @@ -715,6 +716,7 @@ github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1K github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190328170749-bb2674552d8f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI= github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904= github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w= github.com/goreleaser/nfpm v1.3.0/go.mod h1:w0p7Kc9TAUgWMyrub63ex3M2Mgw88M4GZXoTq5UCb40= @@ -960,6 +962,7 @@ github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAK github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -1006,6 +1009,7 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -1088,8 +1092,8 @@ github.com/minio/kes v0.14.0/go.mod h1:OUensXz2BpgMfiogslKxv7Anyx/wj+6bFC6qA7BQc github.com/minio/madmin-go v1.0.12/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs= github.com/minio/madmin-go v1.1.15/go.mod h1:Iu0OnrMWNBYx1lqJTW+BFjBMx0Hi0wjw8VmqhiOs2Jo= github.com/minio/madmin-go v1.1.23/go.mod h1:wv8zCroSCnpjjQdmgsdJEkFH2oD4w9J40OZqbhxjiJ4= -github.com/minio/madmin-go v1.2.3 h1:Z0hgEOKHaOqfBv0hN62FkQJKDW1kmVw6K9vJwM8ol34= -github.com/minio/madmin-go v1.2.3/go.mod h1:wv8zCroSCnpjjQdmgsdJEkFH2oD4w9J40OZqbhxjiJ4= +github.com/minio/madmin-go v1.2.4 h1:o+0X6ENO/AtkRxCbD4FXT6YCRIH7HgDGb+WzfJFDzMQ= +github.com/minio/madmin-go v1.2.4/go.mod h1:/rOfQv4ohkXJ+7EaSnhg9IJEX7cobX08zkSLfh8G3Ks= github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2 h1:xocb1RGyrDJ8PxkNn0NSbaBlfdU6J/Ag9QK62pb7nR8= github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2/go.mod h1:siI9jWTzj1KsNXgz6NOL/S7OTaAUM0OMi+zEkF08gnA= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= @@ -1200,6 +1204,8 @@ github.com/nats-io/stan.go v0.8.3/go.mod h1:Ejm8bbHnMTSptU6uNMAVuxeapMJYBB/Ml3ej github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/ncw/directio v1.0.5 h1:JSUBhdjEvVaJvOoyPAbcW0fnd0tvRXD76wEfZ1KcQz4= github.com/ncw/directio v1.0.5/go.mod h1:rX/pKEYkOXBGOggmcyJeJGloCkleSvphPx2eV3t6ROk= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= @@ -1253,6 +1259,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= @@ -1271,6 +1278,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/xattr v0.4.3 h1:5Jx4GCg5ABtqWZH8WLzeI4fOtM1HyX4RBawuCoua1es= github.com/pkg/xattr v0.4.3/go.mod h1:sBD3RAqlr8Q+RC3FutZcikpT8nyDrIEEBw2J744gVWs= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1387,8 +1395,11 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -1413,12 +1424,14 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1430,6 +1443,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1543,6 +1557,7 @@ go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQc go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.4/go.mod h1:a+pbz+UrcOpvve1Qxf6tGovi15PjgtRhi0QTO2Nlc4U= go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v3 v3.5.0-beta.4/go.mod h1:0L1RulN1QSXq6uKPMUSX+OTAYyFkapMK7iUHXXIH/1E= go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek= go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= @@ -1636,6 +1651,7 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -1756,6 +1772,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -2051,6 +2068,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= @@ -2207,6 +2225,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c= gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= diff --git a/internal/config/identity/openid/jwt.go b/internal/config/identity/openid/jwt.go index 4f39bf506..dbfa231e1 100644 --- a/internal/config/identity/openid/jwt.go +++ b/internal/config/identity/openid/jwt.go @@ -20,6 +20,7 @@ package openid import ( "crypto" "crypto/sha1" + "crypto/sha256" "encoding/base64" "encoding/json" "errors" @@ -33,6 +34,7 @@ import ( "time" jwtgo "github.com/golang-jwt/jwt/v4" + "github.com/minio/madmin-go" "github.com/minio/minio/internal/arn" "github.com/minio/minio/internal/auth" "github.com/minio/minio/internal/config" @@ -369,6 +371,40 @@ func (Config) ID() ID { return "jwt" } +// GetSettings - fetches OIDC settings for site-replication related validation. +// NOTE that region must be populated by caller as this package does not know. +func (r *Config) GetSettings() madmin.OpenIDSettings { + res := madmin.OpenIDSettings{} + if !r.Enabled { + return res + } + + hashedSecret := "" + { + h := sha256.New() + h.Write([]byte(r.ClientSecret)) + bs := h.Sum(nil) + hashedSecret = base64.RawURLEncoding.EncodeToString(bs) + } + if r.RolePolicy != "" { + res.Roles = make(map[string]madmin.OpenIDProviderSettings) + res.Roles[r.roleArn.String()] = madmin.OpenIDProviderSettings{ + ClaimUserinfoEnabled: r.ClaimUserinfo, + RolePolicy: r.RolePolicy, + ClientID: r.ClientID, + HashedClientSecret: hashedSecret, + } + } else { + res.ClaimProvider = madmin.OpenIDProviderSettings{ + ClaimName: r.ClaimName, + ClaimUserinfoEnabled: r.ClaimUserinfo, + ClientID: r.ClientID, + HashedClientSecret: hashedSecret, + } + } + return res +} + // OpenID keys and envs. const ( JwksURL = "jwks_url"