diff --git a/CHANGELOG.md b/CHANGELOG.md index 54cf5b1b5..a2a087eb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,9 @@ BUG FIXES: parent prefix entry in the underlying storage backend. These operations also mark corresponding child tokens as orphans by removing the parent/secondary index from the entries. [GH-4193] + * core: Fix issue occurring from mounting two auth backends with the same path + with one mount having `auth/` in front [GH-4206] + * mfa: Invalidation of MFA configurations (Enterprise) * replication: Fix a panic on some non-64-bit platforms * replication: Fix invalidation of policies on performance secondaries diff --git a/vault/auth.go b/vault/auth.go index eb9e28c8b..523dab2b1 100644 --- a/vault/auth.go +++ b/vault/auth.go @@ -459,11 +459,6 @@ func (c *Core) setupCredentials(ctx context.Context) error { for _, entry := range c.auth.Entries { var backend logical.Backend - // Work around some problematic code that existed in master for a while - if strings.HasPrefix(entry.Path, credentialRoutePrefix) { - entry.Path = strings.TrimPrefix(entry.Path, credentialRoutePrefix) - persistNeeded = true - } // Create a barrier view using the UUID viewPath := credentialBarrierPrefix + entry.UUID + "/" diff --git a/vault/router_ext_test.go b/vault/router_ext_test.go new file mode 100644 index 000000000..78aa76e38 --- /dev/null +++ b/vault/router_ext_test.go @@ -0,0 +1,52 @@ +package vault_test + +import ( + "testing" + + "github.com/hashicorp/vault/api" + "github.com/hashicorp/vault/builtin/credential/userpass" + vaulthttp "github.com/hashicorp/vault/http" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/vault" +) + +func TestRouter_MountSubpath_Checks(t *testing.T) { + testRouter_MountSubpath(t, []string{"auth/abcd/123", "abcd/123"}) + testRouter_MountSubpath(t, []string{"abcd/123", "auth/abcd/123"}) + testRouter_MountSubpath(t, []string{"auth/abcd/123", "abcd/123"}) +} + +func testRouter_MountSubpath(t *testing.T, mountPoints []string) { + coreConfig := &vault.CoreConfig{ + CredentialBackends: map[string]logical.Factory{ + "userpass": userpass.Factory, + }, + } + cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{ + HandlerFunc: vaulthttp.Handler, + }) + cluster.Start() + defer cluster.Cleanup() + + vault.TestWaitActive(t, cluster.Cores[0].Core) + client := cluster.Cores[0].Client + + authInput := &api.EnableAuthOptions{ + Type: "userpass", + } + + for _, mp := range mountPoints { + t.Logf("mounting %s", mp) + var err error + err = client.Sys().EnableAuthWithOptions(mp, authInput) + if err != nil { + t.Fatalf("err: %v", err) + } + } + + cluster.EnsureCoresSealed(t) + + cluster.UnsealCores(t) + + t.Logf("Done: %#v", mountPoints) +} diff --git a/vault/testing.go b/vault/testing.go index f6535edf7..77168d0de 100644 --- a/vault/testing.go +++ b/vault/testing.go @@ -768,6 +768,53 @@ func (c *TestCluster) Start() { } } +// UnsealCores uses the cluster barrier keys to unseal the test cluster cores +func (c *TestCluster) UnsealCores(t testing.T) { + numCores := len(c.Cores) + + // Unseal first core + for _, key := range c.BarrierKeys { + if _, err := c.Cores[0].Unseal(TestKeyCopy(key)); err != nil { + t.Fatalf("unseal err: %s", err) + } + } + + // Verify unsealed + sealed, err := c.Cores[0].Sealed() + if err != nil { + t.Fatalf("err checking seal status: %s", err) + } + if sealed { + t.Fatal("should not be sealed") + } + + TestWaitActive(t, c.Cores[0].Core) + + // Unseal other cores + for i := 1; i < numCores; i++ { + for _, key := range c.BarrierKeys { + if _, err := c.Cores[i].Core.Unseal(TestKeyCopy(key)); err != nil { + t.Fatalf("unseal err: %s", err) + } + } + } + + // Let them come fully up to standby + time.Sleep(2 * time.Second) + + // Ensure cluster connection info is populated. + // Other cores should not come up as leaders. + for i := 1; i < numCores; i++ { + isLeader, _, _, err := c.Cores[i].Leader() + if err != nil { + t.Fatal(err) + } + if isLeader { + t.Fatalf("core[%d] should not be leader", i) + } + } +} + func (c *TestCluster) EnsureCoresSealed(t testing.T) { t.Helper() if err := c.ensureCoresSealed(); err != nil {