1package vault
2
3import (
4	"context"
5	"errors"
6	"fmt"
7	"strings"
8	"time"
9
10	memdb "github.com/hashicorp/go-memdb"
11	"github.com/hashicorp/vault/helper/namespace"
12	"github.com/hashicorp/vault/sdk/framework"
13	"github.com/hashicorp/vault/sdk/logical"
14)
15
16var (
17	invalidateMFAConfig = func(context.Context, *SystemBackend, string) {}
18
19	sysInvalidate = func(b *SystemBackend) func(context.Context, string) {
20		return nil
21	}
22
23	getSystemSchemas = func() []func() *memdb.TableSchema { return nil }
24
25	getEGPListResponseKeyInfo = func(*SystemBackend, *namespace.Namespace) map[string]interface{} { return nil }
26	addSentinelPolicyData     = func(map[string]interface{}, *Policy) {}
27	inputSentinelPolicyData   = func(*framework.FieldData, *Policy) *logical.Response { return nil }
28
29	controlGroupUnwrap = func(context.Context, *SystemBackend, string, bool) (string, error) {
30		return "", errors.New("control groups unavailable")
31	}
32
33	pathInternalUINamespacesRead = func(b *SystemBackend) framework.OperationFunc {
34		return func(ctx context.Context, req *logical.Request, _ *framework.FieldData) (*logical.Response, error) {
35			// Short-circuit here if there's no client token provided
36			if req.ClientToken == "" {
37				return nil, fmt.Errorf("client token empty")
38			}
39
40			// Load the ACL policies so we can check for access and filter namespaces
41			_, te, entity, _, err := b.Core.fetchACLTokenEntryAndEntity(ctx, req)
42			if err != nil {
43				return nil, err
44			}
45			if entity != nil && entity.Disabled {
46				b.logger.Warn("permission denied as the entity on the token is disabled")
47				return nil, logical.ErrPermissionDenied
48			}
49			if te != nil && te.EntityID != "" && entity == nil {
50				b.logger.Warn("permission denied as the entity on the token is invalid")
51				return nil, logical.ErrPermissionDenied
52			}
53
54			return logical.ListResponse([]string{""}), nil
55		}
56	}
57
58	pathLicenseRead = func(b *SystemBackend) framework.OperationFunc {
59		return func(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
60			return nil, nil
61		}
62	}
63
64	pathLicenseUpdate = func(b *SystemBackend) framework.OperationFunc {
65		return func(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
66			return nil, nil
67		}
68	}
69
70	entPaths = func(b *SystemBackend) []*framework.Path {
71		return []*framework.Path{
72			{
73				Pattern: "replication/status",
74				Callbacks: map[logical.Operation]framework.OperationFunc{
75					logical.ReadOperation: func(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
76						resp := &logical.Response{
77							Data: map[string]interface{}{
78								"mode": "disabled",
79							},
80						}
81						return resp, nil
82					},
83				},
84			},
85		}
86	}
87
88	checkRaw = func(b *SystemBackend, path string) error { return nil }
89)
90
91// tuneMount is used to set config on a mount point
92func (b *SystemBackend) tuneMountTTLs(ctx context.Context, path string, me *MountEntry, newDefault, newMax time.Duration) error {
93	zero := time.Duration(0)
94
95	switch {
96	case newDefault == zero && newMax == zero:
97		// No checks needed
98
99	case newDefault == zero && newMax != zero:
100		// No default/max conflict, no checks needed
101
102	case newDefault != zero && newMax == zero:
103		// No default/max conflict, no checks needed
104
105	case newDefault != zero && newMax != zero:
106		if newMax < newDefault {
107			return fmt.Errorf("backend max lease TTL of %d would be less than backend default lease TTL of %d", int(newMax.Seconds()), int(newDefault.Seconds()))
108		}
109	}
110
111	origMax := me.Config.MaxLeaseTTL
112	origDefault := me.Config.DefaultLeaseTTL
113
114	me.Config.MaxLeaseTTL = newMax
115	me.Config.DefaultLeaseTTL = newDefault
116
117	// Update the mount table
118	var err error
119	switch {
120	case strings.HasPrefix(path, credentialRoutePrefix):
121		err = b.Core.persistAuth(ctx, b.Core.auth, &me.Local)
122	default:
123		err = b.Core.persistMounts(ctx, b.Core.mounts, &me.Local)
124	}
125	if err != nil {
126		me.Config.MaxLeaseTTL = origMax
127		me.Config.DefaultLeaseTTL = origDefault
128		return fmt.Errorf("failed to update mount table, rolling back TTL changes")
129	}
130	if b.Core.logger.IsInfo() {
131		b.Core.logger.Info("mount tuning of leases successful", "path", path)
132	}
133
134	return nil
135}
136