Need to give permission to user through role - sql

I have to write script in which I have create login and user, and give Execute on access to this USER to execute only single store procedure SP_SELECTDEPT but not directly only through role. So this way user will be having access to execute only this store procedure but it is not working.
so far I have done.
BEGIN TRANSACTION
USE master
CREATE LOGIN QGtestlogin WITH PASSWORD = 'test123', CHECK_POLICY=off
GO
USE DEPT
CREATE USER QGtestlogin FOR LOGIN QGtestlogin
go
CREATE ROLE QGtestrole AUTHORIZATION QGtestlogin
GO
GRANT EXECUTE ON SP_SELECTDEPT TO QGtestrole
go
if ##ERROR > 0
begin
rollback transaction
end
else begin
commit transaction
end
But when I login with this newly created user it is not even showing the store procedure to execute.
NOTE:
I have added the user to role member using sp_addrolemember
exec sp_addrolemember 'QGtestrole','QGtestlogin'
but still getting error:
Msg 229, Level 14, State 5, Procedure SP_SELECTDEPT, Line 14
The SELECT permission was denied on the object 'Dept', database 'DEPT', schema 'dbo'.

It seems to be problem with SQLEXPRESS edition, When I run the same code on my actual development database they get executed and QGtestlogin able to execute the Store Procedure.

Related

Grant truncate permissions on all tables with out modify

Is there a way I can grant truncate permission to a user without altering privileges in SQL Server?
The minimum permission required is ALTER on table_name. TRUNCATE TABLE permissions default to the table owner, members of the sysadmin fixed server role, and the db_owner and db_ddladmin fixed database roles, and are not transferable. However, you can incorporate the TRUNCATE TABLE statement within a module, such as a stored procedure, and grant appropriate permissions to the module using the EXECUTE AS clause.
CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
AS
SELECT user_name();
Source
You can go through this official documentation.
Create a test Login and User id then grant it execute permission on the stored procedure Truncate_Table_Loner. This id will be used to perform the truncate.
-- Grant Execute Permission
-- Setup ID on Database with Connect permission
USE master
GO
CREATE LOGIN [test_user_id] WITH PASSWORD = 'JustConnect123';
GO
USE TestSQL
GO
CREATE USER [test_user_id] FOR LOGIN [test_user_id];
GO
-- Grant Permission
GRANT EXECUTE ON dbo.Truncate_Table_Loner TO [test_user_id];
GO

How to change 'db_datareader' permission to 'public' for a login in azure sql server?

I created a new login and a new user in Azure SQL server database.
What I want to do is providing a read only permission to this role for a single table in the database.
While doing this I ran the below script:
EXEC sp_addrolemember N'db_datareader', N'new_user'
GO
But with this permission the new user can view all the tables in the database.
So I tried running the below script with 'public' role.
EXEC sp_addrolemember N'public', N'new_user'
GO
But its giving me this error:
"Membership of the public role cannot be changed."
How to provide only a single table read permission to the new user?
Execute the following statement on master database to create your new user login (mydb_user)
CREATE LOGIN mydb_user
WITH PASSWORD = 'p#ssw0rd'
GO
Run below statements on the user database
CREATE USER mydb_user FROM LOGIN mydb_user ;
GO
GRANT SELECT ON dbo.Events TO mydb_user;
I tested this on my side. It should work on your side.

SQL server restore and user permission

