Showing posts with label login. Show all posts
Showing posts with label login. Show all posts

Sunday, 13 September 2015

Contained Database example in SQL Server by serverku

SQL Server 2012 introduced a new feature named "Contained Database" which include all database settings and metadata along with database backup. It allows us to move database backups along with its users to another server, so no need any dependencies on the server. Let us look an example.

1. Enable a setting
 
-- Enable setting for contained database
Use master
GO
exec sp_configure 'show advanced options', 1;
RECONFIGURE WITH OVERRIDE
GO
exec sp_configure 'contained database authentication', 1;
RECONFIGURE WITH OVERRIDE
GO
2. Enable a feature for a database
 
-- Create a new contained database

CREATE DATABASE [ContainedDB]
CONTAINMENT = PARTIAL
ON PRIMARY
( NAME = N'ContainedDB_Data', FILENAME = N'D:\Data\ContainedDB_Data.mdf')
LOG ON
( NAME = N'ContainedDB_Log', FILENAME = N'D:\Log\ContainedDB_Log.ldf')
GO

-- Or change existing database to contained
ALTER DATABASE [ContainedDB] SET CONTAINMENT = PARTIAL
GO
3. Create a new SQL User
 
-- Create a new SQL User in this contained database
USE [ContainedDB]
GO
CREATE USER ContainedDBUser WITH PASSWORD = 'ContainedDBUser'
GO
Checking : Let us login with this User created and below error occur .


 Now change a setting when login with this User.

1. Go to 'Options<<'
2. Move on tab 'Connection  Properties'
3. Set 'Connect to database' to "ContainedDB"


After applying an option, you will be succeed. So wherever you want to move contained database to another server, just move it and log in as options stated above. Enjoy Contained Database!

Sunday, 9 August 2015

Linked Server and OPENQUERY with Execl Source - SQL Server by serverku


As I have written posts for the linked servers with SQL Server option in previous post, the same way we have another option is available and these are with other data sources as a linked server. With SQL Server as a linked server, we can communicate with two SQL servers. But we can also communicate other data sources like excel, csv and others as well. Let us link our SQL server with Excel and get the data from excel. For that we need to go through the same way as I did for SQL Server linked server, but here we need to choose option of other data sources.


How can we do it using TSQL?
 
USE [master]
GO

EXEC [master].[dbo].[sp_addlinkedserver]
@server='ExcelImport',
@srvproduct='Excel',
@provider='Microsoft.Jet.OLEDB.4.0',
@datasrc='D:\Import\Import_1.xls',
@provstr= 'Excel 8.0'

GO

EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'collation compatible', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'data access', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'dist', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'pub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'rpc', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'rpc out', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'sub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'connect timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'collation name', @optvalue=null
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'lazy schema validation', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'query timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'use remote collation', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'EXCELIMPORT', @optname=N'remote proc transaction promotion', @optvalue=N'true'
GO
USE [master]
GO
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'EXCELIMPORT', @locallogin = NULL , @useself = N'False'
GO
It has other data source also like as following,

Now, after creating excel as linked server, we have time to communicate with it and fetch data through linked server & OPENQUERY
 
SELECT
*
FROM ExcelImport...[Sheet1$]

-- OR --

SELECT
*
FROM OPENQUERY(ExcelImport, 'SELECT * FROM [Sheet1$]')
Your comments are appreciated.

Sunday, 2 August 2015

Working with Linked Servers in SQL Server by serverku

We may have a need for some logic to move the data from one server database to another server database on production environment. Also for the distributed transactions or for the cross server database queries we require it.

How to do it? With Linked servers we can perform any distributed transactions between servers. Also, we can execute remote servers stored procedure with linked server communication.

How to create it?
Herewith we have small demo which I have captured during setup it.
  1. Go to the Server Objects --> Linked Servers, Right click on it and click on New Linked Servers.
  2. Specify Server name which you want to linked to current server.
  3. Go to Security tab and select the option for link.
The option details as msdn and book online are following,

Local login : Specify the local login that can connect to the linked server. The local login can be either a login using SQL Server Authentication or a Windows Authentication login. Use this list to restrict the connection to specific logins, or to allow some logins to connect as a different login.

