From b0bca50dfdd8aa63d95e57a579bd3fcf14a2c3ad Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sun, 8 Mar 2026 15:58:27 -0700 Subject: [PATCH] iam: require empty PolicyNames before group deletion Reject DeleteGroup when group has attached policies, matching the existing members check. Also fix GetGroup error handling in DeletePolicy to only skip ErrGroupNotFound, not all errors. --- weed/iamapi/iamapi_group_handlers.go | 3 +++ weed/s3api/s3api_embedded_iam.go | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/weed/iamapi/iamapi_group_handlers.go b/weed/iamapi/iamapi_group_handlers.go index dc4071d94..49d386e0c 100644 --- a/weed/iamapi/iamapi_group_handlers.go +++ b/weed/iamapi/iamapi_group_handlers.go @@ -36,6 +36,9 @@ func (iama *IamApiServer) DeleteGroup(s3cfg *iam_pb.S3ApiConfiguration, values u if len(g.Members) > 0 { return resp, &IamError{Code: iam.ErrCodeDeleteConflictException, Error: fmt.Errorf("cannot delete group %s: group has %d member(s)", groupName, len(g.Members))} } + if len(g.PolicyNames) > 0 { + return resp, &IamError{Code: iam.ErrCodeDeleteConflictException, Error: fmt.Errorf("cannot delete group %s: group has %d attached policy(ies)", groupName, len(g.PolicyNames))} + } s3cfg.Groups = append(s3cfg.Groups[:i], s3cfg.Groups[i+1:]...) return resp, nil } diff --git a/weed/s3api/s3api_embedded_iam.go b/weed/s3api/s3api_embedded_iam.go index f6ee985e5..e89b6c39b 100644 --- a/weed/s3api/s3api_embedded_iam.go +++ b/weed/s3api/s3api_embedded_iam.go @@ -518,7 +518,10 @@ func (e *EmbeddedIamApi) DeletePolicy(ctx context.Context, values url.Values) (* for _, gn := range groupNames { g, err := e.credentialManager.GetGroup(ctx, gn) if err != nil { - continue + if errors.Is(err, credential.ErrGroupNotFound) { + continue + } + return resp, &iamError{Code: iam.ErrCodeServiceFailureException, Error: fmt.Errorf("failed to get group %s: %w", gn, err)} } for _, pn := range g.PolicyNames { if pn == policyName { @@ -1482,6 +1485,9 @@ func (e *EmbeddedIamApi) DeleteGroup(s3cfg *iam_pb.S3ApiConfiguration, values ur if len(g.Members) > 0 { return resp, &iamError{Code: iam.ErrCodeDeleteConflictException, Error: fmt.Errorf("cannot delete group %s: group has %d member(s). Remove all members first", groupName, len(g.Members))} } + if len(g.PolicyNames) > 0 { + return resp, &iamError{Code: iam.ErrCodeDeleteConflictException, Error: fmt.Errorf("cannot delete group %s: group has %d attached policy(ies). Detach all policies first", groupName, len(g.PolicyNames))} + } s3cfg.Groups = append(s3cfg.Groups[:i], s3cfg.Groups[i+1:]...) return resp, nil }