I need to permission a user to a database right after a database restore.
I tried this:
Use [master]
go
restore database DBTest
from disk='E:\userTemp\DBTest1.bak'
WITH MOVE 'DBTest' TO 'E:\SQLData\DBTest1.mdf',
MOVE 'DBTest_log' TO 'F:\SQLData\DBTest1.ldf',
replace, recovery, stats=5, maxtransfersize=1048576
Print '---------------------------RESTORE COMPLETED ---------------------------'
-- Create the user.
CREATE USER [user_indi] FOR LOGIN [user_indi]
GO
USE [DBTest]
GO
EXEC sp_addrolemember N'db_owner', N'user_indi'
GO
When I do this, I get the following error:
Msg 15023, Level 16, State 1, Line 22
User, group, or role 'user_indi' already exists in the current database.
Msg 15410, Level 11, State 1, Procedure sp_addrolemember, Line 75
User or role 'user_indi' does not exist in this database.
So, what added the command to remove the user in the middle. Now it looks like this.
Use [master]
go
restore database DBTest
from disk='E:\userTemp\DBTest1.bak'
WITH MOVE 'DBTest' TO 'E:\SQLData\DBTest1.mdf',
MOVE 'DBTest_log' TO 'F:\SQLData\DBTest1.ldf',
replace, recovery, stats=5, maxtransfersize=1048576
Print '---------------------------RESTORE COMPLETED ---------------------------'
-- Remove the user
USE [DBTest]
GO
DROP USER [user_indi]
GO
-- Create the user.
CREATE USER [user_indi] FOR LOGIN [user_indi]
GO
USE [DBTest]
GO
EXEC sp_addrolemember N'db_owner', N'user_indi'
GO
Now, I get the error:
Msg 15151, Level 16, State 1, Line 2
Cannot drop the user 'user_indi', because it does not exist or you do not have permission.
I can't allow errors as I need to schedule this restore and permission job. Why am I getting this error and how can I workaround it?
RM
Your USE [DBTest] statements are in two different places.
In the first one, you're attempting to create the user in MASTER. In the second one, you're creating it in DBTest.

Failure to execute msdb.dbo.sp_send_dbmail

