From c560fe9d155b64af87a0efb9d9d0885c4e619fdc Mon Sep 17 00:00:00 2001 From: subencheng Date: Tue, 1 Jul 2025 13:43:37 -0700 Subject: [PATCH 1/4] [BB-958] baton-sql: use id instead of name as the resource id --- pkg/connector/server_user.go | 7 ++++++- pkg/mssqldb/roles.go | 15 ++++++++++----- pkg/mssqldb/users.go | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/pkg/connector/server_user.go b/pkg/connector/server_user.go index 637e64f..99d03cf 100644 --- a/pkg/connector/server_user.go +++ b/pkg/connector/server_user.go @@ -151,6 +151,11 @@ func (d *userPrincipalSyncer) CreateAccount( return nil, nil, nil, fmt.Errorf("failed to create login: %w", err) } + uid, err := d.client.GetUserPrincipalByName(ctx, username) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to get user: w", err) + } + // Create a resource for the newly created login profile := map[string]interface{}{ "username": username, @@ -176,7 +181,7 @@ func (d *userPrincipalSyncer) CreateAccount( resource, err := resource.NewUserResource( formattedUsername, d.ResourceType(ctx), - formattedUsername, // Use the formatted username as the ID + uid.ID, userOpts, ) if err != nil { diff --git a/pkg/mssqldb/roles.go b/pkg/mssqldb/roles.go index 0cc5bb7..bce5849 100644 --- a/pkg/mssqldb/roles.go +++ b/pkg/mssqldb/roles.go @@ -324,17 +324,22 @@ WHERE type = 'R' AND principal_id = @p1 return &roleModel, err } -func (c *Client) AddUserToServerRole(ctx context.Context, role string, user string) error { +func (c *Client) AddUserToServerRole(ctx context.Context, role string, userID string) error { l := ctxzap.Extract(ctx) - l.Debug("adding user to database role", zap.String("role", role), zap.String("user", user)) + l.Debug("adding user to database role", zap.String("role", role), zap.String("userID", userID)) - if strings.ContainsAny(role, "[]\"';") || strings.ContainsAny(user, "[]\"';") { + if strings.ContainsAny(role, "[]\"';") || strings.ContainsAny(userID, "[]\"';") { return fmt.Errorf("invalid characters in role or user") } - query := fmt.Sprintf(`ALTER SERVER ROLE [%s] ADD MEMBER [%s];`, role, user) + user, err := c.GetUserPrincipal(ctx, userID) + if err != nil { + return fmt.Errorf("cannot get user: %w", err) + } - _, err := c.db.ExecContext(ctx, query) + query := fmt.Sprintf(`ALTER SERVER ROLE [%s] ADD MEMBER [%s];`, role, user.Name) + + _, err = c.db.ExecContext(ctx, query) if err != nil { return err } diff --git a/pkg/mssqldb/users.go b/pkg/mssqldb/users.go index 3e7812c..f4b51e3 100644 --- a/pkg/mssqldb/users.go +++ b/pkg/mssqldb/users.go @@ -236,6 +236,43 @@ WHERE return &userModel, nil } +func (c *Client) GetUserPrincipalByName(ctx context.Context, name string) (*UserModel, error) { + l := ctxzap.Extract(ctx) + l.Debug("getting user") + + query := ` +SELECT + principal_id, + sid, + name, + type_desc, + is_disabled +FROM + sys.server_principals +WHERE + ( + type = 'S' + OR type = 'U' + OR type = 'C' + OR type = 'E' + OR type = 'K' + ) AND name = @p1 +` + + rows := c.db.QueryRowxContext(ctx, query, name) + + var userModel UserModel + err := rows.StructScan(&userModel) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, fmt.Errorf("user name not found: %s", name) + } + return nil, err + } + + return &userModel, nil +} + // GetUserFromDb find db user from Server principal. func (c *Client) GetUserFromDb(ctx context.Context, db, principalId string) (*UserDBModel, error) { l := ctxzap.Extract(ctx) From dd2491fb6afd1ef77bb99f401ff9c2f0bdf09b64 Mon Sep 17 00:00:00 2001 From: subencheng Date: Tue, 1 Jul 2025 13:54:25 -0700 Subject: [PATCH 2/4] now --- pkg/connector/server_user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/server_user.go b/pkg/connector/server_user.go index 99d03cf..1f549ea 100644 --- a/pkg/connector/server_user.go +++ b/pkg/connector/server_user.go @@ -153,7 +153,7 @@ func (d *userPrincipalSyncer) CreateAccount( uid, err := d.client.GetUserPrincipalByName(ctx, username) if err != nil { - return nil, nil, nil, fmt.Errorf("failed to get user: w", err) + return nil, nil, nil, fmt.Errorf("failed to get user: %w", err) } // Create a resource for the newly created login From 0c897abee6c46e0a008e998eda597f51e8d02afe Mon Sep 17 00:00:00 2001 From: subencheng Date: Tue, 1 Jul 2025 14:10:21 -0700 Subject: [PATCH 3/4] CR --- pkg/mssqldb/users.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/mssqldb/users.go b/pkg/mssqldb/users.go index f4b51e3..15e6647 100644 --- a/pkg/mssqldb/users.go +++ b/pkg/mssqldb/users.go @@ -260,6 +260,9 @@ WHERE ` rows := c.db.QueryRowxContext(ctx, query, name) + if err := rows.Err(); err != nil { + return nil, err + } var userModel UserModel err := rows.StructScan(&userModel) From 1b81a9464bb4ef9cdbdf43e592466cb7381e958a Mon Sep 17 00:00:00 2001 From: subencheng Date: Tue, 1 Jul 2025 14:18:05 -0700 Subject: [PATCH 4/4] more --- pkg/mssqldb/roles.go | 6 ++++++ pkg/mssqldb/users.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/pkg/mssqldb/roles.go b/pkg/mssqldb/roles.go index bce5849..90e39c2 100644 --- a/pkg/mssqldb/roles.go +++ b/pkg/mssqldb/roles.go @@ -280,6 +280,9 @@ WHERE type = 'R' AND principal_id = @p1 var roleModel RoleModel row := c.db.QueryRowxContext(ctx, query, id) + if err := row.Err(); err != nil { + return nil, err + } err := row.StructScan(&roleModel) if err != nil { @@ -315,6 +318,9 @@ WHERE type = 'R' AND principal_id = @p1 var roleModel RoleModel row := c.db.QueryRowxContext(ctx, query, id) + if err := row.Err(); err != nil { + return nil, err + } err := row.StructScan(&roleModel) if err != nil { diff --git a/pkg/mssqldb/users.go b/pkg/mssqldb/users.go index 15e6647..1555827 100644 --- a/pkg/mssqldb/users.go +++ b/pkg/mssqldb/users.go @@ -223,6 +223,9 @@ WHERE ` rows := c.db.QueryRowxContext(ctx, query, userId) + if err := rows.Err(); err != nil { + return nil, err + } var userModel UserModel err := rows.StructScan(&userModel) @@ -307,6 +310,9 @@ AND sp.principal_id = @p1 query = fmt.Sprintf(query, db) row := c.db.QueryRowxContext(ctx, query, principalId) + if err := row.Err(); err != nil { + return nil, err + } var userModel UserDBModel err := row.StructScan(&userModel)