Impersonate : Pass the username and password from the local login to the linked server. For SQL Server Authentication, a login with the exact same name and password must exist on the remote server. For Windows logins, the login must be a valid login on the linked server.

Remote User : Use the remote user to map users not defined in Local login. The Remote User must be a SQL Server Authentication login on the remote server.

Remote Password : Specify the password of the Remote User.

Not be made : Specify that a connection will not be made for logins not defined in the list.

Be made without using a security context : Specify that a connection will be made without using a security context for logins not defined in the list.

Be made using the logins current security context : Specify that a connection will be made using the current security context of the login for logins not defined in the list. If connected to the local server using Windows Authentication, your windows credentials will be used to connect to the remote server. If connected to the local server using SQL Server Authentication, login name and password will be used to connect to the remote server. In this case a login with the exact same name and password must exist on the remote server.

Be made using this security context : Specify that a connection will be made using the login and password specified in the Remote login and With password boxes for logins not defined in the list. The remote login must be a SQL Server Authentication login on the remote server.

We have a some server options like RPC, RPC out as follows


We have seen as how can we create linked server from SSMS. Now we will have script to create linked servers as well.
 USE [master]
GO

EXEC master.dbo.sp_addlinkedserver @server = N'PARESH-PC1', @srvproduct=N'SQL Server'
GO

EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'collation compatible', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'data access', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'dist', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'pub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'rpc', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'rpc out', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'sub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'connect timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'collation name', @optvalue=null
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'lazy schema validation', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'query timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'PARESH-PC1', @optname=N'use remote collation', @optvalue=N'true'
GO

USE [master]
GO
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'PARESH-PC1', @locallogin = NULL , @useself = N'False', @rmtuser = N'dba', @rmtpassword = N'dba@test'
GO

How to get list of linked servers?

SQL Server provide system stored procedure as well system tables , from we can have the details for the same.
  • sp_linkedservers
  • sys.servers
 
-- 1. Fetch the data using tsql

SELECT
*
FROM paresh-pc.demo.dbo.dempteable

-- 2. Running remote stored procedures

EXECUTE paresh-pc.demo.dbo.DemoSP 'test_param'
I hope you enjoyed linked servers. Please share your comments what you are performing with linked servers. 

Saturday, 23 May 2015

Access to the remote server is denied because no login-mapping exists - SQL Server Error by serverku

Recently, when I was working with security and changed some level of access and permission of some logins\users, I received an error while accessing data through linked servers with some logins which was working earlier. An error is reported as below.
Msg 7416, Level 16, State 2, Line 1
Access to the remote server is denied because no login-mapping exists.
After finding solution following, it worked. Here is a some change of linked server and below is a script to used for same. Just adding a logins to linked server which has an issue to access it.
Use master
GO

EXEC master.dbo.sp_addlinkedserver
@server = N'LinkedServerName',
@provider=N'SQLNCLI',
@srvproduct = 'MS SQL Server',
@provstr=N'SERVER=ServerName\InstanceName;User ID=myUser'


EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname = N'LinkedServerName',
@locallogin = NULL ,
@useself = N'False',
@rmtuser = N'myUser',
@rmtpassword = N'*****'
GO
Here is the just script and change your user name in place of ‘myUser’ and appropriate server\instance name. Please share your comments if you received such errors and workaround for same.

Thursday, 21 May 2015

Fix Orphaned Users in SQL Server by serverku

You may aware of the orphaned users and it is experienced when restore a database backup to another server with logins which means the database user restored in a system which does not have associated valid logins. After restoring a database backup we can fix those orphaned users with sp_change_users_login. Let us see a small example to fix orphaned database users.
-- At source server
USE [master]
GO
-- Creating a test login
CREATE LOGIN [testlogin] WITH PASSWORD=N'testlogin', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
USE [DemoDB]
GO
-- Creating a database user for login testlogin created
CREATE USER [testlogin] FOR LOGIN [testlogin]
GO
-- Assigning a database role to testlogin user created
ALTER ROLE [db_datareader] ADD MEMBER [testlogin]
GO

USE master
GO
-- Taking a database backup at source
BACKUP DATABASE [DemoDB]
TO DISK = 'D:\DemoDB_full_20130913.bak'


