diff --git a/changelog/22355.txt b/changelog/22355.txt new file mode 100644 index 0000000000..d748796c1d --- /dev/null +++ b/changelog/22355.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: Fix bug where background thread to update locked user entries runs on DR secondaries. +``` \ No newline at end of file diff --git a/vault/core.go b/vault/core.go index 2cc08b8f31..c14d77c30f 100644 --- a/vault/core.go +++ b/vault/core.go @@ -647,6 +647,8 @@ type Core struct { autoRotateCancel context.CancelFunc + updateLockedUserEntriesCancel context.CancelFunc + // number of workers to use for lease revocation in the expiration manager numExpirationWorkers int @@ -2320,12 +2322,9 @@ func (s standardUnsealStrategy) unseal(ctx context.Context, logger log.Logger, c if err := c.setupHeaderHMACKey(ctx, false); err != nil { return err } - if err := c.runLockedUserEntryUpdates(ctx); err != nil { - return err - } - c.updateLockedUserEntries() - if !c.IsDRSecondary() { + c.updateLockedUserEntries() + if err := c.startRollback(); err != nil { return err } @@ -2592,6 +2591,11 @@ func (c *Core) preSeal() error { c.autoRotateCancel = nil } + if c.updateLockedUserEntriesCancel != nil { + c.updateLockedUserEntriesCancel() + c.updateLockedUserEntriesCancel = nil + } + if seal, ok := c.seal.(*autoSeal); ok { seal.StopHealthCheck() } @@ -3448,16 +3452,26 @@ func (c *Core) setupCachedMFAResponseAuth() { // updateLockedUserEntries runs every 15 mins to remove stale user entries from storage // it also updates the userFailedLoginInfo map with correct information for locked users if incorrect func (c *Core) updateLockedUserEntries() { - ctx := c.activeContext + if c.updateLockedUserEntriesCancel != nil { + return + } + + var updateLockedUserEntriesCtx context.Context + updateLockedUserEntriesCtx, c.updateLockedUserEntriesCancel = context.WithCancel(c.activeContext) + + if err := c.runLockedUserEntryUpdates(updateLockedUserEntriesCtx); err != nil { + c.Logger().Error("failed to run locked user entry updates", "error", err) + } + go func() { ticker := time.NewTicker(15 * time.Minute) for { select { - case <-ctx.Done(): + case <-updateLockedUserEntriesCtx.Done(): ticker.Stop() return case <-ticker.C: - if err := c.runLockedUserEntryUpdates(ctx); err != nil { + if err := c.runLockedUserEntryUpdates(updateLockedUserEntriesCtx); err != nil { c.Logger().Error("failed to run locked user entry updates", "error", err) } }