diff --git a/builtin/logical/database/backend.go b/builtin/logical/database/backend.go index 970583ef850a..5e6bfada625e 100644 --- a/builtin/logical/database/backend.go +++ b/builtin/logical/database/backend.go @@ -291,6 +291,18 @@ func (b *databaseBackend) GetConnection(ctx context.Context, s logical.Storage, return b.GetConnectionWithConfig(ctx, name, config) } +func (b *databaseBackend) GetConnectionSkipVerify(ctx context.Context, s logical.Storage, name string) (*dbPluginInstance, error) { + config, err := b.DatabaseConfig(ctx, s, name) + if err != nil { + return nil, err + } + + // Force the skip verifying the connection + config.VerifyConnection = false + + return b.GetConnectionWithConfig(ctx, name, config) +} + func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name string, config *DatabaseConfig) (*dbPluginInstance, error) { // fast path, reuse the existing connection dbi := b.connections.Get(name) @@ -331,7 +343,7 @@ func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name stri initReq := v5.InitializeRequest{ Config: config.ConnectionDetails, - VerifyConnection: true, + VerifyConnection: config.VerifyConnection, } _, err = dbw.Initialize(ctx, initReq) if err != nil { diff --git a/builtin/logical/database/backend_test.go b/builtin/logical/database/backend_test.go index f5ba7246fcbe..1573d2146ac9 100644 --- a/builtin/logical/database/backend_test.go +++ b/builtin/logical/database/backend_test.go @@ -210,6 +210,7 @@ func TestBackend_config_connection(t *testing.T) { "root_credentials_rotate_statements": []string{}, "password_policy": "", "plugin_version": "", + "verify_connection": false, } configReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(namespace.RootContext(nil), configReq) @@ -264,6 +265,7 @@ func TestBackend_config_connection(t *testing.T) { "root_credentials_rotate_statements": []string{}, "password_policy": "", "plugin_version": "", + "verify_connection": false, } configReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(namespace.RootContext(nil), configReq) @@ -307,6 +309,7 @@ func TestBackend_config_connection(t *testing.T) { "root_credentials_rotate_statements": []string{}, "password_policy": "", "plugin_version": "", + "verify_connection": false, } configReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(namespace.RootContext(nil), configReq) @@ -764,6 +767,7 @@ func TestBackend_connectionCrud(t *testing.T) { "root_credentials_rotate_statements": []any{}, "password_policy": "", "plugin_version": "", + "verify_connection": false, } resp, err = client.Read("database/config/plugin-test") if err != nil { diff --git a/builtin/logical/database/path_config_connection.go b/builtin/logical/database/path_config_connection.go index 2f8f40a1bf04..0f373f371d74 100644 --- a/builtin/logical/database/path_config_connection.go +++ b/builtin/logical/database/path_config_connection.go @@ -40,7 +40,8 @@ type DatabaseConfig struct { RootCredentialsRotateStatements []string `json:"root_credentials_rotate_statements" structs:"root_credentials_rotate_statements" mapstructure:"root_credentials_rotate_statements"` - PasswordPolicy string `json:"password_policy" structs:"password_policy" mapstructure:"password_policy"` + PasswordPolicy string `json:"password_policy" structs:"password_policy" mapstructure:"password_policy"` + VerifyConnection bool `json:"verify_connection" structs:"verify_connection" mapstructure:"verify_connection"` } func (c *DatabaseConfig) SupportsCredentialType(credentialType v5.CredentialType) bool { @@ -378,7 +379,7 @@ func (b *databaseBackend) connectionReadHandler() framework.OperationFunc { delete(config.ConnectionDetails, "service_account_json") resp := &logical.Response{} - if dbi, err := b.GetConnection(ctx, req.Storage, name); err == nil { + if dbi, err := b.GetConnectionSkipVerify(ctx, req.Storage, name); err == nil { config.RunningPluginVersion = dbi.runningPluginVersion if config.PluginVersion != "" && config.PluginVersion != config.RunningPluginVersion { warning := fmt.Sprintf("Plugin version is configured as %q, but running %q", config.PluginVersion, config.RunningPluginVersion) @@ -422,15 +423,15 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc { // both builtin and plugin database types. func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc { return func(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - verifyConnection := data.Get("verify_connection").(bool) - name := data.Get("name").(string) if name == "" { return logical.ErrorResponse(respErrEmptyName), nil } // Baseline - config := &DatabaseConfig{} + config := &DatabaseConfig{ + VerifyConnection: true, + } entry, err := req.Storage.Get(ctx, fmt.Sprintf("config/%s", name)) if err != nil { @@ -442,6 +443,13 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc { } } + // If this value was provided as part of the request we want to set it to this value + if verifyConnectionRaw, ok := data.GetOk("verify_connection"); ok { + config.VerifyConnection = verifyConnectionRaw.(bool) + } else if req.Operation == logical.CreateOperation { + config.VerifyConnection = data.Get("verify_connection").(bool) + } + if pluginNameRaw, ok := data.GetOk("plugin_name"); ok { config.PluginName = pluginNameRaw.(string) } else if req.Operation == logical.CreateOperation { @@ -509,7 +517,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc { initReq := v5.InitializeRequest{ Config: config.ConnectionDetails, - VerifyConnection: verifyConnection, + VerifyConnection: config.VerifyConnection, } initResp, err := dbw.Initialize(ctx, initReq) if err != nil { diff --git a/changelog/28139.txt b/changelog/28139.txt new file mode 100644 index 000000000000..f538ddf769dd --- /dev/null +++ b/changelog/28139.txt @@ -0,0 +1,3 @@ +```release-note:bug +secrets/database: Skip connection verification on reading existing DB connection configuration +``` \ No newline at end of file