Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VAULT-3379] Add support for contained DBs in MSSQL root rotation and lease revocation #12839

Merged
merged 10 commits into from Oct 19, 2021
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -37,7 +37,7 @@ require (
github.com/containerd/containerd v1.4.3 // indirect
github.com/coreos/go-semver v0.3.0
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc
github.com/denisenkom/go-mssqldb v0.11.0
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
github.com/docker/go-connections v0.4.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -305,6 +305,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI=
github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o=
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
Expand Down
40 changes: 36 additions & 4 deletions plugins/database/mssql/mssql.go
Expand Up @@ -30,6 +30,9 @@ type MSSQL struct {
*connutil.SQLConnectionProducer

usernameProducer template.StringTemplate

// A flag to let us know to skip cross DB queries and server login checks
containedDB bool
}

func New() (interface{}, error) {
Expand Down Expand Up @@ -94,6 +97,18 @@ func (m *MSSQL) Initialize(ctx context.Context, req dbplugin.InitializeRequest)
return dbplugin.InitializeResponse{}, fmt.Errorf("invalid username template - did you reference a field that isn't available? : %w", err)
}

containedDB := false
containedDBRaw, err := strutil.GetString(req.Config, "contained_db")
if err != nil {
return dbplugin.InitializeResponse{}, fmt.Errorf("failed to retrieve contained_db: %w", err)
}

if containedDBRaw == "true" {
vinay-gopalan marked this conversation as resolved.
Show resolved Hide resolved
containedDB = true
}

m.containedDB = containedDB

resp := dbplugin.InitializeResponse{
Config: newConf,
}
Expand Down Expand Up @@ -201,6 +216,19 @@ func (m *MSSQL) revokeUserDefault(ctx context.Context, username string) error {
return err
}

// Check if DB is contained
if m.containedDB {
revokeStmt, err := db.PrepareContext(ctx, fmt.Sprintf("DROP USER IF EXISTS [%s]", username))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default user deletion query for contained DBs. Since there are no server logins or database logins, we can simply drop the user. User still needs permissions and this is only in the case that no revocation statements are provided

if err != nil {
return err
}
defer revokeStmt.Close()
if _, err := revokeStmt.ExecContext(ctx); err != nil {
return err
}
return nil
}

// First disable server login
disableStmt, err := db.PrepareContext(ctx, fmt.Sprintf("ALTER LOGIN [%s] DISABLE;", username))
if err != nil {
Expand Down Expand Up @@ -329,12 +357,16 @@ func (m *MSSQL) updateUserPass(ctx context.Context, username string, changePass
return err
}

var exists bool
// Since contained DB users do not have server logins, we
// only query for a login if DB is not a contained DB
if !m.containedDB {
var exists bool

err = db.QueryRowContext(ctx, "SELECT 1 FROM master.sys.server_principals where name = N'$1'", username).Scan(&exists)
err = db.QueryRowContext(ctx, "SELECT 1 FROM master.sys.server_principals where name = N'$1'", username).Scan(&exists)

if err != nil && err != sql.ErrNoRows {
return err
if err != nil && err != sql.ErrNoRows {
return err
}
}

tx, err := db.BeginTx(ctx, nil)
Expand Down
9 changes: 9 additions & 0 deletions plugins/database/mssql/mssql_test.go
Expand Up @@ -42,6 +42,15 @@ func TestInitialize(t *testing.T) {
VerifyConnection: true,
},
},
"contained_db set": {
dbplugin.InitializeRequest{
Config: map[string]interface{}{
"connection_url": connURL,
"contained_db": "true",
},
VerifyConnection: true,
},
},
}

for name, test := range tests {
Expand Down