diff --git a/vault/identity_store.go b/vault/identity_store.go index d936e86c72..d98a23b0b2 100644 --- a/vault/identity_store.go +++ b/vault/identity_store.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/vault/helper/versions" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/consts" + "github.com/hashicorp/vault/sdk/helper/locksutil" "github.com/hashicorp/vault/sdk/logical" "github.com/patrickmn/go-cache" ) @@ -66,6 +67,7 @@ func NewIdentityStore(ctx context.Context, core *Core, config *logical.BackendCo entityCreator: core, mountLister: core, mfaBackend: core.loginMFABackend, + aliasLocks: locksutil.CreateLocks(), } // Create a memdb instance, which by default, operates on lower cased diff --git a/vault/identity_store_structs.go b/vault/identity_store_structs.go index d60427b9f6..b9c4abc9c0 100644 --- a/vault/identity_store_structs.go +++ b/vault/identity_store_structs.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/vault/helper/storagepacker" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/consts" + "github.com/hashicorp/vault/sdk/helper/locksutil" "github.com/hashicorp/vault/sdk/logical" ) @@ -104,6 +105,10 @@ type IdentityStore struct { entityCreator EntityCreator mountLister MountLister mfaBackend *LoginMFABackend + + // aliasLocks is used to protect modifications to alias entries based on the uniqueness factor + // which is name + accessor + aliasLocks []*locksutil.LockEntry } type groupDiff struct { diff --git a/vault/request_handling.go b/vault/request_handling.go index 281a5982d4..725b622565 100644 --- a/vault/request_handling.go +++ b/vault/request_handling.go @@ -1659,6 +1659,7 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re var err error // Fetch the entity for the alias, or create an entity if one // doesn't exist. + entity, entityCreated, err := c.identityStore.CreateOrFetchEntity(ctx, auth.Alias) if err != nil { switch auth.Alias.Local { @@ -1666,7 +1667,7 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re // Only create a new entity if the error was a readonly error and the creation flag is true // i.e the entity was in the middle of being created if entityCreated && errors.Is(err, logical.ErrReadOnly) { - entity, err = possiblyForwardEntityCreation(ctx, c, err, auth, nil) + entity, err = registerLocalAlias(ctx, c, auth.Alias) if err != nil { if strings.Contains(err.Error(), errCreateEntityUnimplemented) { resp.AddWarning("primary cluster doesn't yet issue entities for local auth mounts; falling back to not issuing entities for local auth mounts") @@ -1676,14 +1677,14 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re } } } - err = updateLocalAlias(ctx, c, auth, entity) default: entity, entityCreated, err = possiblyForwardAliasCreation(ctx, c, err, auth, entity) + if err != nil { + return nil, nil, err + } } } - if err != nil { - return nil, nil, err - } + if entity == nil { return nil, nil, fmt.Errorf("failed to create an entity for the authenticated alias") } diff --git a/vault/request_handling_util.go b/vault/request_handling_util.go index bda5af2244..e63dce2d9f 100644 --- a/vault/request_handling_util.go +++ b/vault/request_handling_util.go @@ -68,12 +68,8 @@ func possiblyForwardAliasCreation(ctx context.Context, c *Core, inErr error, aut var errCreateEntityUnimplemented = "create entity unimplemented in the server" -func possiblyForwardEntityCreation(ctx context.Context, c *Core, inErr error, auth *logical.Auth, entity *identity.Entity) (*identity.Entity, error) { - return entity, inErr -} - -func updateLocalAlias(ctx context.Context, c *Core, auth *logical.Auth, entity *identity.Entity) error { - return nil +func registerLocalAlias(_ context.Context, _ *Core, _ *logical.Alias) (*identity.Entity, error) { + return nil, logical.ErrReadOnly } func possiblyForwardSaveCachedAuthResponse(ctx context.Context, c *Core, respAuth *MFACachedAuthResponse) error {