Altering server role on SQL Server - sql-server

I need to create a SQL Server user and link it to my database, so I used the following script
-- Create the user 'tester' for database PILLS
USE [master]
DROP DATABASE [PILLS]
GO
CREATE DATABASE [PILLS]
GO
-- CREAZIONE UTENTE
IF NOT EXISTS(SELECT sp.name AS ServerLoginName, dp.name AS DBUserName FROM sys.server_principals sp LEFT JOIN sys.database_principals dp ON sp.sid = dp.sid WHERE sp.name = 'tester')
CREATE LOGIN [tester] WITH PASSWORD=N'tester', DEFAULT_DATABASE=[PILLS], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
-- MAPPING UTENTE SU DATABASE
USE [PILLS]
CREATE USER tester FROM LOGIN tester;
-- CAMBIO ACCESSI
USE [PILLS]
ALTER LOGIN [tester] DISABLE
GO
ALTER SERVER ROLE [securityadmin] ADD MEMBER [tester]
GO
ALTER SERVER ROLE [serveradmin] ADD MEMBER [tester]
GO
ALTER SERVER ROLE [setupadmin] ADD MEMBER [tester]
GO
ALTER SERVER ROLE [processadmin] ADD MEMBER [tester]
GO
ALTER SERVER ROLE [diskadmin] ADD MEMBER [tester]
GO
ALTER SERVER ROLE [dbcreator] ADD MEMBER [tester]
GO
ALTER SERVER ROLE [bulkadmin] ADD MEMBER [tester]
GO
ALTER LOGIN [tester] ENABLE
GO
The script runs fine but my user doesn't have the server roles as I set previously.
Each instruction looks fine and I've also compared them with the ones generated by SQL Server.
Any ideas?

Related

SQL: Login 'abc' owns one or more databases(s)... Even though I just dropped those roles

I'm trying to remove an SQL login with the following commands:
USE [myDB]
GO
ALTER ROLE [db_owner] DROP MEMBER [abc]
GO
USE [myDB]
GO
DROP USER [abc]
GO
USE [master]
ALTER SERVER ROLE [sysadmin] DROP MEMBER [abc]
GO
USE [master]
DROP LOGIN [abc]
GO
But SQL returns the following Error:
Login 'abc' owns one or more database(s). Change the owner of the database(s) before dropping the login.
There are no other (Non-System-)Databases present on the server and i litterally just dropped the login from role DB_owner - what is going on?
Users with the db_owner role is not the same as being the owner of the database.
You should use ALTER AUTHORIZATION to give ownership of the database to another principal.
If you get the user's SID then you can query the sys.databases catalog view (specifically the owner_sid column) to discover which databases they currently own.

DbCreator role can restore a database but not then access it in MSSQL Server