I am getting this error:
Msg 229, Level 14, State 5, Procedure sp_send_dbmail, Line 1
The EXECUTE permission was denied on the object 'sp_send_dbmail', database 'msdb', schema 'dbo'.
The relevant part of the code:
/****** Object: StoredProcedure [dbo].[dbo.STATUSCHANGE_EMAILALERT] ******/
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'Test#gmail.com', -- Group Email
#subject = 'Employee Status Update',
#profile_name ='Test#gmail.com', -- Setup the profile name group
#body = #body,
#body_format = 'HTML';
Found nice and easy fix that worked for me here:
If your SQL applications can’t send email using database mail (I assume you already have DBMail Account and Profile setup), there are two things to set:
SQL MANAGEMENT STUDIO > MANAGEMENT > DATABASE MAIL > right click and
select CONFIGURE… > select MANAGE PROFILE SECURITY > SQL MANAGEMENT
put a check on PUBLIC option
click on DEFAULT PROFILE and set it to YES
STUDIO > DATABASES > SYSTEM DATABASES > right click on MSDB and
select NEW QUERY > then enter > grant execute on sp_send_dbmail to
public and click OK
To send Database mail, users must be a user in the msdb database and a member of the DatabaseMailUserRole database role in the msdb database. To add msdb users or groups to this role use SQL Server Management Studio or execute the following statement for the user or role that needs to send Database Mail:
EXEC msdb.dbo.sp_addrolemember #rolename = 'DatabaseMailUserRole'
,#membername = '<user or role name>';
GO
Grant execute permission on sp_send_dbmail to the user executing the stored procedure, or add them to the role msdb.DatabaseMailUser .
Ok, just to add to this topic since this was really good information, but still didn't completely solve my problem. If I ran the query in SSMS, it worked once I was granted permission to execute the sp_send_dbmail procedure in msdb. However, when a job was running as my user, it would still fail.
Read through a lot of stuff to get to the conclusion that you need to make sure the sid for the owner in your DB matches the owner sid in the master DB:
--To get owner SID recorded in the master database for the current database
SELECT owner_sid FROM sys.databases WHERE database_id=DB_ID()
--To get the owner SID recorded for the current database owner
SELECT sid FROM sys.database_principals WHERE name=N'dbo'
Even though I had given access to the msdb and execute rights on the sp_send_dbmail, it was still having issues related to the database being untrustworthy and that the owner sids didn't match. Consequently, I had to the Trustworthy on for the database I was running in and fix the ownership issue:
ALTER DATABASE my_db SET TRUSTWORTHY ON;
ALTER AUTHORIZATION ON Database::my_db TO [domain\user];
I had to go through a lot of ferreting around to finally find this write-up which is much more enlightening.
I accidentally changed the "Run As" option for the SQL Agent Job - Step from "[User]" to "(Not Specified)". That caused my Job to start working.
I found here the right solution for me.
You need to add your user (let's say mailuser) to msdb and give this user rights to run dbmail:
USE msdb;
CREATE USER mailuser FOR LOGIN mailuser;
EXEC sp_addrolemember 'DatabaseMailUserRole', 'mailuser'

SQL Server Execute Impersonation

What is the diffrence between...
execute as user = 'testuser'
AND
execute as login = 'testuser'
I am executing a cross database procedure under these logins and it works with the exececute as login but not the execute as user. It is saying the server principal "testuser" is nt able to access the database "xxx" under the securty context.
When i SELECT SYSTEM_USER after both commands I see that it is set to 'testuser'
execute as login provides impersonation to the entire server, since logins are on a server level. Since users are defined per database, execute as user impersonation applies only to a specific database, which is why you see the error when you cross databases.
The EXECUTE AS can be added to stored procs, functions, triggers, etc.
Example to Execute As:
CREATE PROCEDURE dbo.MyProcedure
WITH EXECUTE AS OWNER
In this case you are impersonating the owner of the module being called.
You can also impersonate SELF, OR the USER creating or altering the module OR...
impersonate CALLER , which will enable to module to take on the permissions of the current user, OR...
impersonate OWNER, which will take on the permission of the owner of the procedure being called OR...
impersonate 'user_name', which will impersonate a specific user OR...
impersonate 'login_name' with will impersonate a specific login.
Setting permission on objects like stored procedures can be accomplished with
GRANT EXECUTE ON <schema>.<procedurename> to <username>;
However, you may also want to grant security rights at both the login and user level.
You will want to determine and grant ONLY the necessary rights
for the objects that require access (such as execution). Consider use of the "EXECUTE AS" capability which enables impersonation of another user
to validate permissions that are required to execute the code WITHOUT having to grant all of the necessary rights to all of the underlying objects (e.g. tables).
MOST of the time, you will only need to grant EXECUTE rights to stored procs and then rights are granted to all objects referenced within the stored proc.
In this way, you do not need to give implicit rights (example: to update data or call additional procs). Ownership chaining handles this for you.
This is especially helpful for dynamic sql or if you need to create elevated security tasks such as CREATE TABLE. EXECUTE AS is a handy tool to consider for these.
This example may help clarify all of this:
--Create a user called NoPrivUser with public access to a database (e.g. dbadb)
USE [master]
GO
CREATE LOGIN [NoPrivUser] WITH PASSWORD=N'ABC5%', DEFAULT_DATABASE=[dbadb], CHECK_EXPIRATION=ON, CHECK_POLICY=ON
GO
USE [DBAdb]
GO
CREATE USER [NoPrivUser] FOR LOGIN [NoPrivUser]
GO
NOTE: CREATOR OR OWNER OF THIS PROCEDURE WILL REQUIRE CREATE TABLE RIGHTS within the target database.
use DBAdb
go
CREATE PROCEDURE dbo.MyProcedure
WITH EXECUTE AS OWNER
AS
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].MyTable') AND type in (N'U'))
CREATE TABLE MyTable (PKid int, column1 char(10))
INSERT INTO MyTable
VALUES (1,'ABCDEF')
GO
GRANT EXEC ON dbo.MyProcedure TO NoPrivUser;
GO
-- Now log into your database server as NoPrivUser and run the following.
use dbadb
go
EXEC dbo.MyProcedure
--(1 row(s) affected)
Now try to select from the new table while logged on as NoPrivuser.
You will get the following:
select * from MyTable
go
Msg 229, Level 14, State 5, Line 1 The SELECT permission was denied on
the object 'MyTable', database 'DBAdb', schema 'dbo'.
That is expected since you only ran the procedure under the security context of Owner while logged on as NoPrivUser.
NoPrivUser as no rights to actually read the table, Just to execute the procedure which creates and inserts the rows.
With the EXECUTE AS clause the stored procedure is run under the context of the object owner. This code successfully creates dbo.MyTable and rows are inserted successfully.
In this example, the user "NoPrivUser" has absolutey no granted rights to modify the table, or read or modify any of the data in this table.
It only takes on the rights needed to complete this specific task coded WITHIN the context of this procedure.
This method of creating stored procedures that can perform tasks that require elevated security rights without permanently assigning those rights come be very useful.
Login scope is at the server level while user scope is at the current database level
http://msdn.microsoft.com/en-us/library/ms181362.aspx