do not remove Sid from svcaccount policies (#14064)

fixes #13905
This commit is contained in:
Harshavardhana 2022-01-10 14:26:26 -08:00 committed by GitHub
parent 76b21de0c6
commit 3bd9636a5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 105 additions and 70 deletions

View File

@ -102,6 +102,18 @@ func toAdminAPIErr(ctx context.Context, err error) APIError {
Description: err.Error(), Description: err.Error(),
HTTPStatusCode: http.StatusForbidden, HTTPStatusCode: http.StatusForbidden,
} }
case errors.Is(err, errIAMServiceAccount):
apiErr = APIError{
Code: "XMinioIAMServiceAccount",
Description: err.Error(),
HTTPStatusCode: http.StatusBadRequest,
}
case errors.Is(err, errIAMServiceAccountUsed):
apiErr = APIError{
Code: "XMinioIAMServiceAccountUsed",
Description: err.Error(),
HTTPStatusCode: http.StatusBadRequest,
}
case errors.Is(err, errIAMNotInitialized): case errors.Is(err, errIAMNotInitialized):
apiErr = APIError{ apiErr = APIError{
Code: "XMinioIAMNotInitialized", Code: "XMinioIAMNotInitialized",

View File

@ -816,18 +816,15 @@ func (a adminAPIHandlers) InfoServiceAccount(w http.ResponseWriter, r *http.Requ
var svcAccountPolicy iampolicy.Policy var svcAccountPolicy iampolicy.Policy
impliedPolicy := policy == nil if policy != nil {
svcAccountPolicy = *policy
// If policy is empty, check for policy of the parent user
if !impliedPolicy {
svcAccountPolicy = svcAccountPolicy.Merge(*policy)
} else { } else {
policiesNames, err := globalIAMSys.PolicyDBGet(svcAccount.ParentUser, false) policiesNames, err := globalIAMSys.PolicyDBGet(svcAccount.ParentUser, false)
if err != nil { if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return return
} }
svcAccountPolicy = svcAccountPolicy.Merge(globalIAMSys.GetCombinedPolicy(policiesNames...)) svcAccountPolicy = globalIAMSys.GetCombinedPolicy(policiesNames...)
} }
policyJSON, err := json.MarshalIndent(svcAccountPolicy, "", " ") policyJSON, err := json.MarshalIndent(svcAccountPolicy, "", " ")
@ -839,7 +836,7 @@ func (a adminAPIHandlers) InfoServiceAccount(w http.ResponseWriter, r *http.Requ
infoResp := madmin.InfoServiceAccountResp{ infoResp := madmin.InfoServiceAccountResp{
ParentUser: svcAccount.ParentUser, ParentUser: svcAccount.ParentUser,
AccountStatus: svcAccount.Status, AccountStatus: svcAccount.Status,
ImpliedPolicy: impliedPolicy, ImpliedPolicy: policy == nil,
Policy: string(policyJSON), Policy: string(policyJSON),
} }

View File

@ -37,20 +37,25 @@ import (
func getAnonReadOnlyBucketPolicy(bucketName string) *policy.Policy { func getAnonReadOnlyBucketPolicy(bucketName string) *policy.Policy {
return &policy.Policy{ return &policy.Policy{
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{policy.NewStatement( Statements: []policy.Statement{
policy.NewStatement(
"",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction), policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction),
policy.NewResourceSet(policy.NewResource(bucketName, "")), policy.NewResourceSet(policy.NewResource(bucketName, "")),
condition.NewFunctions(), condition.NewFunctions(),
)}, ),
},
} }
} }
func getAnonWriteOnlyBucketPolicy(bucketName string) *policy.Policy { func getAnonWriteOnlyBucketPolicy(bucketName string) *policy.Policy {
return &policy.Policy{ return &policy.Policy{
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{policy.NewStatement( Statements: []policy.Statement{
policy.NewStatement(
"",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet( policy.NewActionSet(
@ -59,27 +64,33 @@ func getAnonWriteOnlyBucketPolicy(bucketName string) *policy.Policy {
), ),
policy.NewResourceSet(policy.NewResource(bucketName, "")), policy.NewResourceSet(policy.NewResource(bucketName, "")),
condition.NewFunctions(), condition.NewFunctions(),
)}, ),
},
} }
} }
func getAnonReadOnlyObjectPolicy(bucketName, prefix string) *policy.Policy { func getAnonReadOnlyObjectPolicy(bucketName, prefix string) *policy.Policy {
return &policy.Policy{ return &policy.Policy{
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{policy.NewStatement( Statements: []policy.Statement{
policy.NewStatement(
"",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.GetObjectAction), policy.NewActionSet(policy.GetObjectAction),
policy.NewResourceSet(policy.NewResource(bucketName, prefix)), policy.NewResourceSet(policy.NewResource(bucketName, prefix)),
condition.NewFunctions(), condition.NewFunctions(),
)}, ),
},
} }
} }
func getAnonWriteOnlyObjectPolicy(bucketName, prefix string) *policy.Policy { func getAnonWriteOnlyObjectPolicy(bucketName, prefix string) *policy.Policy {
return &policy.Policy{ return &policy.Policy{
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{policy.NewStatement( Statements: []policy.Statement{
policy.NewStatement(
"",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet( policy.NewActionSet(
@ -90,7 +101,8 @@ func getAnonWriteOnlyObjectPolicy(bucketName, prefix string) *policy.Policy {
), ),
policy.NewResourceSet(policy.NewResource(bucketName, prefix)), policy.NewResourceSet(policy.NewResource(bucketName, prefix)),
condition.NewFunctions(), condition.NewFunctions(),
)}, ),
},
} }
} }

View File

@ -1416,6 +1416,7 @@ func (a *azureObjects) GetBucketPolicy(ctx context.Context, bucket string) (*pol
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{ Statements: []policy.Statement{
policy.NewStatement( policy.NewStatement(
"",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet( policy.NewActionSet(

View File

@ -1470,6 +1470,7 @@ func (l *gcsGateway) GetBucketPolicy(ctx context.Context, bucket string) (*polic
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{ Statements: []policy.Statement{
policy.NewStatement( policy.NewStatement(
"",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
actionSet, actionSet,

View File

@ -1084,13 +1084,14 @@ func filterPolicies(cache *iamCache, policyName string, bucketName string) (stri
continue continue
} }
p, found := cache.iamPolicyDocsMap[policy] p, found := cache.iamPolicyDocsMap[policy]
if found { if !found {
continue
}
if bucketName == "" || p.Policy.MatchResource(bucketName) { if bucketName == "" || p.Policy.MatchResource(bucketName) {
policies = append(policies, policy) policies = append(policies, policy)
combinedPolicy = combinedPolicy.Merge(p.Policy) combinedPolicy = combinedPolicy.Merge(p.Policy)
} }
} }
}
return strings.Join(policies, ","), combinedPolicy return strings.Join(policies, ","), combinedPolicy
} }
@ -1511,13 +1512,16 @@ func (store *IAMStoreSys) AddServiceAccount(ctx context.Context, cred auth.Crede
// Found newly requested service account, to be an existing account - // Found newly requested service account, to be an existing account -
// reject such operation (updates to the service account are handled in // reject such operation (updates to the service account are handled in
// a different API). // a different API).
if _, found := cache.iamUsersMap[accessKey]; found { if scred, found := cache.iamUsersMap[accessKey]; found {
return errIAMActionNotAllowed if scred.ParentUser != parentUser {
return errIAMServiceAccountUsed
}
return errIAMServiceAccount
} }
// Parent user must not be a service account. // Parent user must not be a service account.
if cr, found := cache.iamUsersMap[parentUser]; found && cr.IsServiceAccount() { if cr, found := cache.iamUsersMap[parentUser]; found && cr.IsServiceAccount() {
return errIAMActionNotAllowed return errIAMServiceAccount
} }
u := newUserIdentity(cred) u := newUserIdentity(cred)

View File

@ -883,18 +883,19 @@ func (sys *IAMSys) getServiceAccount(ctx context.Context, accessKey string) (aut
var embeddedPolicy *iampolicy.Policy var embeddedPolicy *iampolicy.Policy
jwtClaims, err := auth.ExtractClaims(sa.SessionToken, globalActiveCred.SecretKey) jwtClaims, err := auth.ExtractClaims(sa.SessionToken, globalActiveCred.SecretKey)
if err == nil { if err != nil {
return auth.Credentials{}, nil, err
}
pt, ptok := jwtClaims.Lookup(iamPolicyClaimNameSA()) pt, ptok := jwtClaims.Lookup(iamPolicyClaimNameSA())
sp, spok := jwtClaims.Lookup(iampolicy.SessionPolicyName) sp, spok := jwtClaims.Lookup(iampolicy.SessionPolicyName)
if ptok && spok && pt == "embedded-policy" { if ptok && spok && pt == "embedded-policy" {
policyBytes, err := base64.StdEncoding.DecodeString(sp) policyBytes, err := base64.StdEncoding.DecodeString(sp)
if err == nil { if err != nil {
p, err := iampolicy.ParseConfig(bytes.NewReader(policyBytes)) return auth.Credentials{}, nil, err
if err == nil {
policy := iampolicy.Policy{}.Merge(*p)
embeddedPolicy = &policy
}
} }
embeddedPolicy, err = iampolicy.ParseConfig(bytes.NewReader(policyBytes))
if err != nil {
return auth.Credentials{}, nil, err
} }
} }

View File

@ -31,14 +31,14 @@ func TestPolicySysIsAllowed(t *testing.T) {
p := &policy.Policy{ p := &policy.Policy{
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{ Statements: []policy.Statement{
policy.NewStatement( policy.NewStatement("",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.GetBucketLocationAction), policy.NewActionSet(policy.GetBucketLocationAction),
policy.NewResourceSet(policy.NewResource("mybucket", "")), policy.NewResourceSet(policy.NewResource("mybucket", "")),
condition.NewFunctions(), condition.NewFunctions(),
), ),
policy.NewStatement( policy.NewStatement("",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.PutObjectAction), policy.NewActionSet(policy.PutObjectAction),
@ -164,14 +164,14 @@ func TestPolicyToBucketAccessPolicy(t *testing.T) {
case1Policy := &policy.Policy{ case1Policy := &policy.Policy{
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{ Statements: []policy.Statement{
policy.NewStatement( policy.NewStatement("",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction), policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction),
policy.NewResourceSet(policy.NewResource("mybucket", "")), policy.NewResourceSet(policy.NewResource("mybucket", "")),
condition.NewFunctions(), condition.NewFunctions(),
), ),
policy.NewStatement( policy.NewStatement("",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.GetObjectAction), policy.NewActionSet(policy.GetObjectAction),
@ -199,7 +199,7 @@ func TestPolicyToBucketAccessPolicy(t *testing.T) {
case3Policy := &policy.Policy{ case3Policy := &policy.Policy{
Version: "12-10-2012", Version: "12-10-2012",
Statements: []policy.Statement{ Statements: []policy.Statement{
policy.NewStatement( policy.NewStatement("",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.PutObjectAction), policy.NewActionSet(policy.PutObjectAction),
@ -244,14 +244,14 @@ func TestBucketAccessPolicyToPolicy(t *testing.T) {
case1Result := &policy.Policy{ case1Result := &policy.Policy{
Version: policy.DefaultVersion, Version: policy.DefaultVersion,
Statements: []policy.Statement{ Statements: []policy.Statement{
policy.NewStatement( policy.NewStatement("",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction), policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction),
policy.NewResourceSet(policy.NewResource("mybucket", "")), policy.NewResourceSet(policy.NewResource("mybucket", "")),
condition.NewFunctions(), condition.NewFunctions(),
), ),
policy.NewStatement( policy.NewStatement("",
policy.Allow, policy.Allow,
policy.NewPrincipal("*"), policy.NewPrincipal("*"),
policy.NewActionSet(policy.GetObjectAction), policy.NewActionSet(policy.GetObjectAction),

View File

@ -91,6 +91,12 @@ var errTooManyPolicies = errors.New("Only a single policy may be specified here.
// error returned in IAM subsystem when an external users systems is configured. // error returned in IAM subsystem when an external users systems is configured.
var errIAMActionNotAllowed = errors.New("Specified IAM action is not allowed") var errIAMActionNotAllowed = errors.New("Specified IAM action is not allowed")
// error returned in IAM service account
var errIAMServiceAccount = errors.New("Specified service account cannot be updated in this API call")
// error returned in IAM service account is already used.
var errIAMServiceAccountUsed = errors.New("Specified service account is used by another user")
// error returned in IAM subsystem when IAM sub-system is still being initialized. // error returned in IAM subsystem when IAM sub-system is still being initialized.
var errIAMNotInitialized = errors.New("IAM sub-system is being initialized, please try again") var errIAMNotInitialized = errors.New("IAM sub-system is being initialized, please try again")

2
go.mod
View File

@ -52,7 +52,7 @@ require (
github.com/minio/madmin-go v1.2.4 github.com/minio/madmin-go v1.2.4
github.com/minio/minio-go/v7 v7.0.20 github.com/minio/minio-go/v7 v7.0.20
github.com/minio/parquet-go v1.1.0 github.com/minio/parquet-go v1.1.0
github.com/minio/pkg v1.1.11 github.com/minio/pkg v1.1.14
github.com/minio/selfupdate v0.4.0 github.com/minio/selfupdate v0.4.0
github.com/minio/sha256-simd v1.0.0 github.com/minio/sha256-simd v1.0.0
github.com/minio/simdjson-go v0.2.1 github.com/minio/simdjson-go v0.2.1

3
go.sum
View File

@ -1114,8 +1114,9 @@ github.com/minio/pkg v1.0.3/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP
github.com/minio/pkg v1.0.4/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8= github.com/minio/pkg v1.0.4/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8=
github.com/minio/pkg v1.0.11/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14= github.com/minio/pkg v1.0.11/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
github.com/minio/pkg v1.1.3/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14= github.com/minio/pkg v1.1.3/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
github.com/minio/pkg v1.1.11 h1:FQMYrOZzZenQUVwvxM0YjoAZB15Wb+m3TZSu33Lynx0=
github.com/minio/pkg v1.1.11/go.mod h1:2WJAxesjzmPK9MnLZKm5n1hVYfBg04f2GQs6N5ImNU8= github.com/minio/pkg v1.1.11/go.mod h1:2WJAxesjzmPK9MnLZKm5n1hVYfBg04f2GQs6N5ImNU8=
github.com/minio/pkg v1.1.14 h1:9tGPH6p0YEsIOHOY3sh2Yl5Dn0JNTkNOdZW/p+MKIi4=
github.com/minio/pkg v1.1.14/go.mod h1:2WJAxesjzmPK9MnLZKm5n1hVYfBg04f2GQs6N5ImNU8=
github.com/minio/selfupdate v0.3.1/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM= github.com/minio/selfupdate v0.3.1/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM=
github.com/minio/selfupdate v0.4.0 h1:A7t07pN4Ch1tBTIRStW0KhUVyykz+2muCqFsITQeEW8= github.com/minio/selfupdate v0.4.0 h1:A7t07pN4Ch1tBTIRStW0KhUVyykz+2muCqFsITQeEW8=
github.com/minio/selfupdate v0.4.0/go.mod h1:mcDkzMgq8PRcpCRJo/NlPY7U45O5dfYl2Y0Rg7IustY= github.com/minio/selfupdate v0.4.0/go.mod h1:mcDkzMgq8PRcpCRJo/NlPY7U45O5dfYl2Y0Rg7IustY=