I am working on a tool which is having restore command to restore MSSQL databases. Till now tool was restoring the databases with sysadmin privileges. However, as per new requirement I want to minimize the access privilege for this command i.e restore should be done with dbcreator role instead of sysadmin. With dbcreator I am able to restore the databases, however this command also does some post-operation on the restored databases i.e. updating some value in table. Post-operation is failing with lack of access, since db_owner is required for this user. How to grant db_owner to current user(dbcreator) on the restored databases who is not sysadmin at run time so that my restore command succeeds along with post-operation.
One way to follow security principles of least privilege and role-based access controls is to encapsulate the T-SQL commands that require elevated permissions in a stored procedure. One can then sign the proc with a certificate to confer additional permissions without granting those permissions directly to users. Only execute permissions on the signed stored procedure are required and authorized users are limited to the encapsulated functionality.
Below is an example script to create a stored procedure and DBRestore role using this technique. If your actual RESTORE command contains options that can't be parameterized (e.g. WITH MOVE file locations), you'll need to use dynamic SQL in the proc and take special care to ensure the values validated and/or obtained from a trusted source (e.g. configuration table instead of ad-hoc parameter value).
USE master
GO
--create certificate in master database
CREATE CERTIFICATE sysadmin_cert_login_cert
ENCRYPTION BY PASSWORD = '<cert-password>'
WITH SUBJECT = 'For sysadmin privileges';
GO
--create login from certificate
CREATE LOGIN sysadmin_cert_login FROM CERTIFICATE sysadmin_cert_login_cert;
--confer sysadmin permissions to certificate login
ALTER SERVER ROLE sysadmin
ADD MEMBER sysadmin_cert_login;
GO
--create role for restore user(s)
CREATE ROLE DBRestoreRole;
GO
--create restore proc in master database
CREATE PROC dbo.usp_RestoreDatabase
#DatabaseName sysname
, #BackupFilePath varchar(255)
AS
BEGIN TRY
RESTORE DATABASE #DatabaseName FROM DISK=#BackupFilePath WITH REPLACE;
--after restore, set database owner as desired
ALTER AUTHORIZATION ON DATABASE::RestoreTest TO sa;
--execute post restore DML
UPDATE RestoreTest.dbo.SomeTable
SET SomeColumn = 1;
END TRY
BEGIN CATCH
THROW;
END CATCH;
GO
--grant execute permission to DBRestoreRole
GRANT EXECUTE ON dbo.usp_RestoreDatabase TO DBRestoreRole;
--sign proc with sysadmin certificate
ADD SIGNATURE TO dbo.usp_RestoreDatabase BY CERTIFICATE sysadmin_cert_login_cert WITH PASSWORD='<cert-password>';
--optionally, remove ephemoral private key after signing
ALTER CERTIFICATE sysadmin_cert_login_cert REMOVE PRIVATE KEY;
GO
--create example DBRestoreRole login/user
CREATE LOGIN RestoreTestLogin WITH PASSWORD = '<login-password>';
CREATE USER RestoreTestLogin;
ALTER ROLE DBRestoreRole
ADD MEMBER RestoreTestLogin;
GO
--test execution
EXECUTE AS LOGIN = 'RestoreTestLogin';
GO
EXEC dbo.usp_RestoreDatabase
#DatabaseName = N'RestoreExample'
, #BackupFilePath = 'E:\BackupFiles\RestoreExample.bak';
GO
REVERT;
GO

Is it possible in SQL Server to view multiple databases with one login?

My first question post: I have SQL Server 2017 CU14 dev edition running at Lubuntu 18.04 LTS.
Let's say I have 3 databases masterdb, child1, child2 and with sa login I can see all 3 databases.
Is it possible, for example, to create a login mike to view only child1 and child2 databases, and not showing masterdb?
I already tried other methods, but resulting only in 1 on 1 relation, 1 login view 1 db (not showing others 2 db)
Any insight would be appreciated
The VIEW ANY DATABASE might be what you are after if the login has a user that owns the database in question. Take the below example:
USE master;
GO
CREATE LOGIN Test WITH PASSWORD = '123', CHECK_POLICY = OFF;
ALTER SERVER ROLE dbcreator ADD MEMBER Test;
DENY VIEW ANY DATABASE TO Test;
GO
EXECUTE AS LOGIN = 'Test';
GO
SELECT *
FROM sys.databases;
GO
CREATE DATABASE TestDB;
GO
SELECT *
FROM sys.databases;
REVERT;
GO
DROP DATABASE test;
DROP LOGIN TestDB;
Notice that in the first SELECT, only tempdb and master are shown. After the second, TestDB also shows as the User Test (mapepd to the Login Test) owns the database TestDB.
Note that a user being part of the db_owner role doesn't let them see the database (or any other role):
USE master;
GO
CREATE LOGIN Test WITH PASSWORD = '123', CHECK_POLICY = OFF;
ALTER SERVER ROLE dbcreator ADD MEMBER Test;
DENY VIEW ANY DATABASE TO Test;
GO
CREATE DATABASE SampleDB;
GO
USE SampleDB;
GO
CREATE USER Test FOR LOGIN Test;
ALTER ROLE db_owner ADD MEMBER Test;
GO
USE master;
GO
CREATE DATABASE ExampleDB;
GO
USE ExampleDB;
GO
CREATE USER Test FOR LOGIN Test;
ALTER ROLE db_datareader ADD MEMBER Test;
GO
USE master;
EXECUTE AS LOGIN = 'Test';
GO
SELECT *
FROM sys.databases;
GO
CREATE DATABASE TestDB;
GO
SELECT *
FROM sys.databases;
REVERT;
GO
DROP DATABASE TestDB;
DROP DATABASE SampleDB;
DROP DATABASE ExampleDB;
DROP LOGIN Test;
Neither SampleDB or ExampleDB ever show up in the SELECT statements.