-- At destination server
USE Master
GO
-- Restoring a database backup at source
RESTORE DATABASE [DemoDB]
FROM DISK = 'D:\DemoDB_full_20130913.bak'
WITH replace,
MOVE 'DemoDB' TO 'D:\Data\DemoDB_data.mdf',
MOVE 'DemoDB_log' TO 'D:\Log\DemoDB_log.ldf'


USE DemoDB
GO
EXEC sp_change_users_login 'report'
GO

/*
UserName UserSID
----------------------------------------------
testlogin 0xFD13E649B5EF75469A22D598C8E0790D
*/

-- Mapping a user to new sql login
USE DemoDB
GO
CREATE LOGIN testlogin WITH PASSWORD = 'testlogin'
GO
EXEC sp_change_users_login 'Update_One','testlogin','testlogin'
GO

-- Automatically mapping a user to login, creating a new login if not exists
USE DemoDB
GO
EXEC sp_change_users_login 'Auto_Fix','testlogin',NULL,'testlogin'
GO

/* Output
-- If login does not exists
Barring a conflict, the row for user 'testlogin' will be fixed by updating its link to a new login.
The number of orphaned users fixed by updating users was 0.
The number of orphaned users fixed by adding new logins and then updating users was 1.

-- If login already exists
The row for user 'testlogin' will be fixed by updating its login link to a login already in existence.
The number of orphaned users fixed by updating users was 1.
The number of orphaned users fixed by adding new logins and then updating users was 0.
*/

You can fix all users at one shot using the following script,
USE [DemoDB]
GO

CREATE TABLE #OrphanedUsers
(
Id INT IDENTITY(1, 1),
UserName VARCHAR(250)
)

DECLARE @i INT,
@Total INT,
@User VARCHAR(250)

INSERT INTO #OrphanedUsers (UserName)
SELECT DISTINCT [Name]
FROM [Sysusers]
WHERE Islogin = 1
AND [Name] NOT IN
( 'guest', 'sa', 'dbo', 'public',
'sys', 'INFORMATION_SCHEMA' )

SET @Total = @@ROWCOUNT
SET @i = 1

WHILE ( @i <= @Total)
BEGIN
SELECT @User = UserName
FROM #OrphanedUsers
WHERE Id = @i

EXEC sp_change_users_login 'Auto_Fix', @User, NULL, @User

SET @i = @i + 1
END

DROP TABLE #OrphanedUsers
Hope you enjoyed this small example and would like to you share ideas for same.
Stay tuned for more!

Wednesday, 6 May 2015

Profile name is not valid - Error when sending an email using sp_send_dbmail in SQL Server by serverku

A week ago I shared some posts related to replication and scheduled jobs information and you may enjoy it. Hope you liked it too. While working with security, suddenly I started to receive an error when sending an email though script using sp_send_dbmail from msdb database specifically for one user and I clicked it was due to changes in access of that user. The analysis was going long and checked user access to msdb databases and it has db_datareader, and DatabaseMailUserRole and failed to send an email. Even it was not working, assigned db_owner to that user in msdb database.
Finally came to solution using sysmail_add_principalprofile_sp system object which grants permission for a database user or role to use a specified Database Mail profile,
USE [msdb]
GO
-- DatabaseMailUserRole database role should be assigned to user if user is not db_owner database role and sysadmin server role
EXEC sp_addrolemember N'DatabaseMailUserRole', N'UserName' -- Put user name here
GO

EXECUTE msdb.dbo.sysmail_add_principalprofile_sp
@profile_name = 'ProfileName', -- Put pfofile name here
@principal_name = 'UserName', -- Put user name here
@is_default = 1 ;
YYou can also make the same changes from the user interface. Goto Database Mail, right click and goto Configure Database Mail , select an option Manage Profile Security, Go to Private Profiles Tab, Select User name and check the box of Access and make a default profile to Yes for the profile name using which we want to send an email.


After above change it was succeeded to send an email. Stay tuned for more.

Wednesday, 29 April 2015

SQL Server is unable to complete the New Publication Wizard - Replication Error by serverku

The last time we saw the issue we faced during setup of replication and it was due to original server name change. We came out from one issue But today I am writing for another issue which I faced in the same for replication configuration. I think this is something bad happen during workaround for the solution earlier, by mistake, something went wrong while old server drop and it were used in replication. Even we will look for the solution for this too. So let us move on the error which I get on initial stage of replication configuration while adding publication using Publication Wizard,

“TITLE: New Publication Wizard
------------------------------
SQL Server is unable to complete the New Publication Wizard.

------------------------------
ADDITIONAL INFORMATION:
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)

------------------------------
Invalid object name 'msdb.dbo.MSdistributiondbs'. (Microsoft SQL Server, Error: 208)”
It seems these objects getting destroyed while workaround for earlier error. Finally, I got solution online as how to create those objects in msdb database,
USE MSDB
GO

CREATE TABLE [MSdistributiondbs] (
[name] [sysname] NOT NULL
,[min_distretention] [int] NOT NULL
,[max_distretention] [int] NOT NULL
,[history_retention] [int] NOT NULL
)
GO

CREATE TABLE [dbo].[MSdistpublishers] (
[name] [sysname] NOT NULL
,[distribution_db] [sysname] NOT NULL
,[working_directory] [nvarchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
,[security_mode] [int] NOT NULL
,[login] [sysname] NOT NULL
,[password] [nvarchar] (524) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
,[active] [bit] NOT NULL
,[trusted] [bit] NOT NULL
,[thirdparty_flag] [bit] NOT NULL
)
GO
Above objects created and finally I was succeeding to go ahead for my next steps!

SQL Server is unable to connect to server 'ServerName' - Error while setup replication by serverku

One day when I was setting up replication in my local machine, when I clicked to create a new publication from replication tab, I faced one error and the details,

Error :
TITLE: New Publication Wizard
------------------------------

SQL Server is unable to connect to server 'PARESH\MSSQLSERVER2012'.
------------------------------
ADDITIONAL INFORMATION:

SQL Server replication requires the actual server name to make a connection to the server.
Specify the actual server name, 'ADMIN\MSSQLSERVER2012'. (Replication.Utilities)


This is because of earlier my machine name was “ADMIN” and SQL server installed at that time. After some time I changed my machine name to “PARESH”. Currently SQL Server instance showing “PARESH\MSSQLSERVER2012” from SSMS and showing “"ADMIN\MSSQLSERVER2012” while running @@SERVERNAME from query analyzer. So this is the reason why I am facing above mentioned error. This will raise same error while trying to configure replication and the default SQL instance connected with “(local)” or “.” as a name.

Solution :
I have one option which we have to connect SQL Server with the actual server name and it will be done with change SQL server name to machine name\instance name first. You can change the SQL Server instance name with following script,
EXEC sp_dropserver 'ADMIN\MSSQLSERVER2012' -- <Old Name\Instance>
GO

EXEC sp_addserver 'PARESH\MSSQLSERVER2012','local' -- <New Name\Instance>
GO
When you run a first statement which in above mentioned script, you may face the following error too,

Msg 15190, Level 16, State 1, Procedure sp_dropserver, Line 56
There are still remote logins or linked logins for the server 'ADMIN\MSSQLSERVER2012'.


And we have solved too,
EXEC sp_dropremotelogin 'ADMIN\MSSQLSERVER2012'; -- <Old Name\Instance>
GO
After running all steps we can go ahead for the next step of replication. To check renamed server name with @@SERVERNAME. Among you also faced this issue also. Can we have the other options for the solution here?

Tuesday, 28 April 2015

Alerts for SQL Server security events by serverku

Security is the main thing for servers and SQL servers and we need to trace it for security management. Have to need track who is using it, what they are doing and when they performed. For SQL Server 2005 and later versions we have some DDL events which can help us to achieve this. So let us catch it up. But before going ahead, please visit DDL Trigger and DDL Auditing in SQL Server 2005 and Logon trigger in SQL Server for more information about DDL trigger.
I am presenting here for DDL triggers fire for security events. We can also log all the event data in the table, but I want to describe this post to get al alert for this security event's occurrence. To implement I am creating a DDL trigger in the master database and evaluate for some scenario like login creation, Add server roles and drop logins. You can find the trigger created for the same as following,
CREATE TRIGGER [Trg_TrackLoginManagement]
ON ALL SERVER
FOR
DDL_SERVER_SECURITY_EVENTS
AS
BEGIN
SET NOCOUNT ON

DECLARE @data xml,
@EventType varchar(100),
@EventTime datetime,
@ServerName varchar(100),
@AffectedLoginName varchar(100),
@WhoDidIt varchar(100),
@EmailSubject varchar(500),
@EmailBody varchar(800),
@EmailRecipients varchar(300),
@TSQL varchar(4000)

SET @EmailRecipients = 'prajapatipareshm@gmail.com'

SET @data = EVENTDATA()
SET @EventType = @data.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(100)')
SET @EventTime = @data.value('(/EVENT_INSTANCE/PostTime)[1]','datetime')
SET @ServerName = @data.value('(/EVENT_INSTANCE/ServerName)[1]','varchar(100)')
SET @AffectedLoginName = @data.value('(/EVENT_INSTANCE/ObjectName)[1]','varchar(100)')
SET @WhoDidIt = @data.value('(/EVENT_INSTANCE/LoginName)[1]','varchar(100)')
SET @TSQL = @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]','varchar(4000)')

SET @EmailSubject = @EventType + ' occured by ' + @WhoDidIt + ' on ' +
@ServerName + ' occured at: ' + convert(Varchar, @EventTime)
SET @EmailBody = @TSQL

EXEC msdb.dbo.sp_send_dbmail
@recipients = @EmailRecipients
, @subject = @EmailSubject
, @body = @EmailBody
, @profile_name = '<ProfileName>' -- Put profile name here
, @body_format = 'HTML' ;

END
We are capturing some data which is full information of login name , the events occurred and the date on which it occurred and who did. I collected some snaps after performing and testing some scenario for creating a login, assigning server roles and finally deleting created login after testing, Let me share here.


Above are the alert emails which I received for the events happened to create login, server role assignment and after all deleting the login. If we do not want to continue receiving the alerts for change, then it DDL trigger on the server can be disabled with following statement.
DISABLE TRIGGER [Trg_TrackLoginManagement] ON ALL SERVER
GO
Did you configure any alerts for such DDL events? Share your thoughts here.

Logon trigger in SQL Server by serverku

As a secure part, recently I worked with login details and the auditing for the same. I needed to capture each event for logging statistics like login name, the time when logon, the program through established connection, session and host or client IP. This event is raised when user sessions make connections with SQL Server instances where we configured LOGON trigger. This will helpful for us to make auditing the logon details for each connections. For the small demo let us create required objects and implement it.
USE DemoDB
GO
-- Creating audit table
CREATE TABLE LogonAuditing
(
SessionId int,
LogonTime datetime,
HostName varchar(50),
ProgramName varchar(500),
LoginName varchar(50),
ClientHost varchar(50)
)
GO
USE Master
GO
-- Creating DDL trigger for logon
CREATE TRIGGER LogonAuditTrigger
ON ALL SERVER
FOR LOGON
AS
BEGIN
DECLARE @LogonTriggerData xml,
@EventTime datetime,
@LoginName varchar(50),
@ClientHost varchar(50),
@LoginType varchar(50),
@HostName varchar(50),
@AppName varchar(500)

SET @LogonTriggerData = eventdata()

SET @EventTime = @LogonTriggerData.value('(/EVENT_INSTANCE/PostTime)[1]', 'datetime')
SET @LoginName = @LogonTriggerData.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(50)')
SET @ClientHost = @LogonTriggerData.value('(/EVENT_INSTANCE/ClientHost)[1]', 'varchar(50)')
SET @HostName = HOST_NAME()
SET @AppName = APP_NAME()--,program_name()

INSERT INTO DemoDB.dbo.LogonAuditing
(
SessionId,
LogonTime,
HostName,
ProgramName,
LoginName,
ClientHost
)
SELECT
@@spid,
@EventTime,
@HostName,
@AppName,
@LoginName,
@ClientHost

END
GO
Audit table and the trigger to fill that table is created. Now it is time to evaluate, test it and review the audit table.

We have all details of the logging events from the table. Also one more interesting thing is as we can prevent unwanted user logins and connections to SQL Server. This prohibition can be for the login, program or host, for that we just need to add some code in logon trigger for conditions to make rollback at that time like following,
-- Preventing 'sa' login
IF @LoginName = 'sa'
BEGIN
ROLLBACK;
END

-- Preventing the connections from SSMS
IF @AppName = 'Microsoft SQL Server Management Studio'
BEGIN
ROLLBACK;
END
For first criteria to prevent login ‘SA’, if connection made for the same and the message fired at the time of event logging,


You can make your criteria as per requirement as I implemented for login and program connections. Are you using a Logon Trigger?

Friday, 27 January 2012

Alter failed for Login sa. Cannot set a credential for principal 'sa'. - Error encountered in SQL Server by serverku

Recently, when I worked with SQL Server security, I encountered with one error while trying to modify 'SA' account properties. The exception details looks following,
Alter failed for Login sa. Cannot set a credential for principal 'sa'.

The fix for the error is the option "Map to Credential" is checked in the "General" tab of the Login Properties Page as mentioned below,


Hope this help you.

Friday, 20 January 2012

Application Role in SQL Server by serverku

In the last post we saw custom database roles as how can we create it and assign required access to users. We also noticed that we can add multiple members with the same role. That was the security with database roles and members comes into the picture. Now here we will study of Application Role. This is the security for the application level and no such members comes into the picture.

Application Role :
As per msdn, An application role is a database principal that enables an application to run with its own, user-like permissions. You can use application roles to enable access to specific data to only those users who connect through a particular application

Workaround:
We can implement application role and take into effect with the following steps, I am going to here with some of the examples, so like to create those required objects, so we can set them with application role.

1. Create required objects
USE demo
GO

CREATE TABLE SampleTable1
(
Id int,
Name varchar(10)
)
GO

CREATE TABLE SampleTable2
(
Id int,
Name varchar(10)
)
GO

CREATE PROCEDURE SampleSP1
AS
BEGIN
SET NOCOUNT ON
SELECT * FROM SampleTable1
End
GO

CREATE PROCEDURE SampleSP2
AS
BEGIN
SET NOCOUNT ON
SELECT * FROM SampleTable2
End
GO
Here we have created same required objects as we created in an earlier post for database role.  

2. Create an application role
USE demo
GO

-- sp_addapprole [@rolename = ] 'rolename', [@password = ] 'password'

EXEC sp_addapprole 'AppRole', 'AppPwd'
GO
3. Add permission to this application role
USE demo
GO

GRANT SELECT ON SampleTable1 to AppRole;
GRANT SELECT, INSERT,UPDATE ON SampleTable2 to AppRole;
GRANT EXEC ON SampleSP1 to AppRole;
GO
You can see we have assigned same access to the application role as we did in an earlier post for the custom database role. Application role is created here now, You can also create/view with expanding Roles inside security tab for a particular database and inside it you can find the Application Role tab.


4. Connecting database and activating application role

Application roles are enabled/activated by sp_settapprole system stored procedure and it has required a password. So an application can be connected to SQL Server with this application role with scope of the particular session and required a password to authenticate it to connect SQL Server. To authenticate application roles and activate it it should be required to use in.Net connection code or other application database connection method code. You can refer the link here to use application role in application code.

sp_settapprole system stored procedure activate the application role for the specific connection while connecting with the application and the syntax is as follows,
USE demo
GO

-- sp_setapprole [@rolename = ] 'rolename', [@password = ] 'password'

EXEC sp_setapprole 'AppRole', 'AppPwd'
GO
We can change the password for the application role with following,
USE demo
GO

-- sp_approlepassword [@rolename = ] 'rolename', [@password = ] 'new password'

EXEC sp_approlepassword 'AppRole', 'AppChangedPwd'
GO
Hope these all the steps are enough to implement application role. Stay tuned for more.

Friday, 13 January 2012

Custom Database Role in SQL Server by serverku

Recently, while working with database security, I learned database roles as how the each rule used. Apart from the server level roles if we need to require to assign access/rights to the particular database level, then we need to go through database level roles.

Following are the fixed database level roles as per MSDN,
db_owner :Members of the db_owner fixed database role can perform all configuration and maintenance activities on the database, and can also drop the database.
db_securityadmin :Members of the db_securityadmin fixed database role can modify role membership and manage permissions. Adding principals to this role could enable unintended privilege escalation.
db_accessadmin :Members of the db_accessadmin fixed database role can add or remove access to the database for Windows logins, Windows groups, and SQL Server logins.
db_backupoperator :Members of the db_backupoperator fixed database role can back up the database.
db_ddladmin :Members of the db_ddladmin fixed database role can run any Data Definition Language (DDL) command in a database.
db_datawriter :Members of the db_datawriter fixed database role can add, delete, or change data in all user tables.
db_datareader : Members of the db_datareader fixed database role can read all data from all user tables.
db_denydatawriter :Members of the db_denydatawriter fixed database role cannot add, modify, or delete any data in the user tables within a database.
db_denydatareader : Members of the db_denydatareader fixed database role cannot read any data in the user tables within a database.


You can see the image in all above fixed database roles. Now we will see how can we use the roles and bind with users. Let's create a small demo with examples. Here I am creating required objects used for demos, So let's do that.
USE demo
GO

CREATE TABLE SampleTable1
(
Id int,
Name varchar(10)
)
GO

CREATE TABLE SampleTable2
(
Id int,
Name varchar(10)
)
GO

CREATE PROCEDURE SampleSP1
AS
BEGIN
SET NOCOUNT ON
SELECT * FROM SampleTable1
End
GO

CREATE PROCEDURE SampleSP2
AS
BEGIN
SET NOCOUNT ON
SELECT * FROM SampleTable2
End
GO
Now here I want to assign the access to user as follows,
1. User can see the data from SampleTable2 table.
2. User can perform select/insert/update operation on SampleTable1 table, not delete operation.
3. Can execute stored procedure SampleSP1.
4. Can not execute stored procedure SampleSP2.

Workaround 1:
If we assigned fixed database roles to User like db_datareader, and db_datawriter for a particular database, then user can perform all DML operations on all tables, views in the database. Even if we assigned EXECUTE permission to the user then the user can execute all the stored procedures. After all these permissions we need to deny permission from the user for some of the tables and stored procedures which are not required to be accessed.

Workaround 2:
Instead of doing above such stuffs, We will create a new custom database level role and assigned requited access to use for the objects.
USE demo
GO

CREATE LOGIN [SupportUser]
WITH PASSWORD=N'SupportUser',
DEFAULT_DATABASE=[master],
DEFAULT_LANGUAGE=[us_english],
CHECK_EXPIRATION=OFF,
CHECK_POLICY=OFF
GO

CREATE USER [SupportUser] FOR LOGIN [SupportUser]
GO

CREATE ROLE [SupportRole]
Go

GRANT SELECT ON SampleTable2 TO [SupportRole];
GRANT SELECT,INSERT,UPDATE ON SampleTable1 to [SupportRole];
GRANT EXEC ON SampleSP1 to [SupportRole]
GO

EXEC sp_addrolemember N'SupportRole', N'SupportUser'
GO
Let's connect the SQL Server instance with this newly created user and see the access rights,
USE demo
GO

PRINT 'Inserting in SampleTable1'
GO
INSERT INTO SampleTable1
(
Id,
Name
)
SELECT
1,
'Sample1'
GO

PRINT 'Inserting in SampleTable2'
GO
INSERT INTO SampleTable2
(
Id,
Name
)
SELECT
1,
'Sample2'
GO

PRINT 'Deleting from SampleTable1'
GO
DELETE FROM SampleTable1
GO

PRINT 'Viewing from SampleTable1'
GO
SELECT * FROM SampleTable2
GO
SELECT * FROM SampleTable1
GO


PRINT 'Executing SampleSP11'
GO
EXEC SampleSP1
GO
PRINT 'Executing SampleSP2'
GO
EXEC SampleSP2
GO
You can see the below image to see the access by running user,


The main benefit of the custom database role is role can be assigned to multiple users. You can see below script where I have assigned the same role to different users. So once role created it can be assigned to multiple users.
USE demo
GO

CREATE LOGIN [DBAUser]
WITH PASSWORD=N'DBAUser',
DEFAULT_DATABASE=[master],
DEFAULT_LANGUAGE=[us_english],
CHECK_EXPIRATION=OFF,
CHECK_POLICY=OFF
GO

CREATE USER [DBAUser] FOR LOGIN [DBAUser]
GO

EXEC sp_addrolemember N'SupportRole', N'DBAUser'
GO
Hope you like this post.