Vault 3992 ToB Config and Plugins Permissions (#14817)
* updating changes from ent PR * adding changelog * fixing err * fixing semgrep error
This commit is contained in:
parent
9f03f86077
commit
796003ddda
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
core : check uid and permissions of config dir, config file, plugin dir and plugin binaries
|
||||
```
|
|
@ -2518,6 +2518,8 @@ func createCoreConfig(c *ServerCommand, config *server.Config, backend physical.
|
|||
ClusterName: config.ClusterName,
|
||||
CacheSize: config.CacheSize,
|
||||
PluginDirectory: config.PluginDirectory,
|
||||
PluginFileUid: config.PluginFileUid,
|
||||
PluginFilePermissions: config.PluginFilePermissions,
|
||||
EnableUI: config.EnableUI,
|
||||
EnableRaw: config.EnableRawEndpoint,
|
||||
DisableSealWrap: config.DisableSealWrap,
|
||||
|
@ -2535,6 +2537,7 @@ func createCoreConfig(c *ServerCommand, config *server.Config, backend physical.
|
|||
LicensePath: config.LicensePath,
|
||||
DisableSSCTokens: config.DisableSSCTokens,
|
||||
}
|
||||
|
||||
if c.flagDev {
|
||||
coreConfig.EnableRaw = true
|
||||
coreConfig.DevToken = c.flagDevRootTokenID
|
||||
|
|
|
@ -16,7 +16,9 @@ import (
|
|||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
"github.com/hashicorp/hcl"
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
"github.com/hashicorp/vault/helper/osutil"
|
||||
"github.com/hashicorp/vault/internalshared/configutil"
|
||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||
)
|
||||
|
||||
var entConfigValidate = func(_ *Config, _ string) []configutil.ConfigError {
|
||||
|
@ -54,6 +56,11 @@ type Config struct {
|
|||
|
||||
PluginDirectory string `hcl:"plugin_directory"`
|
||||
|
||||
PluginFileUid int `hcl:"plugin_file_uid"`
|
||||
|
||||
PluginFilePermissions int `hcl:"-"`
|
||||
PluginFilePermissionsRaw interface{} `hcl:"plugin_file_permissions,alias:PluginFilePermissions"`
|
||||
|
||||
EnableRawEndpoint bool `hcl:"-"`
|
||||
EnableRawEndpointRaw interface{} `hcl:"raw_storage_endpoint,alias:EnableRawEndpoint"`
|
||||
|
||||
|
@ -127,7 +134,6 @@ telemetry {
|
|||
prometheus_retention_time = "24h"
|
||||
disable_hostname = true
|
||||
}
|
||||
|
||||
enable_raw_endpoint = true
|
||||
|
||||
storage "%s" {
|
||||
|
@ -276,6 +282,17 @@ func (c *Config) Merge(c2 *Config) *Config {
|
|||
result.PluginDirectory = c2.PluginDirectory
|
||||
}
|
||||
|
||||
result.PluginFileUid = c.PluginFileUid
|
||||
if c2.PluginFileUid != 0 {
|
||||
result.PluginFileUid = c2.PluginFileUid
|
||||
}
|
||||
|
||||
result.PluginFilePermissions = c.PluginFilePermissions
|
||||
if c2.PluginFilePermissionsRaw != nil {
|
||||
result.PluginFilePermissions = c2.PluginFilePermissions
|
||||
result.PluginFilePermissionsRaw = c2.PluginFilePermissionsRaw
|
||||
}
|
||||
|
||||
result.DisablePerformanceStandby = c.DisablePerformanceStandby
|
||||
if c2.DisablePerformanceStandby {
|
||||
result.DisablePerformanceStandby = c2.DisablePerformanceStandby
|
||||
|
@ -350,6 +367,13 @@ func LoadConfig(path string) (*Config, error) {
|
|||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
// check permissions on the config directory
|
||||
if os.Getenv(consts.VaultDisableFilePermissionsCheckEnv) != "true" {
|
||||
err = osutil.OwnerPermissionsMatch(path, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return CheckConfig(LoadConfigDir(path))
|
||||
}
|
||||
return CheckConfig(LoadConfigFile(path))
|
||||
|
@ -385,6 +409,21 @@ func LoadConfigFile(path string) (*Config, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if os.Getenv(consts.VaultDisableFilePermissionsCheckEnv) != "true" {
|
||||
// check permissions of the config file
|
||||
err = osutil.OwnerPermissionsMatch(path, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// check permissions of the plugin directory
|
||||
if conf.PluginDirectory != "" {
|
||||
|
||||
err = osutil.OwnerPermissionsMatch(conf.PluginDirectory, conf.PluginFileUid, conf.PluginFilePermissions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
|
@ -459,6 +498,18 @@ func ParseConfig(d, source string) (*Config, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if result.PluginFilePermissionsRaw != nil {
|
||||
octalPermissionsString, err := parseutil.ParseString(result.PluginFilePermissionsRaw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pluginFilePermissions, err := strconv.ParseInt(octalPermissionsString, 8, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.PluginFilePermissions = int(pluginFilePermissions)
|
||||
}
|
||||
|
||||
if result.DisableSentinelTraceRaw != nil {
|
||||
if result.DisableSentinelTrace, err = parseutil.ParseBool(result.DisableSentinelTraceRaw); err != nil {
|
||||
return nil, err
|
||||
|
@ -838,6 +889,10 @@ func (c *Config) Sanitized() map[string]interface{} {
|
|||
|
||||
"plugin_directory": c.PluginDirectory,
|
||||
|
||||
"plugin_file_uid": c.PluginFileUid,
|
||||
|
||||
"plugin_file_permissions": c.PluginFilePermissions,
|
||||
|
||||
"raw_storage_endpoint": c.EnableRawEndpoint,
|
||||
|
||||
"api_addr": c.APIAddr,
|
||||
|
|
|
@ -694,6 +694,8 @@ func testConfig_Sanitized(t *testing.T) {
|
|||
"disable_indexing": false,
|
||||
"disable_mlock": true,
|
||||
"disable_performance_standby": false,
|
||||
"plugin_file_uid": 0,
|
||||
"plugin_file_permissions": 0,
|
||||
"disable_printable_check": false,
|
||||
"disable_sealwrap": true,
|
||||
"raw_storage_endpoint": true,
|
||||
|
@ -855,6 +857,7 @@ func testParseSockaddrTemplate(t *testing.T) {
|
|||
api_addr = <<EOF
|
||||
{{- GetAllInterfaces | include "flags" "loopback" | include "type" "ipv4" | attr "address" -}}
|
||||
EOF
|
||||
|
||||
listener "tcp" {
|
||||
address = <<EOF
|
||||
{{- GetAllInterfaces | include "flags" "loopback" | include "type" "ipv4" | attr "address" -}}:443
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package osutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
)
|
||||
|
||||
func IsWriteGroup(mode os.FileMode) bool {
|
||||
return mode&0o20 != 0
|
||||
}
|
||||
|
||||
func IsWriteOther(mode os.FileMode) bool {
|
||||
return mode&0o02 != 0
|
||||
}
|
||||
|
||||
func checkPathInfo(info fs.FileInfo, path string, uid int, permissions int) error {
|
||||
err := FileUidMatch(info, path, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = FilePermissionsMatch(info, path, permissions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FilePermissionsMatch(info fs.FileInfo, path string, permissions int) error {
|
||||
if permissions != 0 && int(info.Mode().Perm()) != permissions {
|
||||
return fmt.Errorf("path %q does not have permissions %o", path, permissions)
|
||||
}
|
||||
if permissions == 0 && (IsWriteOther(info.Mode()) || IsWriteGroup(info.Mode())) {
|
||||
return fmt.Errorf("path %q has insecure permissions %o. Vault expects no write permissions for group or others", path, info.Mode().Perm())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OwnerPermissionsMatch checks if vault user is the owner and permissions are secure for input path
|
||||
func OwnerPermissionsMatch(path string, uid int, permissions int) error {
|
||||
if path == "" {
|
||||
return fmt.Errorf("could not verify permissions for path. No path provided ")
|
||||
}
|
||||
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error stating %q: %w", path, err)
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
symLinkInfo, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error stating %q: %w", path, err)
|
||||
}
|
||||
err = checkPathInfo(symLinkInfo, path, uid, permissions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = checkPathInfo(info, path, uid, permissions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package osutil
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCheckPathInfo(t *testing.T) {
|
||||
currentUser, err := user.Current()
|
||||
if err != nil {
|
||||
t.Errorf("failed to get details of current process owner. The error is: %v", err)
|
||||
}
|
||||
uid, err := strconv.ParseInt(currentUser.Uid, 0, 64)
|
||||
if err != nil {
|
||||
t.Errorf("failed to convert uid to int64. The error is: %v", err)
|
||||
}
|
||||
uid2, err := strconv.ParseInt(currentUser.Uid+"1", 0, 64)
|
||||
if err != nil {
|
||||
t.Errorf("failed to convert uid to int64. The error is: %v", err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
uid int
|
||||
filepermissions fs.FileMode
|
||||
permissions int
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
uid: 0,
|
||||
filepermissions: 0o700,
|
||||
permissions: 0,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
uid: int(uid2),
|
||||
filepermissions: 0o700,
|
||||
permissions: 0,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
uid: int(uid),
|
||||
filepermissions: 0o700,
|
||||
permissions: 0,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
uid: 0,
|
||||
filepermissions: 0o777,
|
||||
permissions: 744,
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
err := os.Mkdir("testFile", tc.filepermissions)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
info, err := os.Stat("testFile")
|
||||
if err != nil {
|
||||
t.Errorf("error stating %q: %v", "testFile", err)
|
||||
}
|
||||
if tc.uid != 0 && runtime.GOOS == "windows" && tc.expectError == true {
|
||||
t.Skip("Skipping test in windows environment as no error will be returned in this case")
|
||||
}
|
||||
|
||||
err = checkPathInfo(info, "testFile", tc.uid, int(tc.permissions))
|
||||
if tc.expectError && err == nil {
|
||||
t.Errorf("invalid result. expected error")
|
||||
}
|
||||
if !tc.expectError && err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
|
||||
err = os.RemoveAll("testFile")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//go:build !windows
|
||||
|
||||
package osutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os/user"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func FileUIDEqual(info fs.FileInfo, uid int) bool {
|
||||
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
|
||||
path_uid := int(stat.Uid)
|
||||
if path_uid == uid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func FileGIDEqual(info fs.FileInfo, gid int) bool {
|
||||
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
|
||||
path_gid := int(stat.Gid)
|
||||
if path_gid == gid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func FileUidMatch(info fs.FileInfo, path string, uid int) (err error) {
|
||||
currentUser, err := user.Current()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get details of current process owner. The error is: %w", err)
|
||||
}
|
||||
switch uid {
|
||||
case 0:
|
||||
currentUserUid, err := strconv.Atoi(currentUser.Uid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert uid %q to int. The error is: %w", currentUser.Uid, err)
|
||||
}
|
||||
if !FileUIDEqual(info, currentUserUid) {
|
||||
return fmt.Errorf("path %q is not owned by my uid %s", path, currentUser.Uid)
|
||||
}
|
||||
default:
|
||||
if !FileUIDEqual(info, uid) {
|
||||
return fmt.Errorf("path %q is not owned by uid %d", path, uid)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
//go:build !windows
|
||||
|
||||
package osutil
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/user"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFileUIDEqual(t *testing.T) {
|
||||
currentUser, err := user.Current()
|
||||
if err != nil {
|
||||
t.Errorf("failed to get details of current process owner. The error is: %v", err)
|
||||
}
|
||||
uid, err := strconv.Atoi(currentUser.Uid)
|
||||
if err != nil {
|
||||
t.Errorf("failed to convert uid to int. The error is: %v", err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
uid int
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
uid: uid,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
uid: uid + 1,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
err := os.Mkdir("testFile", 0o777)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
info, err := os.Stat("testFile")
|
||||
if err != nil {
|
||||
t.Errorf("error stating %q: %v", "testFile", err)
|
||||
}
|
||||
|
||||
result := FileUIDEqual(info, tc.uid)
|
||||
if result != tc.expected {
|
||||
t.Errorf("invalid result. expected %t for uid %v", tc.expected, tc.uid)
|
||||
}
|
||||
err = os.RemoveAll("testFile")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileGIDEqual(t *testing.T) {
|
||||
currentUser, err := user.Current()
|
||||
if err != nil {
|
||||
t.Errorf("failed to get details of current process owner. The error is: %v", err)
|
||||
}
|
||||
gid, err := strconv.Atoi(currentUser.Gid)
|
||||
if err != nil {
|
||||
t.Errorf("failed to convert gid to int. The error is: %v", err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
gid int
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
gid: gid,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
gid: gid + 1,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
err := os.Mkdir("testFile", 0o777)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
info, err := os.Stat("testFile")
|
||||
if err != nil {
|
||||
t.Errorf("error stating %q: %v", "testFile", err)
|
||||
}
|
||||
|
||||
result := FileGIDEqual(info, tc.gid)
|
||||
if result != tc.expected {
|
||||
t.Errorf("invalid result. expected %t for gid %v", tc.expected, tc.gid)
|
||||
}
|
||||
err = os.RemoveAll("testFile")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
//go:build windows
|
||||
|
||||
package osutil
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
func FileUidMatch(info fs.FileInfo, path string, uid int) error {
|
||||
return nil
|
||||
}
|
|
@ -31,6 +31,7 @@ func getPluginClusterAndCore(t testing.TB, logger log.Logger) (*vault.TestCluste
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Setenv(consts.VaultDisableFilePermissionsCheckEnv, "true")
|
||||
|
||||
coreConfig := &vault.CoreConfig{
|
||||
Physical: inm,
|
||||
|
|
|
@ -46,6 +46,8 @@ func TestSysConfigState_Sanitized(t *testing.T) {
|
|||
"max_lease_ttl": json.Number("0"),
|
||||
"pid_file": "",
|
||||
"plugin_directory": "",
|
||||
"plugin_file_uid": json.Number("0"),
|
||||
"plugin_file_permissions": json.Number("0"),
|
||||
"enable_response_header_hostname": false,
|
||||
"enable_response_header_raft_node_id": false,
|
||||
"log_requests_level": "",
|
||||
|
|
|
@ -32,4 +32,6 @@ const (
|
|||
// ReplicationResolverALPN is the negotiated protocol used for
|
||||
// resolving replicaiton addresses
|
||||
ReplicationResolverALPN = "replication_resolver_v1"
|
||||
|
||||
VaultDisableFilePermissionsCheckEnv = "VAULT_DISABLE_FILE_PERMISSIONS_CHECK"
|
||||
)
|
||||
|
|
|
@ -915,7 +915,7 @@ func (c *Core) newCredentialBackend(ctx context.Context, entry *MountEntry, sysV
|
|||
|
||||
f, ok := c.credentialBackends[t]
|
||||
if !ok {
|
||||
f = plugin.Factory
|
||||
f = wrapFactoryCheckPerms(c, plugin.Factory)
|
||||
}
|
||||
|
||||
// Set up conf to pass in plugin_name
|
||||
|
|
|
@ -37,6 +37,7 @@ import (
|
|||
"github.com/hashicorp/vault/command/server"
|
||||
"github.com/hashicorp/vault/helper/metricsutil"
|
||||
"github.com/hashicorp/vault/helper/namespace"
|
||||
"github.com/hashicorp/vault/helper/osutil"
|
||||
"github.com/hashicorp/vault/physical/raft"
|
||||
"github.com/hashicorp/vault/sdk/helper/certutil"
|
||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||
|
@ -487,6 +488,12 @@ type Core struct {
|
|||
// pluginDirectory is the location vault will look for plugin binaries
|
||||
pluginDirectory string
|
||||
|
||||
// pluginFileUid is the uid of the plugin files and directory
|
||||
pluginFileUid int
|
||||
|
||||
// pluginFilePermissions is the permissions of the plugin files and directory
|
||||
pluginFilePermissions int
|
||||
|
||||
// pluginCatalog is used to manage plugin configurations
|
||||
pluginCatalog *PluginCatalog
|
||||
|
||||
|
@ -684,6 +691,10 @@ type CoreConfig struct {
|
|||
|
||||
PluginDirectory string
|
||||
|
||||
PluginFileUid int
|
||||
|
||||
PluginFilePermissions int
|
||||
|
||||
DisableSealWrap bool
|
||||
|
||||
RawConfig *server.Config
|
||||
|
@ -998,6 +1009,13 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if conf.PluginFileUid != 0 {
|
||||
c.pluginFileUid = conf.PluginFileUid
|
||||
}
|
||||
if conf.PluginFilePermissions != 0 {
|
||||
c.pluginFilePermissions = conf.PluginFilePermissions
|
||||
}
|
||||
|
||||
createSecondaries(c, conf)
|
||||
|
||||
if conf.HAPhysical != nil && conf.HAPhysical.HAEnabled() {
|
||||
|
@ -3201,3 +3219,18 @@ func (c *Core) GetHAPeerNodesCached() []PeerNode {
|
|||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (c *Core) CheckPluginPerms(pluginName string) (err error) {
|
||||
if c.pluginDirectory != "" && os.Getenv(consts.VaultDisableFilePermissionsCheckEnv) != "true" {
|
||||
err = osutil.OwnerPermissionsMatch(c.pluginDirectory, c.pluginFileUid, c.pluginFilePermissions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fullPath := filepath.Join(c.pluginDirectory, pluginName)
|
||||
err = osutil.OwnerPermissionsMatch(fullPath, c.pluginFileUid, c.pluginFilePermissions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -4,17 +4,17 @@ package diagnose
|
|||
|
||||
import (
|
||||
"io/fs"
|
||||
"syscall"
|
||||
|
||||
"github.com/hashicorp/vault/helper/osutil"
|
||||
)
|
||||
|
||||
// IsOwnedByRoot checks if a file is owned by root
|
||||
func IsOwnedByRoot(info fs.FileInfo) bool {
|
||||
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
|
||||
uid := int(stat.Uid)
|
||||
gid := int(stat.Gid)
|
||||
if uid == 0 && gid == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if !osutil.FileUIDEqual(info, 0) {
|
||||
return false
|
||||
}
|
||||
if !osutil.FileGIDEqual(info, 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -450,6 +450,10 @@ func (b *SystemBackend) handlePluginCatalogUpdate(ctx context.Context, req *logi
|
|||
return logical.ErrorResponse("missing command value"), nil
|
||||
}
|
||||
|
||||
if err = b.Core.CheckPluginPerms(command); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// For backwards compatibility, also accept args as part of command. Don't
|
||||
// accepts args in both command and args.
|
||||
args := d.Get("args").([]string)
|
||||
|
|
|
@ -530,6 +530,8 @@ func testSystemBackendMock(t *testing.T, numCores, numMounts int, backendType lo
|
|||
},
|
||||
}
|
||||
|
||||
os.Setenv(consts.VaultDisableFilePermissionsCheckEnv, "true")
|
||||
|
||||
// Create a tempdir, cluster.Cleanup will clean up this directory
|
||||
tempDir, err := ioutil.TempDir("", "vault-test-cluster")
|
||||
if err != nil {
|
||||
|
@ -602,7 +604,7 @@ func testSystemBackend_SingleCluster_Env(t *testing.T, env []string) *vault.Test
|
|||
"test": plugin.Factory,
|
||||
},
|
||||
}
|
||||
|
||||
os.Setenv(consts.VaultDisableFilePermissionsCheckEnv, "true")
|
||||
// Create a tempdir, cluster.Cleanup will clean up this directory
|
||||
tempDir, err := ioutil.TempDir("", "vault-test-cluster")
|
||||
if err != nil {
|
||||
|
|
|
@ -1395,7 +1395,7 @@ func (c *Core) newLogicalBackend(ctx context.Context, entry *MountEntry, sysView
|
|||
|
||||
f, ok := c.logicalBackends[t]
|
||||
if !ok {
|
||||
f = plugin.Factory
|
||||
f = wrapFactoryCheckPerms(c, plugin.Factory)
|
||||
}
|
||||
|
||||
// Set up conf to pass in plugin_name
|
||||
|
|
|
@ -81,6 +81,15 @@ type pluginClient struct {
|
|||
plugin.ClientProtocol
|
||||
}
|
||||
|
||||
func wrapFactoryCheckPerms(core *Core, f logical.Factory) logical.Factory {
|
||||
return func(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) {
|
||||
if err := core.CheckPluginPerms(conf.Config["plugin_name"]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f(ctx, conf)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Core) setupPluginCatalog(ctx context.Context) error {
|
||||
c.pluginCatalog = &PluginCatalog{
|
||||
builtinRegistry: c.builtinRegistry,
|
||||
|
|
Loading…
Reference in New Issue