Cannot alter the server role 'bulkadmin' in side SP

i have application and sql server 2012 user ( i need to keep him with minimum permission)
i need to perform bulk insert by my application .
so i need to grant and deny the bulk permission by using SP
when i try
Alter PROCEDURE grantRole #Grant bit
With Execute As Owner AS
if(#Grant=1)
ALTER SERVER ROLE [bulkadmin] ADD MEMBER [myUser]
else
ALTER SERVER ROLE [bulkadmin] DROP MEMBER [myUser]
GO
i get the error
Msg 15151, Level 16, State 1, Line 1
Cannot alter the server role 'bulkadmin', because it does not exist or you do not have permission.
note that :the SP 'grantRole' exec from my application by the connection of the user -which is the user need to grant/deny the role- with execute permission
but as developer i have the permission
how can i solved or is their another way

How do I create a new user in a SQL Azure database?

I am trying to use the following template:
-- =================================================
-- Create User as DBO template for SQL Azure Database
-- =================================================
-- For login <login_name, sysname, login_name>, create a user in the database
CREATE USER <user_name, sysname, user_name>
FOR LOGIN <login_name, sysname, login_name>
WITH DEFAULT_SCHEMA = <default_schema, sysname, dbo>
GO
-- Add user to the database owner role
EXEC sp_addrolemember N'db_owner', N'<user_name, sysname, user_name>'
GO
I would like to create a user called user1 with a password of 'user1pass'. I connected with my default database 'authentication' and I have a query window open.
But the template does not make sense for me. For example what's sysname, where do I supply the password and what should I use as the default_schema?
The particular user needs to have the power to do everything. But how do I set it up so he can do everything, is that done if I make the user a database owner?
So far I have tried:
CREATE USER user1, sysname, user1
FOR LOGIN user1, sysname, user1
WITH DEFAULT_SCHEMA = dbo, sysname, dbo
GO
Giving:
Msg 102, Level 15, State 1, Line 1 Incorrect syntax near ','.
and:
CREATE USER user1
FOR LOGIN user1
WITH DEFAULT_SCHEMA = dbo
GO
Giving:
Msg 15007, Level 16, State 1, Line 1 'user1' i
s not a valid login or you do not have permission.
Edit - Contained User (v12 and later)
As of Sql Azure 12, databases will be created as Contained Databases which will allow users to be created directly in your database, without the need for a server login via master.
Sql (standard) User
CREATE USER [MyUser] WITH PASSWORD = 'Secret';
ALTER ROLE [db_datareader] ADD MEMBER [MyUser]; -- or sp_addrolemember
AAD linked User
CREATE USER [SomeUser#mydomain.com] FROM EXTERNAL PROVIDER;
EXEC sp_addrolemember 'db_datareader' , N'SomeUser#mydomain.com'
AAD linked Group
CREATE USER [SomeGroup] FROM EXTERNAL PROVIDER;
EXEC sp_addrolemember 'db_datareader' , N'SomeGroup'
NB! when connecting to the database when using a contained user that you must always specify the database in the connection string.
Traditional Server Login - Database User (Pre v 12)
Just to add to #Igorek's answer, you can do the following in Sql Server Management Studio:
Create the new Login on the server
In master (via the Available databases drop down in SSMS - this is because USE master doesn't work in Azure):
create the login:
CREATE LOGIN username WITH password=N'password';
Create the new User in the database
Switch to the actual database (again via the available databases drop down, or a new connection)
CREATE USER username FROM LOGIN username;
(I've assumed that you want the user and logins to tie up as username, but change if this isn't the case.)
Now add the user to the relevant security roles
EXEC sp_addrolemember N'db_owner', N'username'
GO
(Obviously an app user should have less privileges than dbo.)
Check out this link for all of the information : https://azure.microsoft.com/en-us/blog/adding-users-to-your-sql-azure-database/
First you need to create a login for SQL Azure, its syntax is as follows:
CREATE LOGIN username WITH password='password';
This command needs to run in master db. Only afterwards can you run commands to create a user in the database. The way SQL Azure or SQL Server works is that there is a login created first at the server level and then it is mapped to a user in every database.
HTH
I followed the answers here but when I tried to connect with my new user, I got an error message stating "The server principal 'newuser' is not able to access the database 'master' under the current security context".
I had to also create a new user in the master table to successfully log in with SSMS.
USE [master]
GO
CREATE LOGIN [newuser] WITH PASSWORD=N'blahpw'
GO
CREATE USER [newuser] FOR LOGIN [newuser] WITH DEFAULT_SCHEMA=[dbo]
GO
USE [MyDatabase]
CREATE USER newuser FOR LOGIN newuser WITH DEFAULT_SCHEMA = dbo
GO
EXEC sp_addrolemember N'db_owner', N'newuser'
GO
You can simply create a contained user in SQL DB V12.
Create user containeduser with password = 'Password'
Contained user login is more efficient than login to the database using the login created by master. You can find more details # http://www.sqlindepth.com/contained-users-in-sql-azure-db-v12/
I use the Azure Management console tool of CodePlex, with a very useful GUI, try it. You can save type some code.
1 Create login while connecting to the master db
(in your databaseclient open a connection to the master db)
CREATE LOGIN 'testUserLogin' WITH password='1231!#ASDF!a';
2 Create a user while connecting to your db (in your db client open a connection to your database)
CREATE USER testUserLoginFROM LOGIN testUserLogin;
Please, note, user name is the same as login. It did not work for me when I had a different username and login.
3 Add required permissions
EXEC sp_addrolemember db_datawriter, 'testUser';
You may want to add 'db_datareader' as well.
list of the roles:
https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/database-level-roles?view=sql-server-ver15
I was inspired by #nthpixel answer, but it did not work for my db client DBeaver.
It did not allow me to run USE [master] and use [my-db] statements.
https://azure.microsoft.com/en-us/blog/adding-users-to-your-sql-azure-database/
How to test your user?
Run the query bellow in the master database connection.
SELECT A.name as userName, B.name as login, B.Type_desc, default_database_name, B.*
FROM sys.sysusers A
FULL OUTER JOIN sys.sql_logins B
ON A.sid = B.sid
WHERE islogin = 1 and A.sid is not null
List of all users in Azure SQL
create a user and then add user to a specific role:
CREATE USER [test] WITH PASSWORD=N'<strong password>'
go
ALTER ROLE [db_datareader] ADD MEMBER [test]
go
I found this link very helpful:
https://azure.microsoft.com/en-gb/documentation/articles/sql-database-manage-logins/
It details things like:
- Azure SQL Database subscriber account
- Using Azure Active Directory users to access the database
- Server-level principal accounts (unrestricted access)
- Adding users to the dbmanager database role
I used this and Stuart's answer to do the following:
On the master database (see link as to who has permissions on this):
CREATE LOGIN [MyAdmin] with password='ReallySecurePassword'
And then on the database in question:
CREATE USER [MyAdmin] FROM LOGIN [MyAdmin]
ALTER ROLE db_owner ADD MEMBER [MyAdmin]
You can also create users like this, according to the link:
CREATE USER [mike#contoso.com] FROM EXTERNAL PROVIDER;
I think the templates use the following notation: variable name, variable type, default value.
Sysname is a built-in data type which can hold the names of system objects.
It is limited to 128 Unicode character.
-- same as sysname type
declare #my_sysname nvarchar(128);

Resources