When tainting a route during setup, pre-calculate the namespace specific path (#15067)
This commit is contained in:
parent
d6933e9ef4
commit
a4593e8913
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
core: pre-calculate namespace specific paths when tainting a route during postUnseal
|
||||||
|
```
|
|
@ -3,6 +3,7 @@ package namespace
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||||
|
@ -15,6 +16,10 @@ type Namespace struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Namespace) String() string {
|
||||||
|
return fmt.Sprintf("ID: %s. Path: %s", n.ID, n.Path)
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RootNamespaceID = "root"
|
RootNamespaceID = "root"
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/hashicorp/vault/builtin/plugin"
|
"github.com/hashicorp/vault/builtin/plugin"
|
||||||
"github.com/hashicorp/vault/helper/namespace"
|
"github.com/hashicorp/vault/helper/namespace"
|
||||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||||
|
@ -825,16 +825,19 @@ func (c *Core) setupCredentials(ctx context.Context) error {
|
||||||
path := credentialRoutePrefix + entry.Path
|
path := credentialRoutePrefix + entry.Path
|
||||||
err = c.router.Mount(backend, path, entry, view)
|
err = c.router.Mount(backend, path, entry, view)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("failed to mount auth entry", "path", entry.Path, "error", err)
|
c.logger.Error("failed to mount auth entry", "path", entry.Path, "namespace", entry.Namespace(), "error", err)
|
||||||
return errLoadAuthFailed
|
return errLoadAuthFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.logger.IsInfo() {
|
if c.logger.IsInfo() {
|
||||||
c.logger.Info("successfully enabled credential backend", "type", entry.Type, "path", entry.Path)
|
c.logger.Info("successfully enabled credential backend", "type", entry.Type, "path", entry.Path, "namespace", entry.Namespace())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the path is tainted if set in the mount table
|
// Ensure the path is tainted if set in the mount table
|
||||||
if entry.Tainted {
|
if entry.Tainted {
|
||||||
|
// Calculate any namespace prefixes here, because when Taint() is called, there won't be
|
||||||
|
// a namespace to pull from the context. This is similar to what we do above in c.router.Mount().
|
||||||
|
path = entry.Namespace().Path + path
|
||||||
c.router.Taint(ctx, path)
|
c.router.Taint(ctx, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/hashicorp/go-hclog"
|
log "github.com/hashicorp/go-hclog"
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/helper/namespace"
|
"github.com/hashicorp/vault/helper/namespace"
|
||||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,9 +9,9 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
metrics "github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
radix "github.com/armon/go-radix"
|
"github.com/armon/go-radix"
|
||||||
hclog "github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||||
"github.com/hashicorp/vault/helper/namespace"
|
"github.com/hashicorp/vault/helper/namespace"
|
||||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||||
|
@ -47,6 +47,8 @@ func NewRouter() *Router {
|
||||||
storagePrefix: radix.New(),
|
storagePrefix: radix.New(),
|
||||||
mountUUIDCache: radix.New(),
|
mountUUIDCache: radix.New(),
|
||||||
mountAccessorCache: radix.New(),
|
mountAccessorCache: radix.New(),
|
||||||
|
// this will get replaced in production with a real logger but it's useful to have a default in place for tests
|
||||||
|
logger: hclog.NewNullLogger(),
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
@ -530,7 +532,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
}
|
}
|
||||||
r.l.RUnlock()
|
r.l.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath
|
return logical.ErrorResponse(fmt.Sprintf("no handler for route %q. route entry not found.", req.Path)), false, false, logical.ErrUnsupportedPath
|
||||||
}
|
}
|
||||||
req.Path = adjustedPath
|
req.Path = adjustedPath
|
||||||
defer metrics.MeasureSince([]string{
|
defer metrics.MeasureSince([]string{
|
||||||
|
@ -551,7 +553,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
|
|
||||||
// Filtered mounts will have a nil backend
|
// Filtered mounts will have a nil backend
|
||||||
if re.backend == nil {
|
if re.backend == nil {
|
||||||
return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath
|
return logical.ErrorResponse(fmt.Sprintf("no handler for route %q. route entry found, but backend is nil.", req.Path)), false, false, logical.ErrUnsupportedPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the path is tainted, we reject any operation except for
|
// If the path is tainted, we reject any operation except for
|
||||||
|
@ -560,7 +562,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
switch req.Operation {
|
switch req.Operation {
|
||||||
case logical.RevokeOperation, logical.RollbackOperation:
|
case logical.RevokeOperation, logical.RollbackOperation:
|
||||||
default:
|
default:
|
||||||
return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath
|
return logical.ErrorResponse(fmt.Sprintf("no handler for route %q. route entry is tainted.", req.Path)), false, false, logical.ErrUnsupportedPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/hashicorp/vault/helper/namespace"
|
"github.com/hashicorp/vault/helper/namespace"
|
||||||
"github.com/hashicorp/vault/sdk/logical"
|
"github.com/hashicorp/vault/sdk/logical"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue